feat: field costs

This commit is contained in:
korzepadawid 2022-04-13 18:35:02 +02:00
parent af2f61984a
commit 1dbb1a0e4c
3 changed files with 26 additions and 17 deletions

View File

@ -6,7 +6,7 @@ from typing import Tuple, Optional, List
from common.constants import ROWS, COLUMNS from common.constants import ROWS, COLUMNS
FREE_FIELD = ' ' EMPTY_FIELDS = ['s', 'g', ' ']
LEFT = 'LEFT' LEFT = 'LEFT'
RIGHT = 'RIGHT' RIGHT = 'RIGHT'
UP = 'UP' UP = 'UP'
@ -44,6 +44,7 @@ class Node:
state: State state: State
parent: Optional[Node] parent: Optional[Node]
action: Optional[str] action: Optional[str]
grid: List[List[str]]
cost: int = field(init=False) cost: int = field(init=False)
depth: int = field(init=False) depth: int = field(init=False)
@ -51,20 +52,23 @@ class Node:
return self.state < node.state return self.state < node.state
def __post_init__(self) -> None: def __post_init__(self) -> None:
self.cost = 0 if not self.parent else self.parent.cost + 1 if self.grid[self.state.position[0]][self.state.position[1]] == 'g':
self.depth = self.cost self.cost = 1 if not self.parent else self.parent.cost + 1
else:
self.cost = 3 if not self.parent else self.parent.cost + 3
self.depth = 0 if not self.parent else self.parent.depth + 1
def __hash__(self) -> int: def __hash__(self) -> int:
return hash(self.state) return hash(self.state)
def expand(node: Node, grid: List[List[str]]) -> List[Node]: def expand(node: Node, grid: List[List[str]]) -> List[Node]:
return [child_node(node=node, action=action) for action in actions(node.state, grid)] return [child_node(node=node, action=action, grid=grid) for action in actions(node.state, grid)]
def child_node(node: Node, action: str) -> Node: def child_node(node: Node, action: str, grid: List[List[str]]) -> Node:
next_state = result(state=node.state, action=action) next_state = result(state=node.state, action=action)
return Node(state=next_state, parent=node, action=action) return Node(state=next_state, parent=node, action=action, grid=grid)
def next_position(current_position: Tuple[int, int], direction: str) -> Tuple[int, int]: def next_position(current_position: Tuple[int, int], direction: str) -> Tuple[int, int]:
@ -75,7 +79,7 @@ def next_position(current_position: Tuple[int, int], direction: str) -> Tuple[in
def valid_move(position: Tuple[int, int], grid: List[List[str]]) -> bool: def valid_move(position: Tuple[int, int], grid: List[List[str]]) -> bool:
row, col = position row, col = position
return grid[row][col] == FREE_FIELD return grid[row][col] in EMPTY_FIELDS
def actions(state: State, grid: List[List[str]]) -> List[str]: def actions(state: State, grid: List[List[str]]) -> List[str]:
@ -170,7 +174,7 @@ def get_path_from_start(node: Node) -> List[str]:
def a_star(state: State, grid: List[List[str]], goals: List[Tuple[int, int]]) -> List[str]: def a_star(state: State, grid: List[List[str]], goals: List[Tuple[int, int]]) -> List[str]:
node = Node(state=state, parent=None, action=None) node = Node(state=state, parent=None, action=None, grid=grid)
frontier = list() frontier = list()
heapq.heappush(frontier, (f(node, goals[0]), node)) heapq.heappush(frontier, (f(node, goals[0]), node))

View File

@ -29,7 +29,7 @@ CASTLE_SPAWN_FIRST_COL = 9
NBR_OF_WATER = 16 NBR_OF_WATER = 16
NBR_OF_TREES = 20 NBR_OF_TREES = 20
NBR_OF_MONSTERS = 2 NBR_OF_MONSTERS = 2
NBR_OF_SANDS = 15 NBR_OF_SANDS = 35
TILES = [ TILES = [
'grass1.png', 'grass1.png',

View File

@ -20,7 +20,7 @@ class Level:
# sprite group setup # sprite group setup
self.sprites = pygame.sprite.Group() self.sprites = pygame.sprite.Group()
self.map = [[' ' for x in range(COLUMNS)] for y in range(ROWS)] self.map = [['g' for _ in range(COLUMNS)] for y in range(ROWS)]
self.list_knights_blue = [] self.list_knights_blue = []
self.list_knights_red = [] self.list_knights_red = []
@ -37,18 +37,19 @@ class Level:
def generate_map(self): def generate_map(self):
spawner = Spawner(self.map) spawner = Spawner(self.map)
spawner.spawn_where_possible(['w' for x in range(NBR_OF_WATER)]) spawner.spawn_where_possible(['w' for _ in range(NBR_OF_WATER)])
spawner.spawn_where_possible(['t' for x in range(NBR_OF_TREES)]) spawner.spawn_where_possible(['t' for _ in range(NBR_OF_TREES)])
spawner.spawn_where_possible(['s' for _ in range(NBR_OF_SANDS)])
spawner.spawn_in_area(['k_b' for x in range(4)], LEFT_KNIGHTS_SPAWN_FIRST_ROW, LEFT_KNIGHTS_SPAWN_FIRST_COL, spawner.spawn_in_area(['k_b' for _ in range(4)], LEFT_KNIGHTS_SPAWN_FIRST_ROW, LEFT_KNIGHTS_SPAWN_FIRST_COL,
KNIGHTS_SPAWN_WIDTH, KNIGHTS_SPAWN_HEIGHT) KNIGHTS_SPAWN_WIDTH, KNIGHTS_SPAWN_HEIGHT)
spawner.spawn_in_area(['k_r' for x in range(4)], RIGHT_KNIGHTS_SPAWN_FIRST_ROW, RIGHT_KNIGHTS_SPAWN_FIRST_COL, spawner.spawn_in_area(['k_r' for _ in range(4)], RIGHT_KNIGHTS_SPAWN_FIRST_ROW, RIGHT_KNIGHTS_SPAWN_FIRST_COL,
KNIGHTS_SPAWN_WIDTH, KNIGHTS_SPAWN_HEIGHT) KNIGHTS_SPAWN_WIDTH, KNIGHTS_SPAWN_HEIGHT)
spawner.spawn_in_area(['c'], CASTLE_SPAWN_FIRST_ROW, CASTLE_SPAWN_FIRST_COL, CASTLE_SPAWN_WIDTH, spawner.spawn_in_area(['c'], CASTLE_SPAWN_FIRST_ROW, CASTLE_SPAWN_FIRST_COL, CASTLE_SPAWN_WIDTH,
CASTLE_SPAWN_HEIGHT, 2) CASTLE_SPAWN_HEIGHT, 2)
spawner.spawn_where_possible(['m' for x in range(NBR_OF_MONSTERS)]) spawner.spawn_where_possible(['m' for _ in range(NBR_OF_MONSTERS)])
def setup_base_tiles(self): def setup_base_tiles(self):
textures = [] textures = []
@ -69,8 +70,12 @@ class Level:
texture_index = 6 texture_index = 6
texture_surface = textures[texture_index][1] texture_surface = textures[texture_index][1]
Tile((col_index, row_index), texture_surface, self.sprites, 't') Tile((col_index, row_index), texture_surface, self.sprites, 't')
elif col == "s":
texture_index = 4
texture_surface = textures[texture_index][1]
Tile((col_index, row_index), texture_surface, self.sprites)
else: else:
texture_index = random.randint(0, 4) texture_index = random.randint(0, 3)
texture_surface = textures[texture_index][1] texture_surface = textures[texture_index][1]
Tile((col_index, row_index), texture_surface, self.sprites) Tile((col_index, row_index), texture_surface, self.sprites)
@ -126,7 +131,7 @@ class Level:
current_knight.rotate_right() current_knight.rotate_right()
elif next_action == FORWARD: elif next_action == FORWARD:
current_knight.step_forward() current_knight.step_forward()
self.map[knight_pos_y][knight_pos_x] = ' ' self.map[knight_pos_y][knight_pos_x] = 'g'
# update knight on map # update knight on map
if current_knight.direction.name == UP: if current_knight.direction.name == UP: