Exemplo n.º 1
0
    def min_max_search(self, game: ChessGame, depth: int,
                       maximize_color: Color, parent_max: int, parent_min: int,
                       first_move: bool):
        """
        Use minmax search with alpha beta prune to calculate the next best move
        """
        board = game.board
        game_status = game.check_game_status()
        if not depth or game_status != 'Continue':
            if (game_status == "BlackLoss" and maximize_color
                    == Color.WHITE) or (game_status == "WhiteLoss"
                                        and maximize_color == Color.BLACK):
                return math.inf
            ret = self.game_evaluation(maximize_color)
            return ret
        else:
            turn = game.turn

            if turn == maximize_color:
                max_score = parent_min
                for row in range(8):
                    for col in range(8):
                        piece = board[row][col]
                        if piece.color == turn:
                            moves = piece.get_checked_moves()["moves"]
                            src = (row, col)
                            for tar in moves:
                                game.update(src, tar, 'Queen', is_ai=True)
                                child_score = self.min_max_search(
                                    game, depth - 1, maximize_color,
                                    parent_max, max_score, False)
                                game.undo()
                                if child_score > max_score:
                                    if first_move:
                                        self.best_move = [src, tar]
                                    max_score = child_score
                                if max_score > parent_max:
                                    return parent_max
                return max_score
            else:
                min_score = parent_max
                for row in range(8):
                    for col in range(8):
                        piece = board[row][col]
                        if piece.color == turn:
                            moves = piece.get_checked_moves()["moves"]
                            src = (row, col)
                            for tar in moves:
                                game.update(src, tar, 'Queen', is_ai=True)
                                child_score = self.min_max_search(
                                    game, depth - 1, maximize_color, min_score,
                                    parent_min, False)
                                game.undo()
                                if child_score < min_score:
                                    if first_move:
                                        self.best_move = [src, tar]
                                    min_score = child_score
                                if min_score < parent_min:
                                    return parent_min
                return min_score
Exemplo n.º 2
0
class TestUpDate(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_update_start_move_black(self):
        random_num_1 = random.randint(0, 7)
        random_num_2 = random.randint(0, 7)
        for row in range(6, 8):
            for col in range(8):
                self.assertFalse(self.game.update((row, col),
                                 (random_num_1, random_num_2), "Queen"))

    def test_update_ended_without_continue(self):
        self.game.half_move_clock = 49
        self.game.full_move_clock = 100
        self.game.count = 200
        self.game.en_passant_target_notation = "-"
        self.game.castling_notation = "-"
        self.game.turn = Color.WHITE
        empty = Empty(None, Color.EMPTY, -1, -1)
        for row in range(8):
            for col in range(8):
                self.game.board[row][col] = empty
        self.game.board[7][3] = King(self.game, Color.BLACK, 7, 3)
        self.game.board[0][5] = King(self.game, Color.WHITE, 0, 5)
        self.assertTrue(self.game.update((0, 5), (0, 4), "Queen"))
        self.assertFalse(self.game.update((7, 3), (7, 2), "Queen"))

    def test_update_move_pawn(self):
        for col in range(8):
            self.assertTrue(self.game.update((1, col), (3, col), "Queen"))
            self.assertEqual(self.game.en_passant_target_notation, chr(ord('a') + col) + "3")
            self.game.turn = Color.WHITE
        for col in range(8):
            self.assertTrue(self.game.update((3, col), (4, col), "Queen"))
            self.game.turn = Color.WHITE

    def test_update_move_white(self):
        random_num_1 = random.randint(0, 7)
        random_num_2 = random.randint(0, 7)
        self.assertFalse(self.game.update((0, 0), (random_num_1, random_num_2), "Queen"))
        self.game.turn = Color.WHITE
        self.assertTrue(self.game.update((0, 1), (2, 0), "Queen"))
        self.game.turn = Color.WHITE
        self.assertTrue(self.game.update((2, 0), (0, 1), "Queen"))
        self.game.turn = Color.WHITE
        self.assertFalse(self.game.update((0, 2), (random_num_1, random_num_2), "Queen"))
        self.game.turn = Color.WHITE
        self.assertFalse(self.game.update((0, 3), (random_num_1, random_num_2), "Queen"))
        self.game.turn = Color.WHITE
        self.assertFalse(self.game.update((0, 4), (random_num_1, random_num_2), "Queen"))
        self.game.turn = Color.WHITE
        self.assertFalse(self.game.update((0, 5), (random_num_1, random_num_2), "Queen"))
        self.game.turn = Color.WHITE
        self.assertTrue(self.game.update((0, 6), (2, 7), "Queen"))
        self.game.turn = Color.WHITE
        self.assertTrue(self.game.update((2, 7), (0, 6), "Queen"))
        self.game.turn = Color.WHITE
        self.assertFalse(self.game.update((0, 7), (random_num_1, random_num_2), "Queen"))

    def test_update_kings_coordinate(self):
        self.game.update((1, 4), (3, 4), "Queen")
        self.game.update((6, 4), (4, 4), "Queen")
        self.game.update((0, 4), (1, 4), "Queen")
        self.game.update((7, 4), (6, 4), "Queen")
        self.assertEqual(self.game.kings_coordinate[0], (1, 4))
        self.assertEqual(self.game.kings_coordinate[1], (6, 4))

    def test_update_history(self):
        self.game.update((1, 0), (3, 0), "Queen")
        self.game.update((6, 0), (4, 0), "Queen")
        self.game.update((0, 0), (2, 0), "Queen")
        self.game.update((7, 0), (5, 0), "Queen")
        self.game.update((1, 7), (3, 7), "Queen")
        self.game.update((6, 7), (4, 7), "Queen")
        self.game.update((0, 7), (2, 7), "Queen")
        self.game.update((7, 7), (5, 7), "Queen")

        self.assertEqual(self.game.history[0]["fen"], "rnbqkbnr/pppppppp/8/8/P7/8/1PPPPPPP/RNBQKBNR b KQkq a3 0 1")
        self.assertEqual(self.game.history[0]["movement"], {"src": "a2", "tar": "a4"})

        self.assertEqual(self.game.history[1]["fen"], "rnbqkbnr/1ppppppp/8/p7/P7/8/1PPPPPPP/RNBQKBNR w KQkq a6 0 2")
        self.assertEqual(self.game.history[1]["movement"], {"src": "a7", "tar": "a5"})

        self.assertEqual(self.game.history[2]["fen"], "rnbqkbnr/1ppppppp/8/p7/P7/R7/1PPPPPPP/1NBQKBNR b Kkq - 1 2")
        self.assertEqual(self.game.history[2]["movement"], {"src": "a1", "tar": "a3"})

        self.assertEqual(self.game.history[3]["fen"], "1nbqkbnr/1ppppppp/r7/p7/P7/R7/1PPPPPPP/1NBQKBNR w Kk - 2 3")
        self.assertEqual(self.game.history[3]["movement"], {"src": "a8", "tar": "a6"})

        self.assertEqual(self.game.history[4]["fen"], "1nbqkbnr/1ppppppp/r7/p7/P6P/R7/1PPPPPP1/1NBQKBNR b Kk h3 0 3")
        self.assertEqual(self.game.history[4]["movement"], {"src": "h2", "tar": "h4"})

        self.assertEqual(self.game.history[5]["fen"], "1nbqkbnr/1pppppp1/r7/p6p/P6P/R7/1PPPPPP1/1NBQKBNR w Kk h6 0 4")
        self.assertEqual(self.game.history[5]["movement"], {"src": "h7", "tar": "h5"})

        self.assertEqual(self.game.history[6]["fen"], "1nbqkbnr/1pppppp1/r7/p6p/P6P/R6R/1PPPPPP1/1NBQKBN1 b k - 1 4")
        self.assertEqual(self.game.history[6]["movement"], {"src": "h1", "tar": "h3"})

        self.assertEqual(self.game.history[7]["fen"], "1nbqkbn1/1pppppp1/r6r/p6p/P6P/R6R/1PPPPPP1/1NBQKBN1 w - - 2 5")
        self.assertEqual(self.game.history[7]["movement"], {"src": "h8", "tar": "h6"})