예제 #1
0
    def test_optimized_combined_heuristic(self):
        """test that the optimized, stateful heuristic provides the same
        values as the non-optimized one"""
        heuristic = CombinedHeuristic()
        optimized_heuristic = OptimizedCombinedHeuristic()

        game_1 = CCGame(width=5, visitors=[optimized_heuristic])

        def heuristics_agree():
            for player in [1, 2]:
                self.assertAlmostEqual(heuristic.value(game_1, player),
                                       optimized_heuristic.value(game_1,
                                                                 player),
                                       2)

        game_1.move(2, 1, CCMovement.LS)
        heuristics_agree()

        game_1.move(7, 1, CCMovement.RN)
        heuristics_agree()

        game_1.undo_last_move()
        game_1.rotate_turn()
        heuristics_agree()

        game_1.undo_last_move()
        heuristics_agree()
예제 #2
0
    def test_zobrist_hashing(self):
        game = CCGame(width=5)

        hasher = CCZobristHash(game)

        game_2 = CCGame(width=5)

        self.assertEqual(hasher.get_hash(game), hasher.get_hash(game_2))

        game.move(2, 0, CCMovement.LS)

        self.assertFalse(hasher.get_hash(game) == hasher.get_hash(game_2))
 def test_available_moves_depth_2(self):
     game = CCGame(width=5)
     game.move(2, 0, CCMovement.RS)
     game.rotate_turn()
     moves = CCReasoner.available_moves(game, 1)
     self.assertTrue(
         CCMove([(0,
                  0), (2,
                       0), (4,
                            2)], [CCMovement.LS, CCMovement.RS]) in moves)
     self.assertTrue(
         CCMove([(1, 0), (3,
                          2), (3,
                               0)], [CCMovement.RS, CCMovement.L]) in moves)
     self.assertTrue(
         CCMove([(2, 2), (2,
                          0), (4,
                               2)], [CCMovement.L, CCMovement.RS]) in moves)
예제 #4
0
    def _available_moves(game: CCGame,
                         row: int,
                         column: int,
                         player: int,
                         previous_moves: list = [],
                         previous_positions: list = []) -> List[CCMove]:
        """
        Returns a dict a list of movements that the player
        can make, considering the piece found at 'row' and 'column'
        """
        moves: List[CCMove] = []
        jumping = game.player_can_only_jump

        def undo_movement():
            if game.player_turn != player:
                game.rotate_turn()
            game.undo_last_move()
            if not jumping and game.player_can_only_jump:
                # reset jumping state
                game.player_can_only_jump = False

        for movement in CCMovement:
            if game.can_move(row, column, movement):
                turn = game.move(row, column, movement)
                if (game.moved_to_row[-1],
                        game.moved_to_column[-1]) in previous_positions:
                    # we already passed through this state, avoid
                    # infinite recursion
                    undo_movement()
                    continue
                previous_positions.append(
                    (game.moved_to_row[-1], game.moved_to_column[-1]))
                previous_moves.append(movement)
                moves.append(CCMove([*previous_positions], [*previous_moves]))
                if turn == player:
                    # turn hasn't rotated -> current piece can still jump more
                    moves += (CCReasoner._available_moves(
                        game, game.moved_to_row[-1], game.moved_to_column[-1],
                        player, previous_moves, previous_positions))
                previous_positions.pop()
                previous_moves.pop()
                undo_movement()

        return moves