def test_fifty_moves_rest_by_pawn_move(self): board = prepare_board(config={ POS("a1"): (PlayerEnum.white, PieceEnum.king), POS("h2"): (PlayerEnum.white, PieceEnum.pawn), POS("a8"): (PlayerEnum.black, PieceEnum.king), POS("h7"): (PlayerEnum.black, PieceEnum.pawn), }, turn=PlayerEnum.white) white_pos1, white_pos2 = POS("a1"), POS("b1") black_pos1, black_pos2 = POS("a8"), POS("b8") for _ in range(48): # 48 moves don't take/move pawn board.apply(ActionMove(white_pos1, white_pos2)) board.apply(ActionMove(black_pos1, black_pos2)) white_pos1, white_pos2 = white_pos2, white_pos1 black_pos1, black_pos2 = black_pos2, black_pos1 # 49th move are just pawns board.apply(ActionMove(POS("h2"), POS("h3"))) self.assertNotIn(ActionMove(pos_from=None, pos_to=None, claim_draw=True), board.legal_moves) board.apply(ActionMove(POS("h7"), POS("h6"))) # pawns should break the counter, draw should not be possible self.assertNotIn(ActionMove(pos_from=None,pos_to=None,claim_draw=True), board.legal_moves) # not even after another 49 moves! for _ in range(49): board.apply(ActionMove(white_pos1, white_pos2)) board.apply(ActionMove(black_pos1, black_pos2)) white_pos1, white_pos2 = white_pos2, white_pos1 black_pos1, black_pos2 = black_pos2, black_pos1 self.assertNotIn(ActionMove(pos_from=None, pos_to=None, claim_draw=True), board.legal_moves)
def test_fifty_moves_rest_by_take_move(self): board = prepare_board(config={ POS("a1"): (PlayerEnum.white, PieceEnum.king), POS("h2"): (PlayerEnum.white, PieceEnum.rook), POS("a8"): (PlayerEnum.black, PieceEnum.king), POS("h3"): (PlayerEnum.black, PieceEnum.rook), POS("h4"): (PlayerEnum.black, PieceEnum.rook), }, turn=PlayerEnum.white) white_pos1, white_pos2 = POS("a1"), POS("b1") black_pos1, black_pos2 = POS("a8"), POS("b8") for _ in range(48): # 48 moves don't take/move pawn board.apply(ActionMove(white_pos1, white_pos2)) board.apply(ActionMove(black_pos1, black_pos2)) white_pos1, white_pos2 = white_pos2, white_pos1 black_pos1, black_pos2 = black_pos2, black_pos1 # 49th move are rooks taking board.apply(ActionMove(POS("h2"), POS("h3"), to_take=POS("h3"))) board.apply(ActionMove(POS("h4"), POS("h3"), to_take=POS("h3"))) self.assertNotIn(ActionMove(pos_from=None, pos_to=None, claim_draw=True), board.legal_moves) # not even after another 49 moves! for _ in range(49): board.apply(ActionMove(white_pos1, white_pos2)) board.apply(ActionMove(black_pos1, black_pos2)) white_pos1, white_pos2 = white_pos2, white_pos1 black_pos1, black_pos2 = black_pos2, black_pos1 self.assertNotIn(ActionMove(pos_from=None, pos_to=None, claim_draw=True), board.legal_moves)
def test_king_threaten_by_king(self): board = prepare_board(config={ POS("d8"): (PlayerEnum.white, PieceEnum.king), POS("d6"): (PlayerEnum.black, PieceEnum.king) }, turn=PlayerEnum.white) legal_moves = board.get_legal_moves(POS("d8")) expected_legal_moves = [ ActionMove(POS("d8"), POS("c8")), ActionMove(POS("d8"), POS("e8")), ] self.assertCountEqual(expected_legal_moves, legal_moves)
def test_king_threaten_by_pawn(self): board = prepare_board(config={ POS("g1"): (PlayerEnum.white, PieceEnum.king), POS("g2"): (PlayerEnum.black, PieceEnum.rook), POS("f3"): (PlayerEnum.black, PieceEnum.pawn), }, turn=PlayerEnum.white) legal_moves = board.get_legal_moves(POS("g1")) expected_legal_moves = [ ActionMove(POS("g1"), POS("f1")), ActionMove(POS("g1"), POS("h1")), ] self.assertCountEqual(expected_legal_moves, legal_moves)
def check_move_is_illegal(self, board, move_from, move_to): rules = board with self.assertRaises(IllegalMoveException): rules.apply(ActionMove(move_from, move_to))
def test_fifty_moves(self): board = prepare_board(config={ POS("a1"): (PlayerEnum.white, PieceEnum.king), POS("a8"): (PlayerEnum.black, PieceEnum.king) }, turn=PlayerEnum.white) white_pos1, white_pos2 = POS("a1"), POS("b1") black_pos1, black_pos2 = POS("a8"), POS("b8") for _ in range(49): # 49 moves don't take/move pawn board.apply(ActionMove(white_pos1, white_pos2)) board.apply(ActionMove(black_pos1, black_pos2)) white_pos1, white_pos2 = white_pos2, white_pos1 black_pos1, black_pos2 = black_pos2, black_pos1 self.assertNotIn(ActionMove(pos_from=None,pos_to=None, claim_draw=True), board.legal_moves) # white does his 50th move, then the draw should be possible for black board.apply(ActionMove(white_pos1, white_pos2)) self.assertIn(ActionMove(pos_from=None, pos_to=None, claim_draw=True), board.legal_moves) # after both made their 50th moves, it should be possible for white as well board.apply(ActionMove(black_pos1, black_pos2)) self.assertIn(ActionMove(pos_from=None,pos_to=None, claim_draw=True), board.legal_moves)
def test_king_castling_king_side_disabled_after_king_move(self): board = prepare_board(config={ POS("h1"): (PlayerEnum.white, PieceEnum.rook), POS("e1"): (PlayerEnum.white, PieceEnum.king) }, turn=PlayerEnum.white) board.specific[PlayerEnum.white].can_castle_king_side = True board.apply(ActionMove(POS("e1"), POS("e2"))) self.assertEqual(False, board.specific[PlayerEnum.white].can_castle_king_side)
def test_king_castling_king_side_unaffected(self): board = prepare_board(config={ POS("h1"): (PlayerEnum.white, PieceEnum.rook), POS("e1"): (PlayerEnum.white, PieceEnum.king), POS("a2"): (PlayerEnum.white, PieceEnum.pawn), }, turn=PlayerEnum.white) board.specific[PlayerEnum.white].can_castle_king_side = True board.apply(ActionMove(POS("a2"), POS("a3"))) self.assertEqual(True, board.specific[PlayerEnum.white].can_castle_king_side)
def test_fifty_moves_next_move_50_take(self): board = prepare_board(config={ POS("a1"): (PlayerEnum.white, PieceEnum.king), POS("h7"): (PlayerEnum.white, PieceEnum.queen), POS("a8"): (PlayerEnum.black, PieceEnum.king) }, turn=PlayerEnum.white) white_pos1, white_pos2 = POS("a1"), POS("b1") black_pos1, black_pos2 = POS("a8"), POS("b8") for _ in range(49): # 49 moves don't take/move pawn board.apply(ActionMove(white_pos1, white_pos2)) board.apply(ActionMove(black_pos1, black_pos2)) white_pos1, white_pos2 = white_pos2, white_pos1 black_pos1, black_pos2 = black_pos2, black_pos1 # first 50th move white moves queen next to black king, forcing only take moves board.apply(ActionMove(POS("h7"), POS("b7"))) # black's only option is to take, so he cannot claim a draw as his 50th move will be take self.assertNotIn(ActionMove(pos_from=None, pos_to=None, claim_draw=True), board.legal_moves) # black takes, and moves counter rest, so draw not possible for white board.apply(ActionMove(black_pos1, POS("b7"), to_take=POS("b7"))) self.assertNotIn(ActionMove(pos_from=None, pos_to=None, claim_draw=True), board.legal_moves)
def test_promote_by_taking(self): board = prepare_board(config={ POS("h7"): (PlayerEnum.white, PieceEnum.pawn), POS("g8"): (PlayerEnum.black, PieceEnum.knight), POS("h8"): (PlayerEnum.black, PieceEnum.rook) }, turn=PlayerEnum.white ) legal_moves = board.get_legal_moves(POS("h7")) expected_legal_moves = [ ActionMove(POS("h7"), POS("g8"), to_take=POS("g8"), promote_piece=PieceEnum.bishop), ActionMove(POS("h7"), POS("g8"), to_take=POS("g8"), promote_piece=PieceEnum.knight), ActionMove(POS("h7"), POS("g8"), to_take=POS("g8"), promote_piece=PieceEnum.rook), ActionMove(POS("h7"), POS("g8"), to_take=POS("g8"), promote_piece=PieceEnum.queen), ] self.assertCountEqual(expected_legal_moves, legal_moves)
def test_promote_blocked_illegal(self): for promoted_piece in (PieceEnum.queen, PieceEnum.knight, PieceEnum.bishop, PieceEnum.rook): board = prepare_board(config={ POS("a7"): (PlayerEnum.white, PieceEnum.pawn), POS("a8"): (PlayerEnum.black, PieceEnum.queen) }, turn=PlayerEnum.white ) with self.assertRaises(IllegalMoveException): board.apply(ActionMove(pos_from=POS("a7"), pos_to=POS("a8"), promote_piece=promoted_piece))
def test_promote_pawn(self): for promoted_piece in (PieceEnum.queen, PieceEnum.knight, PieceEnum.bishop, PieceEnum.rook): board = prepare_board(config={ POS("a7"): (PlayerEnum.white, PieceEnum.pawn) }, turn=PlayerEnum.white ) board.apply(ActionMove(pos_from=POS("a7"), pos_to=POS("a8"), promote_piece=promoted_piece)) self.assertEqual(None, board.board.board[0][6].piece) self.assertEqual(None, board.board.board[0][6].player) self.assertEqual(promoted_piece, board.board.board[0][7].piece) self.assertEqual(PlayerEnum.white, board.board.board[0][7].player)
def check_move_is_allowed(self, board, after_config_expected, move_from, move_to, **kwargs): rules = board rules.apply(ActionMove(move_from, move_to, **kwargs)) for file in range(8): for rank in range(8): player, piece = None, None pos = Position(file, rank) if pos in after_config_expected: player, piece = after_config_expected[pos] self.assertEqual(player, rules.board.board[file][rank].player) self.assertEqual(piece, rules.board.board[file][rank].piece)