def play(self):
        """See base class."""
        self._create_game()
        game_service = GameService(self._game, ignore_deadline=False)

        self._view.update(self._game)

        while self._game.running:
            self._game_round += 1
            time_to_react = randint(4, 16)
            self.__reset_game_deadline(time_to_react)

            # Read input from user if there is a human player
            player_action = None
            if self.__you is not None and self.__you.active:
                player_action = self._view.read_next_action()
                if datetime.now(time_zone) > self._game.deadline:
                    player_action = Action.get_default()
                self.__reset_game_deadline(time_to_react)

            for ai in self._ais:
                if ai is not None and ai.player.active:
                    action = self.__choose_ai_action(ai, time_to_react)
                    game_service.do_action(ai.player, action)
                    self.__reset_game_deadline(time_to_react)

            # Perform action of human player after AIs finished their calculations
            # Otherwise the AIs would already know the players move
            if self.__you is not None and player_action is not None:
                game_service.do_action(self.__you, player_action)

            self._view.update(self._game)
Пример #2
0
    def __create_child(self, player: Player, action: Action, turn_counter: int, max_speed: int):
        if player.speed == max_speed and action == Action.speed_up:
            return

        modified_game = self._game.copy()
        game_service = GameService(modified_game)
        game_service.turn.turn_ctr = turn_counter
        SearchTreeRoot.__perform_simulation(game_service, action, modified_game.get_player_by_id(player.id))
        game_service.check_and_set_died_players()

        return SearchTreeNode(modified_game.copy(), action)
 def setUp(self):
     self.player1 = Player(1, 10, 10, Direction.down, 1, True, "")
     self.player2 = Player(2, 10, 30, Direction.down, 3, True, "")
     self.player3 = Player(3, 30, 10, Direction.right, 2, True, "Name 3")
     players = [self.player1, self.player2, self.player3]
     cells = [[Cell() for _ in range(40)] for _ in range(40)]
     cells[self.player1.y][self.player1.x] = Cell([self.player1])
     cells[self.player2.y][self.player2.x] = Cell([self.player2])
     cells[self.player3.y][self.player3.x] = Cell([self.player3])
     time = datetime(2020, 10, 1, 12, 5, 13, 0, timezone.utc)
     self.game = Game(40, 40, cells, players, 2, True, time)
     self.sut = GameService(self.game)
Пример #4
0
    def __try_combination(game: Game, player_ids_to_watch: List[int], combination: Tuple[Action],
                          turn_counter: int):
        modified_game = game.copy()
        game_service = GameService(modified_game)
        game_service.turn.turn_ctr = turn_counter
        players = modified_game.get_players_by_ids(player_ids_to_watch)
        for j in range(len(combination)):
            action = combination[j]
            player = players[j]
            SearchTreeRoot.__perform_simulation(game_service, action, player)

        game_service.check_and_set_died_players()
        return SearchTreeRoot(modified_game.copy())
Пример #5
0
    def create_next_action(self, game: Game, return_value: Value):
        """See base class."""
        self._turn_ctr += 1

        surviving_actions = self.create_all_next_surviving_actions(game)
        if surviving_actions is not None and len(surviving_actions) > 0:
            return_value.value = choice(surviving_actions).get_index()
            return_value.value = self.find_actions_by_best_path_connection(
                surviving_actions, game)[0][0].get_index()
        else:
            surviving_pathfinding_actions = self.find_actions_by_best_path_connection(
                self.find_surviving_actions(GameService(game), 1), game)
            return_value.value = surviving_pathfinding_actions[0][0].get_index() \
                if surviving_pathfinding_actions is not None and len(surviving_pathfinding_actions) > 0 \
                else Action.get_default().get_index()
Пример #6
0
    def create_next_actions_ranked(self, game: Game) -> Optional[List[Tuple[Action, int]]]:
        """Calculates all actions with the number of reachable paths, with which the AI won't lose in the next turn.

        Args:
            game: The game object in which the AI is located and which contains the current status of the game.

        Returns:
            A list with actions and the corresponding number of accessible paths.
        """
        game_service = GameService(game)
        game_service.turn.turn_ctr = self._turn_ctr

        surviving_actions = self.find_surviving_actions_with_best_depth(game_service)

        return self.find_actions_by_best_path_connection(surviving_actions, game)
Пример #7
0
    def find_actions_by_best_path_connection(self, actions: List[Action], game: Game) -> Optional[
            List[Tuple[Action, int]]]:
        """ Calculates for the passed actions how many paths are still accessible after the execution of the action.

        For this purpose, points are randomly generated on the playing field and an algorithm for finding paths is
        used to check whether the point can be reached.

        Args:
            actions: List of actions to check.
            game: The game that contains the current state of the game.

        Returns:
            List of actions with the accessible paths.
        """
        if actions is None or len(actions) == 0:
            return None
        # shuffle the actions, so that different actions are chosen if they have the same quality and the AI is not so
        # easily predictable.
        shuffle(actions)
        actions_with_possible_paths: List[Tuple[Action, int]] = []
        free_cells_for_pathfinding = self.get_random_free_cells_from_playground(game)

        path_finder = BestFirst(diagonal_movement=DiagonalMovement.never)

        for action in actions:
            game_copy = game.copy()
            game_service = GameService(game_copy)
            try:
                player = game_service.game.get_player_by_id(self.player.id)
                game_service.visited_cells_by_player[player.id] = game_service.get_and_visit_cells(player, action)
            except InvalidPlayerMoveException:
                continue

            matrix = game_copy.translate_cell_matrix_to_pathfinding_matrix()
            current_possible_paths = 0
            length_free_cells = len(free_cells_for_pathfinding)
            for i in range(length_free_cells):
                grid = Grid(matrix=matrix)
                start = grid.node(player.x, player.y)
                end = grid.node(free_cells_for_pathfinding[i][0], free_cells_for_pathfinding[i][1])
                path, _ = path_finder.find_path(start, end, grid)
                if len(path) > 0:  # a path exists
                    current_possible_paths += 1

            actions_with_possible_paths.append((action, current_possible_paths))
        # Action with most accessible paths at index 0
        actions_with_possible_paths.sort(key=operator.itemgetter(1), reverse=True)
        return actions_with_possible_paths
    def test_ai_should_choose_empty_list_with_depth_three_and_no_surviving_action(self):
        player1 = Player(1, 1, 2, Direction.up, 1, True, "")
        player2 = Player(2, 1, 1, Direction.down, 3, True, "")
        players = [player1, player2]
        cells = [[Cell(),           Cell(),          Cell(),            Cell(),             Cell()],
                 [Cell([player2]),  Cell([player2]), Cell([player2]),   Cell(),             Cell()],
                 [Cell(),           Cell([player1]), Cell(),            Cell([player2]),    Cell()],
                 [Cell([player2]),  Cell([player2]), Cell(),            Cell([player2]),    Cell()],
                 [Cell(),           Cell(),          Cell([player2]),   Cell(),             Cell()]]

        time = datetime(2020, 10, 1, 12, 5, 13, 0, timezone.utc)
        game = Game(5, 5, cells, players, 2, True, time)
        game_service = GameService(game)
        sut = NotKillingItselfAI(player1, [], 3, 0, 3)

        actions: List[Action] = sut.find_surviving_actions(game_service, 3)

        self.assertTrue(len(actions) == 0)
    def test_ai_should_choose_best_list_of_actions_by_depth(self):
        player1 = Player(1, 1, 2, Direction.up, 1, True, "")
        player2 = Player(2, 1, 1, Direction.down, 3, True, "")
        players = [player1, player2]
        cells = [[Cell(),           Cell(),          Cell(),            Cell(),             Cell()],
                 [Cell([player2]),  Cell([player2]), Cell([player2]),   Cell(),             Cell()],
                 [Cell(),           Cell([player1]), Cell(),            Cell([player2]),    Cell()],
                 [Cell([player2]),  Cell(), Cell(),            Cell([player2]),    Cell()],
                 [Cell(),           Cell(),          Cell([player2]),   Cell(),             Cell()]]

        time = datetime(2020, 10, 1, 12, 5, 13, 0, timezone.utc)
        game = Game(5, 5, cells, players, 2, True, time)
        game_service = GameService(game)
        sut = NotKillingItselfAI(player1, [], 3, 0, 5)

        actions: List[Action] = sut.find_surviving_actions_with_best_depth(game_service)

        self.assertTrue(Action.turn_right in actions)
        self.assertTrue(len(actions) == 1)
    def test_ai_should_not_choose_speed_up_if_max_speed_is_allready_reached(self):
        MAX_SPEED = 3
        player1 = Player(1, 0, 4, Direction.up, MAX_SPEED, True, "")
        player2 = Player(2, 0, 1, Direction.down, 3, True, "")
        players = [player1, player2]
        cells = [[Cell(), Cell(), Cell(), Cell(), Cell()],
                 [Cell([player2]), Cell(), Cell(), Cell(), Cell()],
                 [Cell(), Cell(), Cell(), Cell(), Cell()],
                 [Cell(), Cell(), Cell(), Cell(), Cell()],
                 [Cell([player1]), Cell(), Cell(), Cell(), Cell()]]
        time = datetime(2020, 10, 1, 12, 5, 13, 0, timezone.utc)
        game = Game(5, 5, cells, players, 2, True, time)
        game_service = GameService(game)
        sut = NotKillingItselfAI(player1, [], MAX_SPEED, 0, 3)

        actions: List[Action] = sut.find_surviving_actions(game_service, 1)

        self.assertTrue(Action.slow_down in actions)
        self.assertTrue(Action.turn_right in actions)
        self.assertTrue(len(actions) == 2)
    def test_ai_should_choose_the_correct_list_of_actions_non_killing_itself(self):
        player1 = Player(1, 0, 1, Direction.up, 1, True, "")
        player2 = Player(2, 4, 4, Direction.down, 3, True, "")
        players = [player1, player2]
        cells = [[Cell(), Cell(), Cell(), Cell(), Cell()],
                 [Cell([player1]), Cell(), Cell(), Cell(), Cell()],
                 [Cell(), Cell(), Cell(), Cell(), Cell()],
                 [Cell(), Cell(), Cell(), Cell(), Cell()],
                 [Cell(), Cell(), Cell(), Cell(), Cell([player2])]]

        time = datetime(2020, 10, 1, 12, 5, 13, 0, timezone.utc)
        game = Game(5, 5, cells, players, 2, True, time)
        game_service = GameService(game)
        sut = NotKillingItselfAI(player1, [], 3, 0, 3)

        actions: List[Action] = sut.find_surviving_actions(game_service, 3)

        self.assertTrue(Action.change_nothing in actions)
        self.assertTrue(Action.turn_right in actions)
        self.assertTrue(len(actions) == 2)
    def test_ai_should_calc_action_with_max_distance(self):
        player1 = Player(1, 0, 4, Direction.up, 1, True, "")
        player2 = Player(2, 0, 1, Direction.down, 3, True, "")
        players = [player1, player2]
        cells = [[Cell(), Cell(), Cell(), Cell(), Cell()],
                 [Cell([player2]), Cell(), Cell(), Cell(), Cell()],
                 [Cell(), Cell(), Cell(), Cell(), Cell()],
                 [Cell(), Cell(), Cell(), Cell(), Cell()],
                 [Cell([player1]), Cell(), Cell(), Cell(), Cell()]]
        time = datetime(2020, 10, 1, 12, 5, 13, 0, timezone.utc)
        game = Game(5, 5, cells, players, 2, True, time)
        game_service = GameService(game)
        sut = NotKillingItselfAI(player1, [], 3, 0, 3)

        actions: List[Action] = sut.calc_action_with_max_distance_to_visited_cells(game_service, [Action.speed_up,
                                                                                                  Action.change_nothing,
                                                                                                  Action.turn_right])

        self.assertTrue(Action.turn_right in actions)
        self.assertTrue(len(actions) == 1)
Пример #13
0
    def create_next_action(self, game: Game, return_value: Value):
        """See base class."""
        self._turn_ctr += 1

        game_service = GameService(game)
        game_service.turn.turn_ctr = self._turn_ctr

        surviving_actions = self.find_surviving_actions_with_best_depth(
            game_service)
        if AIOptions.max_distance in self.__options:
            max_distance_actions = self.calc_action_with_max_distance_to_visited_cells(
                game_service, surviving_actions)
            action = choice(
                max_distance_actions
            ) if max_distance_actions is not None and len(
                max_distance_actions) > 0 else Action.change_nothing
        else:
            action = choice(
                surviving_actions) if surviving_actions is not None and len(
                    surviving_actions) > 0 else Action.change_nothing

        return_value.value = action.get_index()