Beispiel #1
0
    def test_is_not_stalemate(self):
        """
        Configure board where white player has one legal move.
        Expected result is stalemate has not occurred.
        :return:
        """
        # Try for king
        board = ChessBoard()
        board['a8'] = King(Color.BLACK)
        board['c1'] = Rook(Color.WHITE)
        board['d7'] = Rook(Color.WHITE)

        is_stalemate = board.is_stalemate(Color.BLACK)
        self.assertFalse(is_stalemate,
                         'Board configuration should not result in stalemate')

        # Try for piece other than king
        board = ChessBoard()
        board['a8'] = King(Color.BLACK)
        board['b1'] = Rook(Color.WHITE)
        board['d7'] = Rook(Color.WHITE)
        board['f2'] = Pawn(Color.BLACK)

        is_stalemate = board.is_stalemate(Color.BLACK)
        self.assertFalse(is_stalemate,
                         'Board configuration should not result in stalemate')
    def test_piece_pinned(self):
        """
        Test moving a piece of every type that is the same color as king but pinned by opponents piece.
        Expected result is legal move list for piece should be empty.
        :return:
        """
        # Pawn pined
        board = ChessBoard()
        board['c3'] = King(Color.WHITE)
        board['d4'] = Pawn(Color.WHITE)
        board['f6'] = Bishop(Color.BLACK)

        legal_moves = board.get_legal_moves('d4')
        self.assertListEqual([], legal_moves,
                             'Piece should not have any legal moves.')

        # Rook pined
        board = ChessBoard()
        board['c3'] = King(Color.WHITE)
        board['d4'] = Rook(Color.WHITE)
        board['f6'] = Bishop(Color.BLACK)

        legal_moves = board.get_legal_moves('d4')
        self.assertListEqual([], legal_moves,
                             'Piece should not have any legal moves.')

        # Knight pined
        board = ChessBoard()
        board['c3'] = King(Color.WHITE)
        board['d4'] = Knight(Color.WHITE)
        board['f6'] = Bishop(Color.BLACK)

        legal_moves = board.get_legal_moves('d4')
        self.assertListEqual([], legal_moves,
                             'Piece should not have any legal moves.')

        # Bishop pined
        board = ChessBoard()
        board['c3'] = King(Color.WHITE)
        board['c5'] = Bishop(Color.WHITE)
        board['c6'] = Rook(Color.BLACK)

        legal_moves = board.get_legal_moves('c5')
        self.assertListEqual([], legal_moves,
                             'Piece should not have any legal moves.')

        # Queen kinda pined
        board = ChessBoard()
        board['c3'] = King(Color.WHITE)
        board['c4'] = Queen(Color.WHITE)
        board['c6'] = Rook(Color.BLACK)

        legal_moves = board.get_legal_moves('c4')
        self.assertListEqual(['c5', 'c6'], legal_moves,
                             'Legal moves dont match expected moves.')
Beispiel #3
0
 def test_rook_checkmate(self):
     """
     Test that a rook will put a king of the opposite color in checkmate
     :return:
     """
     board = ChessBoard()
     board['a3'] = King(Color.WHITE)
     board['a5'] = Rook(Color.BLACK)
     board['b8'] = Rook(Color.BLACK)
     self.assertTrue(board.is_checkmate(Color.WHITE),
                     'King should be in checkmate')
Beispiel #4
0
    def test_king_perform_castle(self):
        """
        Perform castle to left and right with black king and white king.
        Expected result is king is moved two places to the left or right and the rook in that direction is
        moved on the other side of the king.
        :return:
        """
        castle_expected_result = {
            Color.WHITE: [{
                'king_move': ('e1', 'c1'),
                'rook_move': ('a1', 'd1')
            }, {
                'king_move': ('e1', 'g1'),
                'rook_move': ('h1', 'f1')
            }],
            Color.BLACK: [{
                'king_move': ('e8', 'c8'),
                'rook_move': ('a8', 'd8')
            }, {
                'king_move': ('e8', 'g8'),
                'rook_move': ('h8', 'f8')
            }]
        }

        for color, left_right_castle in castle_expected_result.items():
            for castle_info in left_right_castle:
                with self.subTest(color=color, castle_info=castle_info):
                    board = ChessBoard()
                    king_start, king_end = castle_info['king_move']
                    rook_start, rook_end = castle_info['rook_move']
                    board[king_start] = King(color)
                    board[rook_start] = Rook(color)

                    move_result = board.move_piece(king_start, king_end)

                    self.assertEqual(Type.KING, board[king_end].type,
                                     'King should have moved two spaces')
                    self.assertEqual(Type.ROOK, board[rook_end].type,
                                     'Rook should be on other side of king')
                    self.assertIsNone(board[rook_start],
                                      'Rook should have been moved')

                    expected_result = {
                        king_start: None,
                        king_end: King(color),
                        rook_start: None,
                        rook_end: Rook(color),
                    }
                    self.assertDictEqual(
                        expected_result, move_result,
                        'Expected move result does not match actual')
Beispiel #5
0
    def test_king_movement_adjusted_after_right_rook_moves(self):
        """
        Move the queen side rook for white and black player
        Expected result is king can no longer castle queen side.
        :return:
        """
        board = ChessBoard()
        king_positions = {Color.WHITE: 'e1', Color.BLACK: 'e8'}
        rook_positions = {Color.WHITE: ('h1', 'h2'), Color.BLACK: ('a8', 'a7')}
        expected_directions = {
            MoveDirection.FORWARD: 1,
            MoveDirection.F_RIGHT_DIAG: 1,
            MoveDirection.RIGHT: 1,
            MoveDirection.B_RIGHT_DIAG: 1,
            MoveDirection.BACKWARD: 1,
            MoveDirection.B_LEFT_DIAG: 1,
            MoveDirection.LEFT: 2,
            MoveDirection.F_LEFT_DIAG: 1
        }

        for color in [Color.BLACK, Color.WHITE]:
            with self.subTest(color=color,
                              king_pos=king_positions[color],
                              rook_pos=rook_positions[color]):
                king_pos = king_positions[color]
                rook_start, rook_end = rook_positions[color]
                board[king_pos] = King(color)
                board[rook_start] = Rook(color)
                board.move_piece(rook_start, rook_end)

                self.assertDictEqual(expected_directions,
                                     board[king_pos].move_directions,
                                     'Incorrect move_directions')
Beispiel #6
0
    def test_empty_fen(self):
        """
        Create fen object without supplying a FEN string
        Expect default chess board
        :return:
        """
        fen = Fen()

        expected_board = {
            'a1': Rook(Color.WHITE), 'b1': Knight(Color.WHITE), 'c1': Bishop(Color.WHITE), 'd1': Queen(Color.WHITE),
            'e1': King(Color.WHITE), 'f1': Bishop(Color.WHITE), 'g1': Knight(Color.WHITE), 'h1': Rook(Color.WHITE),
            'a2': Pawn(Color.WHITE), 'b2': Pawn(Color.WHITE), 'c2': Pawn(Color.WHITE), 'd2': Pawn(Color.WHITE),
            'e2': Pawn(Color.WHITE), 'f2': Pawn(Color.WHITE), 'g2': Pawn(Color.WHITE), 'h2': Pawn(Color.WHITE),
            'a8': Rook(Color.BLACK), 'b8': Knight(Color.BLACK), 'c8': Bishop(Color.BLACK), 'd8': Queen(Color.BLACK),
            'e8': King(Color.BLACK), 'f8': Bishop(Color.BLACK), 'g8': Knight(Color.BLACK), 'h8': Rook(Color.BLACK),
            'a7': Pawn(Color.BLACK), 'b7': Pawn(Color.BLACK), 'c7': Pawn(Color.BLACK), 'd7': Pawn(Color.BLACK),
            'e7': Pawn(Color.BLACK), 'f7': Pawn(Color.BLACK), 'g7': Pawn(Color.BLACK), 'h7': Pawn(Color.BLACK),
        }
        self.assertEqual(expected_board, fen.board)
    def test_king_castle_legal_move(self):
        """
        Place king on starting square and rooks of the same color on their starting squares.
        Expected result is that queen side and king side castling is listed in legal moves list.
        :return:
        """
        board = ChessBoard()
        board['a1'] = Rook(Color.WHITE)
        board['e1'] = King(Color.WHITE)
        board['a8'] = Rook(Color.BLACK)
        board['e8'] = King(Color.BLACK)

        # Try with just one rook.
        expected_legal_moves = {
            'e1': ['c1', 'd1', 'd2', 'e2', 'f1', 'f2'],
            'e8': ['c8', 'd7', 'd8', 'e7', 'f7', 'f8'],
        }
        for position, expected_moves in expected_legal_moves.items():
            with self.subTest(position=position,
                              expected_moves=expected_moves):
                legal_moves = board.get_legal_moves(position)
                legal_moves.sort()
                self.assertListEqual(
                    expected_moves, legal_moves,
                    'Castle move should be in legal move list')

        # Try with both rooks.
        board['h1'] = Rook(Color.WHITE)
        board['h8'] = Rook(Color.BLACK)
        expected_legal_moves = {
            'e1': ['c1', 'd1', 'd2', 'e2', 'f1', 'f2', 'g1'],
            'e8': ['c8', 'd7', 'd8', 'e7', 'f7', 'f8', 'g8'],
        }
        for position, expected_moves in expected_legal_moves.items():
            with self.subTest(position=position,
                              expected_moves=expected_moves):
                legal_moves = board.get_legal_moves(position)
                legal_moves.sort()
                self.assertListEqual(
                    expected_moves, legal_moves,
                    'Castle move should be in legal move list')
Beispiel #8
0
 def test_knight_checkmate(self):
     """
     Test that a knight will put a king of the opposite color in checkmate
     :return:
     """
     board = ChessBoard()
     board['b4'] = Bishop(Color.BLACK)
     board['c5'] = Rook(Color.BLACK)
     board['d1'] = King(Color.WHITE)
     board['e3'] = Knight(Color.BLACK)
     board['f3'] = Pawn(Color.BLACK)
     self.assertTrue(board.is_checkmate(Color.WHITE),
                     'King should be in checkmate')
Beispiel #9
0
    def test_rook_capture(self):
        """
        Move a rook to square where there are pieces of the opposite color on capture file and rank.
        Expected result is that the squares that contain the pieces of the opposite color are in the list of possible
        moves for the rook. One opposing piece is also successfully captured by rook.
        :return:
        """
        board = ChessBoard()
        start_position = 'b1'
        capture_position = 'e1'
        board[start_position] = Rook(Color.WHITE)
        board['c2'] = Bishop(Color.BLACK)
        board['c8'] = Pawn(Color.BLACK)
        board['e1'] = Bishop(Color.BLACK)

        # Test possible moves with several pieces on possible capture squares
        expected_possible_moves = [
            'a1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'c1', 'd1', 'e1'
        ]
        possible_moves = board.get_legal_moves(start_position)
        possible_moves.sort()

        message = 'Expected move list does not match actual move list'
        self.assertListEqual(expected_possible_moves, possible_moves, message)

        # Confirm piece is captured
        move_result = board.move_piece(start_position, capture_position)
        message = 'Rook should have captured piece on ' + capture_position + ' square'
        self.assertIsInstance(board[capture_position], Rook, message)

        # Test move result
        expected_move_result = {
            start_position: None,
            capture_position: Rook(Color.WHITE)
        }
        self.assertDictEqual(expected_move_result, move_result,
                             'Expected move result does not match actual')
Beispiel #10
0
    def test_can_castle(self):
        """
        Test that a king can perform a castle
        :return:
        """
        board = ChessBoard()

        # Check from white perspective
        board['a1'] = Rook(Color.WHITE)
        board['e1'] = King(Color.WHITE)
        board['h1'] = Rook(Color.WHITE)
        self.assertTrue(board.can_castle(Color.WHITE, MoveDirection.LEFT),
                        'King should be able to castle')
        self.assertTrue(board.can_castle(Color.WHITE, MoveDirection.RIGHT),
                        'King should be able to castle')

        # Check from black perspective
        board['a8'] = Rook(Color.BLACK)
        board['e8'] = King(Color.BLACK)
        board['h8'] = Rook(Color.BLACK)
        self.assertTrue(board.can_castle(Color.BLACK, MoveDirection.LEFT),
                        'King should be able to castle')
        self.assertTrue(board.can_castle(Color.BLACK, MoveDirection.RIGHT),
                        'King should be able to castle')
Beispiel #11
0
    def test_is_stalemate(self):
        """
        Test case where it is a players move and they have no valid moves left.
        Expected result is a stalemate has occurred.
        :return:
        """
        board = ChessBoard()
        board['a1'] = King(Color.BLACK)
        board['b4'] = Rook(Color.WHITE)
        board['c2'] = King(Color.WHITE)
        board['c4'] = Bishop(Color.WHITE)

        is_stalemate = board.is_stalemate(Color.BLACK)
        self.assertTrue(is_stalemate,
                        'Board configuration should result in stalemate')
Beispiel #12
0
 def test_queen_checkmate(self):
     """
     Test that a queen will put a king of the opposite color in checkmate
     :return:
     """
     board = ChessBoard()
     board['d6'] = King(Color.BLACK)
     board['c5'] = Pawn(Color.BLACK)
     board['e5'] = Pawn(Color.BLACK)
     board['a5'] = Bishop(Color.WHITE)
     board['d5'] = Queen(Color.WHITE)
     board['d2'] = Rook(Color.WHITE)
     board['g6'] = Knight(Color.WHITE)
     self.assertTrue(board.is_checkmate(Color.BLACK),
                     'King should be in checkmate')
Beispiel #13
0
    def test_move_result_checkmate(self):
        """
        Move a piece to place the king in checkmate.
        Expected result is the king is placed in checkmate an the is_over flag is set to True.
        :return:
        """
        self.p1.color = Color.WHITE
        self.p2.color = Color.BLACK

        # Confirm checkmate and game_over flag set to True
        # Minimal
        fen = '8/8/8/8/6q1/3k4/8/4K3 b - -'
        game = ChessGame(fen=fen, white_player=self.p1, black_player=self.p2)
        self.assertFalse(game.is_over)

        result = game.move_piece('g4', 'e2')
        expected_move_result = MoveResult()
        expected_move_result.update_positions = {'g4': None, 'e2': Queen(Color.BLACK)}
        expected_move_result.king_in_checkmate = self.p1
        expected_move_result.king_in_check = self.p1
        self.assertEqual(expected_move_result, result)
        self.assertTrue(game.is_over)

        # Medium
        fen = '8/1r6/8/4k3/1q6/8/8/K7 b KQkq -'
        game = ChessGame(fen=fen, white_player=self.p1, black_player=self.p2)
        self.assertFalse(game.is_over)

        result = game.move_piece('b7', 'a7')
        expected_move_result = MoveResult()
        expected_move_result.update_positions = {'b7': None, 'a7': Rook(Color.BLACK)}
        expected_move_result.king_in_checkmate = self.p1
        expected_move_result.king_in_check = self.p1
        self.assertEqual(expected_move_result, result)
        self.assertTrue(game.is_over)

        # Complex
        fen = '8/3n4/4b3/2q1k3/K7/2P5/3RB1p1/8 b - -'
        game = ChessGame(fen=fen, white_player=self.p1, black_player=self.p2)
        self.assertFalse(game.is_over)

        result = game.move_piece('d7', 'b6')
        expected_move_result = MoveResult()
        expected_move_result.update_positions = {'d7': None, 'b6': Knight(Color.BLACK)}
        expected_move_result.king_in_checkmate = self.p1
        expected_move_result.king_in_check = self.p1
        self.assertEqual(expected_move_result, result)
        self.assertTrue(game.is_over)
Beispiel #14
0
 def test_rook_check(self):
     """
     Test that a rook will put a king of the opposite color in check
     :return:
     """
     piece_positions = [('a1', 'a8'), ('a1', 'h1'), ('a8', 'a1'),
                        ('a8', 'h8'), ('h8', 'a8'), ('h8', 'h1'),
                        ('h1', 'a1'), ('h1', 'h8')]
     for positions in piece_positions:
         rook_position, king_position = positions
         with self.subTest(rook_position=rook_position,
                           king_position=king_position):
             board = ChessBoard()
             board[rook_position] = Rook(Color.BLACK)
             board[king_position] = King(Color.WHITE)
             self.assertTrue(board.is_check(Color.WHITE),
                             'Rook should put king in check')
Beispiel #15
0
    def test_move_result_draw(self):
        """
        Move piece to create a draw situation.
        Expected result is game over flag is set and so is draw move result flag.
        :return:
        """
        self.p1.color = Color.WHITE
        self.p2.color = Color.BLACK

        fen = 'k7/4K3/2N5/8/3R4/8/8/8 w - -'
        game = ChessGame(fen=fen, white_player=self.p1, black_player=self.p2)
        result = game.move_piece('d4', 'b4')
        expected_promote_result = MoveResult()
        expected_promote_result.update_positions = {'d4': None, 'b4': Rook(Color.WHITE)}
        expected_promote_result.draw = True

        self.assertEqual(expected_promote_result, result)
        self.assertTrue(game.is_over)
Beispiel #16
0
    def test_pawn_capture(self):
        """
        Move a pawn to a square where there is a piece of the opposite color on one of the most immediate diagonal
        squares.
        Expected result is that the square that contains the piece of the opposite color is in the list of possible
        moves for the pawn. Opposing piece is also successfully captured by pawn.
        :return:
        """
        # Test diagonal move when a piece of the opposite color is present
        board = ChessBoard()
        start_position = 'b1'
        capture_position = 'c2'
        board[start_position] = Pawn(Color.WHITE)
        board['c2'] = Bishop(Color.BLACK)
        expected_possible_moves = ['b2', 'b3', 'c2']
        possible_moves = board.get_legal_moves(start_position)
        possible_moves.sort()

        message = 'Expected pawn to be able to move diagonally'
        self.assertListEqual(expected_possible_moves, possible_moves, message)

        # place a second piece and confirm both diagonals show as possible moves
        board['a2'] = Rook(Color.BLACK)
        expected_possible_moves = ['a2', 'b2', 'b3', 'c2']
        possible_moves = board.get_legal_moves(start_position)
        possible_moves.sort()

        message = 'Expected pawn to be able to move diagonally in both directions'
        self.assertListEqual(expected_possible_moves, possible_moves, message)

        # Move pawn to capture a piece
        move_result = board.move_piece(start_position, capture_position)
        message = 'Pawn should have captured piece on ' + capture_position + ' square'
        self.assertIsInstance(board[capture_position], Pawn, message)

        # Test move result
        expected_move_result = {
            start_position: None,
            capture_position: Pawn(Color.WHITE)
        }
        self.assertDictEqual(expected_move_result, move_result,
                             'Expected move result does not match actual')
    def test_king_cant_put_self_in_check(self):
        """
        Place king in middle square. Place rook of opposing color on an immediate front right diagonal square.
        Expected result is the space directly to the right and in front of king is not in legal moves list.
        :return:
        """
        color_group = [(Color.WHITE, Color.BLACK), (Color.BLACK, Color.WHITE)]
        for group in color_group:
            with self.subTest(group=group):
                board = ChessBoard()
                king_color, rook_color = group
                board['d4'] = King(king_color)
                board['e5'] = Rook(rook_color)

                expected_moves = ['c3', 'c4', 'd3', 'e5']
                legal_moves = board.get_legal_moves('d4')
                legal_moves.sort()
                self.assertListEqual(
                    expected_moves, legal_moves,
                    'King should not be able to put self in check')
Beispiel #18
0
    def test_rook_cant_capture(self):
        """
        Move rook to a square and another piece of the same color immediately to the right of the rook.
        Expected result is that the square containing the pieces of the same color is not in the list of legal
        moves for the rook.
        :return:
        """
        color_group = [Color.WHITE, Color.BLACK]
        for color in color_group:
            with self.subTest(color=color):
                board = ChessBoard()
                board['d4'] = Rook(color)
                board['e4'] = Pawn(color)

                expected_moves = [
                    'a4', 'b4', 'c4', 'd1', 'd2', 'd3', 'd5', 'd6', 'd7', 'd8'
                ]
                legal_moves = board.get_legal_moves('d4')
                legal_moves.sort()
                self.assertListEqual(
                    expected_moves, legal_moves,
                    'Expected moves does not match legal moves')
Beispiel #19
0
    def test_different_board_setups(self):
        """
        Create Fen object using empty board, middle game, end game
        Expect board config to match expected value
        :return:
        """
        # Empty board
        fen_str = '8/8/8/8/8/8/8/8 w - -'
        expected_board1 = {}
        fen = Fen(fen_str)
        self.assertEqual(expected_board1, fen.board)

        # Partial game
        fen_str = 'r2qkbnr/2pp1ppp/b1n5/1N2p3/4P1Q1/8/PPPP1PPP/R1B1K1NR w KQkq -'
        expected_board2 = {
            'a1': Rook(Color.WHITE), 'c1': Bishop(Color.WHITE), 'e1': King(Color.WHITE), 'g1': Knight(Color.WHITE),
            'h1': Rook(Color.WHITE), 'a2': Pawn(Color.WHITE), 'b2': Pawn(Color.WHITE), 'c2': Pawn(Color.WHITE),
            'd2': Pawn(Color.WHITE), 'f2': Pawn(Color.WHITE), 'g2': Pawn(Color.WHITE), 'h2': Pawn(Color.WHITE),
            'a8': Rook(Color.BLACK), 'd8': Queen(Color.BLACK), 'e8': King(Color.BLACK), 'f8': Bishop(Color.BLACK),
            'g8': Knight(Color.BLACK), 'h8': Rook(Color.BLACK),'c7': Pawn(Color.BLACK), 'd7': Pawn(Color.BLACK),
            'f7': Pawn(Color.BLACK), 'g7': Pawn(Color.BLACK), 'h7': Pawn(Color.BLACK), 'a6': Bishop(Color.BLACK),
            'c6': Knight(Color.BLACK), 'e5': Pawn(Color.BLACK), 'b5': Knight(Color.WHITE), 'e4': Pawn(Color.WHITE),
            'g4': Queen(Color.WHITE)
        }
        fen = Fen(fen_str)
        self.assertEqual(expected_board2, fen.board)

        # End game
        fen_str = '5rk1/7p/8/4p1p1/2nP4/2PB4/bP4QP/2K4R w - -'
        expected_board3 = {
            'c1': King(Color.WHITE), 'h1': Rook(Color.WHITE), 'b2': Pawn(Color.WHITE), 'g2': Queen(Color.WHITE),
            'h2': Pawn(Color.WHITE), 'c3': Pawn(Color.WHITE), 'd3': Bishop(Color.WHITE), 'd4': Pawn(Color.WHITE),
            'a2': Bishop(Color.BLACK), 'c4': Knight(Color.BLACK), 'e5': Pawn(Color.BLACK), 'g5': Pawn(Color.BLACK),
            'h7': Pawn(Color.BLACK), 'f8': Rook(Color.BLACK), 'g8': King(Color.BLACK)
        }
        fen = Fen(fen_str)
        self.assertEqual(expected_board3, fen.board)
    def test_rook_legal_moves(self):
        """
        Move a rook to each corner and one middle square.
        Expected result is that all the possible moves match the expected list.
        :return:
        """
        start_positions = {
            Color.WHITE: {
                'a1': [
                    'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'b1', 'c1', 'd1',
                    'e1', 'f1', 'g1', 'h1'
                ],
                'a8': [
                    'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'b8', 'c8', 'd8',
                    'e8', 'f8', 'g8', 'h8'
                ],
                'h1': [
                    'a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h2', 'h3', 'h4',
                    'h5', 'h6', 'h7', 'h8'
                ],
                'h8': [
                    'a8', 'b8', 'c8', 'd8', 'e8', 'f8', 'g8', 'h1', 'h2', 'h3',
                    'h4', 'h5', 'h6', 'h7'
                ],
                'd4': [
                    'a4', 'b4', 'c4', 'd1', 'd2', 'd3', 'd5', 'd6', 'd7', 'd8',
                    'e4', 'f4', 'g4', 'h4'
                ]
            },
            Color.BLACK: {
                'a1': [
                    'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'b1', 'c1', 'd1',
                    'e1', 'f1', 'g1', 'h1'
                ],
                'a8': [
                    'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'b8', 'c8', 'd8',
                    'e8', 'f8', 'g8', 'h8'
                ],
                'h1': [
                    'a1', 'b1', 'c1', 'd1', 'e1', 'f1', 'g1', 'h2', 'h3', 'h4',
                    'h5', 'h6', 'h7', 'h8'
                ],
                'h8': [
                    'a8', 'b8', 'c8', 'd8', 'e8', 'f8', 'g8', 'h1', 'h2', 'h3',
                    'h4', 'h5', 'h6', 'h7'
                ],
                'd4': [
                    'a4', 'b4', 'c4', 'd1', 'd2', 'd3', 'd5', 'd6', 'd7', 'd8',
                    'e4', 'f4', 'g4', 'h4'
                ]
            }
        }
        for color, positions in start_positions.items():
            for start_position, expected_moves in positions.items():
                with self.subTest(color=color,
                                  start_position=start_position,
                                  expected_moves=expected_moves):
                    board = ChessBoard()
                    board[start_position] = Rook(color)
                    possible_moves = board.get_legal_moves(start_position)
                    possible_moves.sort()

                    message = 'Expected move list does not match actual move list'
                    self.assertListEqual(expected_moves, possible_moves,
                                         message)
Beispiel #21
0
    def test_cannot_castle(self):
        """
        Test cases where a king cannot castle.
        Expected result is king cannot castle through check, from check, into check, after moving, if
        the rook has moved.
        :return:
        """
        # Check case where king would pass through check
        board = ChessBoard()
        board['a1'] = Rook(Color.WHITE)
        board['e1'] = King(Color.WHITE)
        board['d5'] = Rook(Color.BLACK)

        expected_moves = ['e2', 'f1', 'f2']
        legal_moves = board.get_legal_moves('e1')
        legal_moves.sort()
        self.assertListEqual(expected_moves, legal_moves,
                             'Expected moves does not match actual')

        # King in check
        board.move_piece('d5', 'e5')
        expected_moves = ['d1', 'd2', 'f1', 'f2']
        legal_moves = board.get_legal_moves('e1')
        legal_moves.sort()
        self.assertListEqual(expected_moves, legal_moves,
                             'Expected moves does not match actual')

        # King ends in check
        board.move_piece('e5', 'c5')
        expected_moves = ['d1', 'd2', 'e2', 'f1', 'f2']
        legal_moves = board.get_legal_moves('e1')
        legal_moves.sort()
        self.assertListEqual(expected_moves, legal_moves,
                             'Expected moves does not match actual')

        # Check after king moves
        board = ChessBoard()
        board['a1'] = Rook(Color.WHITE)
        board['e1'] = King(Color.WHITE)
        board.move_piece('e1', 'd1')

        expected_moves = ['c1', 'c2', 'd2', 'e1', 'e2']
        legal_moves = board.get_legal_moves('d1')
        legal_moves.sort()
        self.assertListEqual(expected_moves, legal_moves,
                             'Expected moves does not match actual')

        # Check after left rook moves
        board = ChessBoard()
        board['a1'] = Rook(Color.WHITE)
        board['e1'] = King(Color.WHITE)
        board.move_piece('a1', 'b1')

        expected_moves = ['d1', 'd2', 'e2', 'f1', 'f2']
        legal_moves = board.get_legal_moves('e1')
        legal_moves.sort()
        self.assertListEqual(expected_moves, legal_moves,
                             'Expected moves does not match actual')

        # Check after right rook moves
        board = ChessBoard()
        board['e1'] = King(Color.WHITE)
        board['h1'] = Rook(Color.WHITE)
        board.move_piece('h1', 'h2')

        expected_moves = ['d1', 'd2', 'e2', 'f1', 'f2']
        legal_moves = board.get_legal_moves('e1')
        legal_moves.sort()
        self.assertListEqual(expected_moves, legal_moves,
                             'Expected moves does not match actual')

        # Check with both rooks after right rook moves
        board = ChessBoard()
        board['a1'] = Rook(Color.WHITE)
        board['e1'] = King(Color.WHITE)
        board['h1'] = Rook(Color.WHITE)
        board.move_piece('h1', 'h2')

        expected_moves = ['c1', 'd1', 'd2', 'e2', 'f1', 'f2']
        legal_moves = board.get_legal_moves('e1')
        legal_moves.sort()
        self.assertListEqual(expected_moves, legal_moves,
                             'Expected moves does not match actual')

        # Check with both rooks after right rook moves
        board = ChessBoard()
        board['a1'] = Rook(Color.WHITE)
        board['e1'] = King(Color.WHITE)
        board['h1'] = Rook(Color.WHITE)
        board.move_piece('a1', 'b1')

        expected_moves = ['d1', 'd2', 'e2', 'f1', 'f2', 'g1']
        legal_moves = board.get_legal_moves('e1')
        legal_moves.sort()
        self.assertListEqual(expected_moves, legal_moves,
                             'Expected moves does not match actual')

        # Confirm cannot castle even if king and rooks back in starting positions
        fen = Fen('r3k2r/8/8/8/8/8/8/8 b - -')
        board = ChessBoard(fen)

        can_castle_left = board.can_castle(Color.BLACK, MoveDirection.LEFT)
        can_castle_right = board.can_castle(Color.BLACK, MoveDirection.RIGHT)
        self.assertFalse(can_castle_left,
                         'King should not be able to castle left')
        self.assertFalse(can_castle_right,
                         'King should not be able to castle right')