Beispiel #1
0
    def test_knight_capture(self):
        """
        Move knight to a middle square with a piece on a capture square.
        Expected result is position with opponent piece is in legal move list and piece is captured
        when knight moves to that position.
        :return:
        """
        board = ChessBoard()
        start_position = 'd4'
        capture_position = 'f5'
        board[start_position] = Knight(Color.WHITE)
        board[capture_position] = Bishop(Color.BLACK)
        expected_possible_moves = [
            'b3', 'b5', 'c2', 'c6', 'e2', 'e6', 'f3', 'f5'
        ]
        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)

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

        # Test move result
        expected_move_result = {
            start_position: None,
            capture_position: Knight(Color.WHITE)
        }
        self.assertDictEqual(expected_move_result, move_result,
                             'Expected move result does not match actual')
Beispiel #2
0
    def test_king_movement_adjusted_after_moving(self):
        """
        Move a king of each color
        Expected result is king cannot move left or right two squares once it has moved.
        :return:
        """
        board = ChessBoard()
        positions = {Color.WHITE: ('e1', 'e2'), Color.BLACK: ('e8', 'e7')}
        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: 1,
            MoveDirection.F_LEFT_DIAG: 1
        }

        for color in [Color.BLACK, Color.WHITE]:
            with self.subTest(color=color, movement=positions[color]):
                start_pos, end_pos = positions[color]
                board[start_pos] = King(color)
                board.move_piece(start_pos, end_pos)

                self.assertDictEqual(expected_directions,
                                     board[end_pos].move_directions,
                                     'Incorrect move_directions')
Beispiel #3
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 #4
0
    def test_queen_capture(self):
        """
        Move queen to position where an opponents piece is in the capture path.
        Expected result is opponents piece is in legal move list and piece is captured when queen moves to that
        position.
        :return:
        """
        board = ChessBoard()
        start_position = 'd4'
        capture_position = 'e4'
        board[start_position] = Queen(Color.WHITE)
        board['d5'] = Pawn(Color.BLACK)
        board[capture_position] = Pawn(Color.BLACK)
        expected_possible_moves = [
            'a1', 'a4', 'a7', 'b2', 'b4', 'b6', 'c3', 'c4', 'c5', 'd1', 'd2',
            'd3', 'd5', 'e3', 'e4', 'e5', 'f2', 'f6', 'g1', 'g7', 'h8'
        ]
        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)

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

        # Test move result
        expected_move_result = {
            start_position: None,
            capture_position: Queen(Color.WHITE)
        }
        self.assertDictEqual(expected_move_result, move_result,
                             'Expected move result does not match actual')
Beispiel #5
0
    def test_move_l_shape(self):
        """
        Move knight in every possible direction.
        Expected result is that the knight no longer exist on the starting square, but on the ending square.
        :return:
        """
        start_position = 'd4'
        end_positions = ['b3', 'b5', 'c2', 'c6', 'e2', 'e6', 'f3', 'f5']
        piece_colors = [Color.WHITE, Color.BLACK]

        for color in piece_colors:
            for end_position in end_positions:
                with self.subTest(color=color, end_position=end_position):
                    board = ChessBoard()
                    board[start_position] = Knight(color)

                    move_result = board.move_piece(start_position,
                                                   end_position)
                    self.assertIsNone(
                        board[start_position],
                        'There should no longer be a piece on start position')
                    self.assertIsInstance(
                        board[end_position], Knight,
                        'There should be a piece on end position')

                    expected_result = {
                        start_position: None,
                        end_position: Knight(color)
                    }
                    self.assertDictEqual(
                        expected_result, move_result,
                        'Expected move result does not match actual')
    def test_pawn_legal_moves_piece_blocking(self):
        """
        Place a pawn on a square and another piece 2 positions in front of it.
        Expected result is there are is one legal move for the pawn that is blocked.
        :return:
        """
        opposing_colors = [[Color.BLACK, Color.WHITE],
                           [Color.WHITE, Color.BLACK]]
        for opposing_color in opposing_colors:
            start_positions = ['b2', 'g7']
            blocking_positions = ['b4', 'g5']
            expected_moves = [['b3'], ['g6']]
            pawn_colors = [Color.WHITE, Color.BLACK]
            for start, blocking, expected, pawn_color, opposing in zip(
                    start_positions, blocking_positions, expected_moves,
                    pawn_colors, opposing_color):
                with self.subTest(start=start,
                                  blocking=blocking,
                                  expected=expected,
                                  pawn_color=pawn_color,
                                  opposing=opposing):
                    board = ChessBoard()
                    board[start] = Pawn(pawn_color)
                    board[blocking] = Pawn(opposing)

                    legal_moves = board.get_legal_moves(start)
                    legal_moves.sort()

                    message = 'Pawn should only have one legal move'
                    self.assertListEqual(expected, legal_moves, message)
Beispiel #7
0
    def test_king_capture(self):
        """
        Move king to square right next to piece of opposing color with nothing backing it up.
        Expected result is position with opponent piece is in legal move list and piece is captured
        when king moves to that position.
        :return:
        """
        board = ChessBoard()
        start_position = 'd4'
        capture_position = 'e4'
        board[start_position] = King(Color.WHITE)
        board[capture_position] = Pawn(Color.BLACK)

        expected_legal_moves = ['c3', 'c4', 'c5', 'd5', 'e3', 'e4', 'e5']
        possible_moves = board.get_legal_moves(start_position)
        possible_moves.sort()

        self.assertListEqual(
            expected_legal_moves, possible_moves,
            'Expected move list does not match actual move list')

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

        # Test move result
        expected_move_result = {
            start_position: None,
            capture_position: King(Color.WHITE)
        }
        self.assertDictEqual(expected_move_result, move_result,
                             'Expected move result does not match actual')
    def test_king_legal_moves(self):
        """
        Move a king 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', 'b1', 'b2'],
                'a8': ['a7', 'b7', 'b8'],
                'h1': ['g1', 'g2', 'h2'],
                'h8': ['g7', 'g8', 'h7'],
                'd4': ['c3', 'c4', 'c5', 'd3', 'd5', 'e3', 'e4', 'e5']
            },
            Color.BLACK: {
                'a1': ['a2', 'b1', 'b2'],
                'a8': ['a7', 'b7', 'b8'],
                'h1': ['g1', 'g2', 'h2'],
                'h8': ['g7', 'g8', 'h7'],
                'd4': ['c3', 'c4', 'c5', 'd3', 'd5', 'e3', 'e4', 'e5']
            }
        }
        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] = King(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 #9
0
    def test_bishop_capture(self):
        """
        Move a bishop to square where there is a piece of the opposite color on capture diagonal.
        Expected result is position with opponent piece is in legal move list and piece is captured
        when bishop moves to that position.
        :return:
        """
        board = ChessBoard()
        start_position = 'd4'
        capture_position = 'h8'
        board[start_position] = Bishop(Color.WHITE)
        board['c5'] = Queen(Color.BLACK)
        board[capture_position] = Pawn(Color.BLACK)
        expected_possible_moves = [
            'a1', 'b2', 'c3', 'c5', 'e3', 'e5', 'f2', 'f6', 'g1', 'g7', 'h8'
        ]
        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)

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

        # Test move result
        expected_move_result = {
            start_position: None,
            capture_position: Bishop(Color.WHITE)
        }
        self.assertDictEqual(expected_move_result, move_result,
                             'Expected move result does not match actual')
Beispiel #10
0
    def test_move_right(self):
        """
        Move a piece of every type one square to the right.
        Expected result is that the piece no longer exist on the starting square, but on the ending square.
        :return:
        """
        start_positions = ['a1', 'h8']
        end_positions = ['b1', 'g8']
        piece_colors = [Color.WHITE, Color.BLACK]
        piece_types = {Type.KING: King, Type.QUEEN: Queen, Type.ROOK: Rook}
        for start, end, color in zip(start_positions, end_positions,
                                     piece_colors):
            for t, piece_class in piece_types.items():
                with self.subTest(t=t,
                                  piece_class=piece_class,
                                  start=start,
                                  end=end,
                                  color=color):
                    board = ChessBoard()
                    board[start] = piece_class(color)

                    move_result = board.move_piece(start, end)
                    self.assertIsNone(
                        board[start],
                        'There should no longer be a piece on square ' + start)
                    self.assertIsInstance(
                        board[end], piece_class,
                        'There should be a piece on square ' + end)

                    expected_result = {start: None, end: piece_class(color)}
                    self.assertDictEqual(
                        expected_result, move_result,
                        'Expected move result does not match actual')
Beispiel #11
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 #12
0
 def test_bishop_checkmate(self):
     """
     Test that a queen will put a king of the opposite color in checkmate
     :return:
     """
     board = ChessBoard()
     board['a8'] = King(Color.WHITE)
     board['a6'] = Knight(Color.BLACK)
     board['b6'] = King(Color.BLACK)
     board['c6'] = Bishop(Color.BLACK)
     self.assertTrue(board.is_checkmate(Color.WHITE),
                     'King should be in checkmate')
Beispiel #13
0
 def test_pawn_checkmate(self):
     """
     Test that a pawn will put a king of the opposite color in checkmate
     :return:
     """
     board = ChessBoard()
     board['a1'] = King(Color.WHITE)
     board['a2'] = Pawn(Color.WHITE)
     board['b1'] = Bishop(Color.WHITE)
     board['b2'] = Pawn(Color.BLACK)
     board['c3'] = Pawn(Color.BLACK)
     self.assertTrue(board.is_checkmate(Color.WHITE),
                     'King should be in checkmate')
Beispiel #14
0
    def __init__(self, fen=None, **kwargs):
        """
        Generate a ChessGame object.

        :param fen: string
            Fen notation string to initialize game.
        :param kwargs:
        """
        super().__init__(**kwargs)

        self.fen = fen if fen else 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -'
        fen = Fen(self.fen, validate=False)
        self._board = ChessBoard(fen)
Beispiel #15
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 #16
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 #17
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 #18
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 #19
0
 def test_pawn_check(self):
     """
     Test that a pawn will put a king of the opposite color in check
     :return:
     """
     piece_positions = [('c2', 'b1'), ('a2', 'b1')]
     for positions in piece_positions:
         pawn_position, king_position = positions
         with self.subTest(pawn_position=pawn_position,
                           king_position=king_position):
             board = ChessBoard()
             board[pawn_position] = Pawn(Color.BLACK)
             board[king_position] = King(Color.WHITE)
             self.assertTrue(board.is_check(Color.WHITE),
                             'Pawn should put king in check')
Beispiel #20
0
 def test_bishop_check(self):
     """
     Test that a bishop will put a king of the opposite color in check
     :return:
     """
     piece_positions = [('a1', 'h8'), ('a8', 'h1'), ('h8', 'a1'),
                        ('h1', 'a8')]
     for positions in piece_positions:
         bishop_position, king_position = positions
         with self.subTest(bishop_position=bishop_position,
                           king_position=king_position):
             board = ChessBoard()
             board[bishop_position] = Bishop(Color.BLACK)
             board[king_position] = King(Color.WHITE)
             self.assertTrue(board.is_check(Color.WHITE),
                             'Bishop should put king in check')
Beispiel #21
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 #22
0
 def test_queen_check(self):
     """
     Test that a queen will put a king of the opposite color in check
     :return:
     """
     piece_positions = [('a1', 'a8'), ('a1', 'h1'), ('a1', 'h8'),
                        ('a8', 'a1'), ('a8', 'h8'), ('a8', 'h8'),
                        ('h8', 'a1'), ('h8', 'a8'), ('h8', 'h1'),
                        ('h1', 'a1'), ('h1', 'a8'), ('h1', 'h8')]
     for positions in piece_positions:
         queen_position, king_position = positions
         with self.subTest(queen_position=queen_position,
                           king_position=king_position):
             board = ChessBoard()
             board[queen_position] = Queen(Color.BLACK)
             board[king_position] = King(Color.WHITE)
             self.assertTrue(board.is_check(Color.WHITE),
                             'Queen should put king in check')
Beispiel #23
0
 def test_knight_check(self):
     """
     Test that a knight will put a king of the opposite color in check
     :return:
     """
     piece_positions = [('a1', 'b3'), ('a1', 'c2'), ('d4', 'e6'),
                        ('d4', 'f5'), ('d4', 'f3'), ('d4', 'e2'),
                        ('d4', 'c2'), ('d4', 'b3'), ('d4', 'b5'),
                        ('d4', 'c6')]
     for positions in piece_positions:
         knight_position, king_position = positions
         with self.subTest(knight_position=knight_position,
                           king_position=king_position):
             board = ChessBoard()
             board[knight_position] = Knight(Color.BLACK)
             board[king_position] = King(Color.WHITE)
             self.assertTrue(board.is_check(Color.WHITE),
                             'Knight should put king in check')
Beispiel #24
0
    def test_pawn_cant_capture(self):
        """
        Move a pawn to a square where there is a piece of the same color on one of the most immediate diagonal
        squares.
        Expected result is that the square that contains the piece of the same color is not in the list of possible
        moves for the pawn.
        :return:
        """
        board = ChessBoard()
        start_position = 'b1'
        board[start_position] = Pawn(Color.WHITE)
        board['c2'] = Bishop(Color.WHITE)
        expected_possible_moves = ['b2', 'b3']
        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)
Beispiel #25
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 #27
0
    def test_bishop_cant_capture(self):
        """
        Move bishop to square and place piece of same color in movement path.
        Expected result is that the square containing the piece of the same color is not in the list of legal
        moves.
        :return:
        """
        color_group = [Color.WHITE, Color.BLACK]
        for color in color_group:
            with self.subTest(color=color):
                board = ChessBoard()
                board['b2'] = Bishop(color)
                board['c3'] = Pawn(color)

                expected_moves = ['a1', 'a3', 'c1']
                legal_moves = board.get_legal_moves('b2')
                legal_moves.sort()
                self.assertListEqual(
                    expected_moves, legal_moves,
                    'Expected list does not match actual legal move list')
Beispiel #28
0
    def test_queen_cant_capture(self):
        """
        Move queen to a square and place piece of same color in movement path.
        Expected result is that the square containing the piece of the same color is not in the list of legal
        moves.
        :return:
        """
        board = ChessBoard()
        board['b2'] = Queen(Color.WHITE)
        board['b3'] = Pawn(Color.WHITE)

        expected_legal_moves = [
            'a1', 'a2', 'a3', 'b1', 'c1', 'c2', 'c3', 'd2', 'd4', 'e2', 'e5',
            'f2', 'f6', 'g2', 'g7', 'h2', 'h8'
        ]
        legal_moves = board.get_legal_moves('b2')
        legal_moves.sort()

        self.assertListEqual(expected_legal_moves, legal_moves,
                             'Expected move list does not match actual')
    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')
    def test_pawn_en_passant_legal_move(self):
        """
        Place pawn on 4th or 5th rank and move pawn of opposite color immediately to left or right of first pawn.
        Expected result is en passant move is present in legal move list for first pawn.
        :return:
        """
        piece_movements = {
            Color.WHITE: [[('h2', 'h5'), ('g7', 'g5')],
                          [('a2', 'a5'), ('b7', 'b5')]],
            Color.BLACK: [[('a7', 'a4'), ('b2', 'b4')],
                          [('h7', 'h4'), ('g2', 'g4')]]
        }
        expected_moves = {
            Color.WHITE: {
                'h5': ['g6', 'h6'],
                'a5': ['a6', 'b6']
            },
            Color.BLACK: {
                'a4': ['a3', 'b3'],
                'h4': ['g3', 'h3']
            }
        }
        fen = Fen('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -')
        for (c1, moves_for_color), (c2, expected_for_color) in zip(
                piece_movements.items(), expected_moves.items()):
            for piece_moves, (check_position, expected_list) in zip(
                    moves_for_color, expected_for_color.items()):
                with self.subTest(piece_moves=piece_moves,
                                  check_position=check_position,
                                  expected_list=expected_list):
                    board = ChessBoard(fen)
                    for movements in piece_moves:
                        start, end = movements
                        board.move_piece(start, end)

                    legal_moves = board.get_legal_moves(check_position)
                    legal_moves.sort()
                    self.assertListEqual(
                        expected_list, legal_moves,
                        'En passant move should be in legal moves list')