a_star #21
@ -1,40 +1,39 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum, unique
|
||||
from typing import Tuple, Optional, List
|
||||
|
||||
from common.constants import ROWS, COLUMNS
|
||||
|
||||
FREE_FIELD = ' '
|
||||
LEFT = 'LEFT'
|
||||
RIGHT = 'RIGHT'
|
||||
UP = 'UP'
|
||||
DOWN = 'DOWN'
|
||||
|
||||
directions = {
|
||||
LEFT: (0, -1),
|
||||
RIGHT: (0, 1),
|
||||
UP: (-1, 0),
|
||||
DOWN: (1, 0)
|
||||
}
|
||||
|
||||
@unique
|
||||
class Direction(Enum):
|
||||
LEFT = (0, -1)
|
||||
RIGHT = (0, 1)
|
||||
UP = (-1, 0)
|
||||
DOWN = (1, 0)
|
||||
|
||||
|
||||
@unique
|
||||
class Action(Enum):
|
||||
TURN_LEFT = 'TURN_LEFT'
|
||||
TURN_RIGHT = 'TURN_RIGHT'
|
||||
FORWARD = 'FORWARD'
|
||||
TURN_LEFT = 'TURN_LEFT'
|
||||
TURN_RIGHT = 'TURN_RIGHT'
|
||||
FORWARD = 'FORWARD'
|
||||
|
||||
|
||||
@dataclass
|
||||
class State:
|
||||
position: Tuple[int, int]
|
||||
direction: Direction
|
||||
direction: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Node:
|
||||
state: State
|
||||
parent: Optional[Node]
|
||||
action: Action
|
||||
action: str
|
||||
cost: int = field(init=False)
|
||||
depth: int = field(init=False)
|
||||
|
||||
@ -53,15 +52,15 @@ def expand(node: Node) -> List[Node]:
|
||||
return [child_node(node=node, action=action) for action in actions(node.state)]
|
||||
|
||||
|
||||
def child_node(node: Node, action: Action) -> Node:
|
||||
def child_node(node: Node, action: str) -> Node:
|
||||
next_state = result(state=node.state, action=action)
|
||||
return Node(state=next_state, parent=node, action=action)
|
||||
|
||||
|
||||
def next_position(current_position: Tuple[int, int], direction: Direction) -> Tuple[int, int]:
|
||||
x1, y1 = direction.value
|
||||
x2, y2 = current_position
|
||||
return x1 + x2, y1 + y2
|
||||
def next_position(current_position: Tuple[int, int], direction: str) -> Tuple[int, int]:
|
||||
next_row, next_col = directions[direction]
|
||||
row, col = current_position
|
||||
return next_row + row, next_col + col
|
||||
|
||||
|
||||
def valid_move(position: Tuple[int, int], grid: List[List[str]]) -> bool:
|
||||
@ -69,32 +68,32 @@ def valid_move(position: Tuple[int, int], grid: List[List[str]]) -> bool:
|
||||
return grid[row][col] == FREE_FIELD
|
||||
|
||||
|
||||
def actions(state: State, grid: List[List[str]]) -> List[Action]:
|
||||
possible_actions = [Action.FORWARD, Action.TURN_LEFT, Action.TURN_RIGHT]
|
||||
def actions(state: State, grid: List[List[str]]) -> List[str]:
|
||||
possible_actions = [FORWARD, TURN_LEFT, TURN_RIGHT]
|
||||
row, col = state.position
|
||||
direction = state.direction
|
||||
|
||||
if direction == Direction.UP and row == 0:
|
||||
if direction == UP and row == 0:
|
||||
remove_forward(possible_actions)
|
||||
if direction == Direction.DOWN and row == ROWS - 1:
|
||||
if direction == DOWN and row == ROWS - 1:
|
||||
remove_forward(possible_actions)
|
||||
if direction == Direction.LEFT and col == 0:
|
||||
if direction == LEFT and col == 0:
|
||||
remove_forward(possible_actions)
|
||||
if direction == Direction.RIGHT and col == COLUMNS - 1:
|
||||
if direction == RIGHT and col == COLUMNS - 1:
|
||||
remove_forward(possible_actions)
|
||||
|
||||
if not valid_move(next_position(state.position, direction), grid):
|
||||
if FORWARD not in possible_actions and not valid_move(next_position(state.position, direction), grid):
|
||||
remove_forward(possible_actions)
|
||||
|
||||
return possible_actions
|
||||
|
||||
|
||||
def remove_forward(possible_actions: List[Action]) -> None:
|
||||
if Action.FORWARD in possible_actions:
|
||||
possible_actions.remove(Action.FORWARD)
|
||||
def remove_forward(possible_actions: List[str]) -> None:
|
||||
if FORWARD in possible_actions:
|
||||
possible_actions.remove(FORWARD)
|
||||
|
||||
|
||||
def result(state: State, action: Action, grid: List[List[str]]) -> State:
|
||||
def result(state: State, action: str, grid: List[List[str]]) -> State:
|
||||
pass
|
||||
|
||||
|
||||
@ -106,7 +105,7 @@ def h(state: State, goal: Tuple[int, int]) -> int:
|
||||
"""heuristics that calculates Manhattan distance between current position and goal"""
|
||||
x1, y1 = state.position
|
||||
x2, y2 = goal
|
||||
return abs(x1 - x2) + abs(y1 - y2) # Manhattan distance
|
||||
return abs(x1 - x2) + abs(y1 - y2)
|
||||
|
||||
|
||||
def f(current_node: Node, goal: Tuple[int, int]) -> int:
|
||||
|
@ -2,6 +2,7 @@ import random
|
||||
|
||||
import pygame
|
||||
|
||||
import algorithms.a_star as a_s
|
||||
from algorithms.bfs import graphsearch, State
|
||||
from common.constants import *
|
||||
from common.helpers import castle_neighbors
|
||||
@ -110,6 +111,9 @@ class Level:
|
||||
|
||||
castle_cords = (self.list_castles[0].position[0], self.list_castles[0].position[1])
|
||||
goal_list = castle_neighbors(self.map, castle_cords[0], castle_cords[1]) # list of castle neighbors
|
||||
print(knight_pos_x, knight_pos_y)
|
||||
st = a_s.State((knight_pos_x, knight_pos_y), a_s.UP)
|
||||
print(f'Actions: {a_s.actions(st, self.map)}')
|
||||
action_list = graphsearch(state, self.map, goal_list)
|
||||
print(action_list)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user