Example #1
0
    def create_all_next_surviving_actions(self, game: Game) -> List[Action]:
        """Calculates not only one but all actions that will let the player survive for the next rounds.

        Args:
            game: The current state of the game.

        Returns:
            A list of actions which will let the player survive for the next rounds.
        """

        root = SearchTreeRoot(game.copy())
        player_ids_to_watch = game.get_other_player_ids(
            self.player, self.__distance_to_check, True)
        combinations = Action.get_combinations(len(player_ids_to_watch))

        search_tree_actions = []

        for action in Action.get_actions():
            if root.calculate_action(self.player, player_ids_to_watch,
                                     combinations, self.__depth,
                                     self._turn_ctr, True, [action],
                                     self._max_speed, True) is not None:
                search_tree_actions.append(action)

        return search_tree_actions
    def test_get_random_action(self):
        not_expected = Action.get_random_action()

        result = Action.get_random_action()
        while not_expected == result:
            result = Action.get_random_action()

        self.assertNotEqual(not_expected, result)
    def test_get_actions_randomly(self):
        not_expected = []
        for action in list(Action):
            not_expected.append(action)

        result = Action.get_actions(True)
        while result == not_expected:
            result = Action.get_actions(True)

        self.assertNotEqual(not_expected, result)
Example #4
0
    def create_next_action(self, game: Game, return_value: Value):
        """See base class."""
        self._turn_ctr += 1

        root = SearchTreeRoot(game.copy())
        player_ids_to_watch = game.get_other_player_ids(
            self.player, self.__distance_to_check, True)
        combinations = Action.get_combinations(len(player_ids_to_watch))

        action = root.calculate_action(self.player, player_ids_to_watch,
                                       combinations, self.__depth,
                                       self._turn_ctr, True, [],
                                       self._max_speed, self.__randomize)
        return_value.value = (action if action is not None else
                              Action.get_random_action()).get_index()
    def __choose_ai_action(self, ai: ArtificialIntelligence, time_to_react: int) -> Action:
        return_value = multiprocessing.Value('i', Action.get_default().get_index())

        process = multiprocessing.Process(target=Controller.call_ai, args=(ai, self._game.copy(), return_value,))
        start = datetime.now(time_zone)
        process.start()
        process.join(time_to_react - 1)  # wait time_to_react seconds minus one for the calculation to be finished

        if process.is_alive():
            # If an execution is terminated, the execution time is set to 1 minute.
            start = datetime.now(time_zone) - timedelta(seconds=60)
            process.terminate()

        self._log_execution_time(ai, (datetime.now(time_zone) - start).total_seconds())
        return Action.get_by_index(return_value.value)
    def test_should_select_action_to_let_player_survive_next_two_rounds(self):
        game = self.data_loader.load(tests.read_test_file("ai/game_4.json"))

        result = Value('i')
        self.sut.create_next_action(game, result)

        self.assertEqual(Action.turn_left, Action.get_by_index(result.value))
Example #7
0
    def do_action(self, player: Player, action: Action):
        """Performs the action for a player.

        Additionally it checks if the game is finished and which players have died when a new turn starts.

        Args:
            player: The player who wants to perform the action.
            action: The action to perform.
        Raises:
            InvalidPlayerMoveException:
                The player is outside the field, has reached an invalid player speed or was not
                allowed to take any further action this turn.
        """
        try:
            new_turn = self.turn.action(player)
            action_to_perform = action \
                if self.__ignore_deadline or datetime.now(self.game.deadline.tzinfo) <= self.game.deadline \
                else Action.get_default()
            self.visited_cells_by_player[player.id] = self.get_and_visit_cells(
                player, action_to_perform)

            if new_turn:
                self.check_and_set_died_players()

        except InvalidPlayerMoveException:
            self.set_player_inactive(player)

        self.game.running = self.is_game_running()
    def test_create_combinations_as_product(self):
        player_count = 4

        result = Action.get_combinations(player_count)

        self.assertEqual(pow(len(Action), player_count), len(result))
        self.assertEqual(player_count, len(result[0]))
    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)
    def test_get_actions_in_order(self):
        expected = []
        for action in list(Action):
            expected.append(action)

        result = Action.get_actions()

        self.assertEqual(expected, result)
    def test_should_select_action_to_let_player_survive_next_two_rounds_2(self):
        game = self.data_loader.load(tests.read_test_file("ai/game_3.json"))
        sut = SearchTreeAI(game.you, 2, 2)

        result = Value('i')
        sut.create_next_action(game, result)

        self.assertEqual(Action.slow_down, Action.get_by_index(result.value))
    def test_should_select_action_to_let_player_survive_next_round(self):
        game = self.data_loader.load(tests.read_test_file("ai/game_1.json"))
        sut = SearchTreeAI(game.you, 1, 3, True)

        result = Value('i')
        sut.create_next_action(game, result)

        self.assertEqual(Action.turn_right, Action.get_by_index(result.value))
Example #13
0
    def test_online_connection_can_be_executed(self, connect_mock):
        connect_mock.return_value = mock
        view = Mock()
        data_loader = Mock()
        data_loader.load.side_effect = [create_game(True), create_game(False)]
        data_writer = Mock()
        data_writer.write.return_value = Action.get_default()
        controller = OnlineController(view, "", "", "", data_loader,
                                      data_writer, PathfindingAI.__name__,
                                      (2, 75))

        controller.play()

        view.update.assert_has_calls([call(ANY), call(ANY)], any_order=False)
        view.end.assert_called_once()
        data_loader.load.assert_has_calls([call(""), call("")],
                                          any_order=False)
        mock.send.assert_has_calls([call(Action.get_default())])
    def test_read_next_action_should_return_correct_action_input_close(self, sys_exit, time_sleep):
        mock_event = Mock()
        mock_event.type = pygame_mock.QUIT = 2
        pygame_mock.event.get.return_value = [mock_event]

        result = self.sut.read_next_action()

        self.assertEqual(Action.get_default(), result)
        pygame_mock.display.quit.assert_called()
        pygame_mock.quit.assert_called()
Example #15
0
    def test_create_action_should_return_action_with_best_connection(self):
        player1 = Player(1, 0, 0, Direction.down, 1, True, "")
        player2 = Player(2, 0, 2, Direction.down, 3, True, "")
        players = [player1, player2]
        cells = [[Cell([player1]),  Cell(),             Cell()],
                 [Cell(),           Cell([player2]),    Cell()],
                 [Cell([player2]),  Cell(),             Cell()]]
        game = Game(3, 3, cells, players, 2, True, datetime.now())
        sut = PathfindingAI(player1, 2, 10)

        result = Value('i')
        sut.create_next_action(game, result)

        self.assertEqual(Action.turn_left, Action.get_by_index(result.value))
Example #16
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()
    def __choose_action(self, game: Game,
                        time_zone: datetime.tzinfo) -> Action:
        return_value = multiprocessing.Value('i')
        self.__default_ai.create_next_action(game, return_value)

        own_time = datetime.now(time_zone)
        seconds_for_calculation = (game.deadline - own_time).seconds

        process = multiprocessing.Process(target=Controller.call_ai,
                                          args=(
                                              self.__ai,
                                              game,
                                              return_value,
                                          ))
        process.start()
        process.join(seconds_for_calculation - 1)

        if process.is_alive():
            process.terminate()

        return Action.get_by_index(return_value.value)
Example #18
0
 def read_next_action(self) -> Action:  # noqa: C901
     """See base class."""
     while True:
         for event in self.__pygame.event.get():
             if event.type == self.__pygame.QUIT:  # Allows to close the pygame-window
                 self.end()
                 return Action.get_default()
             elif event.type == self.__pygame.KEYDOWN:
                 pressed_key = self.__pygame.key.get_pressed()
                 self.__next_action = False
                 if pressed_key[self.__pygame.K_UP]:
                     return Action.speed_up
                 elif pressed_key[self.__pygame.K_DOWN]:
                     return Action.slow_down
                 elif pressed_key[self.__pygame.K_RIGHT]:
                     return Action.turn_right
                 elif pressed_key[self.__pygame.K_LEFT]:
                     return Action.turn_left
                 elif pressed_key[self.__pygame.K_SPACE]:
                     return Action.change_nothing
             elif event.type == self.__pygame.KEYUP:
                 self.__next_action = True
Example #19
0
 def __get_actions(root: bool, first_actions: List[Action], randomize: bool) -> List[Action]:
     if root and first_actions is not None and len(first_actions) >= 1:
         return first_actions
     return Action.get_actions(randomize)
Example #20
0
 def create_next_action(self, game: Game, return_value: Value):
     """See base class."""
     self._turn_ctr += 1
     action = Action.get_random_action()
     return_value.value = action.get_index()
Example #21
0
 def create_next_action(self, game: Game, return_value: Value):
     """See base class."""
     self._turn_ctr += 1
     actions = self.create_next_actions_ranked(game)
     action = actions[0][0] if actions is not None and len(actions) > 0 else Action.get_random_action()
     return_value.value = action.get_index()