diff --git a/main.py b/main.py index 6a11f12..0e335d9 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ # libraries +import time import pygame from pyglet.gl import * # for blocky textures import random @@ -119,12 +120,20 @@ def main(): for component in ui_components_list.selectable_ui_components: component.set_flags(is_active=False) + # === TARGET-MINE CHOICE (NAIVE) === + mines = minefield.get_active_mines() + if any(mines): + row, column = random.choice(mines).position + const.SCREEN.blit(HIGHLIGHT, const.get_tile_coordinates((row, column))) + else: + is_game_over = True + action_sequence = a_star.graphsearch( initial_state=a_star.State( row=minefield.agent.position[0], column=minefield.agent.position[1], direction=minefield.agent.direction), - minefield=minefield, tox=row, toy=column) + minefield=minefield, target_type="mine", tox=row, toy=column) # initializing variables in_game_timer = 0 diff --git a/mine_models/standard_mine.py b/mine_models/standard_mine.py index 4f1a9d9..371fe8c 100644 --- a/mine_models/standard_mine.py +++ b/mine_models/standard_mine.py @@ -3,7 +3,7 @@ from .mine import Mine class StandardMine(Mine): def __init__(self, position, active=True): - self.mine_type = "standard" + self.type = "standard" super().__init__(position, active) def disarm(self): diff --git a/minefield.py b/minefield.py index 269d3d6..6238734 100644 --- a/minefield.py +++ b/minefield.py @@ -45,16 +45,31 @@ class Minefield: if mine is not None and isinstance(mine, TimeMine): mine.timer = max(0, mine.starting_time - int(self.turn / 4)) + def get_active_mines(self): + mines = list() + + for row in range(const.V_GRID_VER_TILES): + for column in range(const.V_GRID_VER_TILES): + mine = self.matrix[row][column].mine + + if mine is not None and mine.active: + # do not add mines with predecessors + if mine.type == 'chained' and mine.predecessor is not None: + continue + + mines.append(mine) + + return mines + # ================ # # === MOVEMENT === # # ================ # # check if sapper's destination is accessible - # If Agent comes upon a tile with a mine his starting position shall be reestablished - def is_valid_move(self, target_row: int, target_column: int): + @staticmethod + def is_valid_move(target_row: int, target_column: int): if 0 <= target_row < const.V_GRID_VER_TILES \ - and 0 <= target_column < const.V_GRID_HOR_TILES \ - and self.matrix[target_row][target_column].mine is None: + and 0 <= target_column < const.V_GRID_HOR_TILES: return True return False diff --git a/searching_algorithms/a_star.py b/searching_algorithms/a_star.py index c87ed90..5c42f66 100644 --- a/searching_algorithms/a_star.py +++ b/searching_algorithms/a_star.py @@ -45,12 +45,32 @@ def get_estimated_cost(node: Node): return abs(node.state.row - GOAL[0]) + abs(node.state.column - GOAL[1]) -def goal_test(state: State): +def tile_goal_test(state: State): if (state.row, state.column) == GOAL: return True return False +def mine_goal_test(state: State): + if state.row == GOAL[0] and state.column == GOAL[1] - 1: + if state.direction == Direction.RIGHT: + return True + + elif state.row == GOAL[0] and state.column == GOAL[1] + 1: + if state.direction == Direction.LEFT: + return True + + elif state.row == GOAL[0] - 1 and state.column == GOAL[1]: + if state.direction == Direction.DOWN: + return True + + elif state.row == GOAL[0] + 1 and state.column == GOAL[1]: + if state.direction == Direction.UP: + return True + + return False + + def get_successors(state: State, minefield: Minefield): successors = list() @@ -73,6 +93,7 @@ def graphsearch(initial_state: State, minefield: Minefield, fringe: List[Node] = None, explored: List[Node] = None, + target_type: str = "tile", tox: int = None, toy: int = None): @@ -86,6 +107,11 @@ def graphsearch(initial_state: State, if tox is not None and toy is not None: GOAL = (tox, toy) + if target_type == "mine": + goal_test = mine_goal_test + else: + goal_test = tile_goal_test + # fringe and explored initialization if fringe is None: fringe = list()