예제 #1
0
class TestIsBeingChecked(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_is_being_checked_start(self):
        self.assertFalse(self.game.is_being_checked())

    def test_is_being_checked_during_game_true(self):
        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[0][0] = King(self.game, Color.WHITE, 0, 0)
        self.game.board[7][3] = King(self.game, Color.BLACK, 7, 3)
        self.game.kings_coordinate = [(0, 0), (7, 3)]
        self.game.board[1][0] = Pawn(self.game, Color.BLACK, 1, 0)
        self.game.board[4][5] = Pawn(self.game, Color.WHITE, 4, 5)
        self.game.board[4][1] = Rook(self.game, Color.WHITE, 4, 1)
        self.game.board[3][3] = Bishop(self.game, Color.BLACK, 3, 3)
        self.assertTrue(self.game.is_being_checked())

    def test_is_being_checked_during_game_false(self):
        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[0][4] = King(self.game, Color.WHITE, 0, 4)
        self.game.board[7][3] = King(self.game, Color.BLACK, 7, 3)
        self.game.kings_coordinate = [(0, 4), (7, 3)]
        self.game.board[1][0] = Pawn(self.game, Color.BLACK, 1, 0)
        self.game.board[4][5] = Pawn(self.game, Color.WHITE, 4, 5)
        self.game.board[4][1] = Rook(self.game, Color.WHITE, 4, 1)
        self.game.board[3][3] = Bishop(self.game, Color.BLACK, 3, 3)
        self.assertFalse(self.game.is_being_checked())
예제 #2
0
class TestUpdateCastle(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_update_castle(self):
        self.game.half_move_clock = 0
        self.game.full_move_clock = 10
        self.game.count = 20
        self.game.empty_cell = Empty(None, Color.EMPTY, -1, -1)
        self.game.history = [{"fen": "r3k3/8/8/8/Pp6/8/8/4K2R b Kq a3 0 10",
                              "movement": {"src": "a2", "tar": "a4"}}]
        self.game.turn = Color.BLACK
        for row in range(8):
            for col in range(8):
                self.game.board[row][col] = self.game.empty_cell
        self.game.board[7][4] = King(self.game, Color.BLACK, 7, 4)
        self.game.board[7][4].firstMove = True
        self.game.board[7][0] = Rook(self.game, Color.BLACK, 7, 0)
        self.game.board[7][0].firstMove = True
        self.game.board[0][4] = King(self.game, Color.WHITE, 0, 4)
        self.game.board[0][4].firstMove = True
        self.game.board[0][7] = Rook(self.game, Color.WHITE, 0, 7)
        self.game.board[0][7].firstMove = True
        self.game.board[3][0] = Pawn(self.game, Color.WHITE, 3, 0)
        self.game.board[3][1] = Pawn(self.game, Color.BLACK, 3, 1)
        expected_1 = self.game.board[7][0]
        expected_2 = self.game.board[0][7]

        self.game.update_castle((7, 4), (7, 2))
        self.assertEqual(self.game.board[7][3], expected_1)

        self.game.update_castle((0, 4), (0, 6))
        self.assertEqual(self.game.board[0][5], expected_2)
예제 #3
0
 def create_game(self, username: str, mode: str) -> dict:
     """
     Create a new chess game in put it in the dictionary, store the data in the database.
     :param username: username of the user playing the game
     :param mode: the mode of the game. "easy": easy AI game; "advanced": advanced AI game; "pvp": player vs player
     :return: A dict where only has one key "session_id"
     """
     session_id = self.generate_unique_session_id()
     game = ChessGame()
     self.sessions[session_id] = (game, username)
     self.modes[session_id] = mode
     time = datetime.datetime.now()
     fen = game.get_fen()
     status = game.check_game_status()
     conn = self.engine.connect()
     conn.execute(
         self.current_game.insert(), {
             "username": username,
             "session_id": session_id,
             "status": status,
             "fen": fen,
             "mode": mode,
             "start_time": time,
             "last_update": time
         })
     conn.close()
     return {"session_id": session_id, "valid": True}
예제 #4
0
class TestGetFen(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_get_fen_start(self):
        self.assertEqual(self.game.get_fen(),
                         "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")

    def test_get_fen_during_game(self):
        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[0][0] = King(self.game, Color.WHITE, 0, 0)
        self.game.board[7][3] = King(self.game, Color.BLACK, 7, 3)
        self.game.board[1][0] = Pawn(self.game, Color.BLACK, 1, 0)
        self.game.board[4][5] = Pawn(self.game, Color.WHITE, 4, 5)
        self.game.board[4][1] = Rook(self.game, Color.WHITE, 4, 1)
        self.game.board[3][3] = Bishop(self.game, Color.BLACK, 3, 3)
        self.game.history = [{"src": (0, 4)}, {"src": (7, 4)}]
        self.game.en_passant_target_notation = "-"
        self.game.half_move_clock = 0
        self.game.full_move_clock = 20
        self.assertEqual(self.game.get_fen(),
                         "3k4/8/8/1R3P2/3b4/8/p7/K7 w - - 0 20")
예제 #5
0
class TestGetGameHistory(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_get_game_history_empty(self):
        self.game.history = []
        expected = []
        ret = self.game.get_game_history()
        self.assertEqual(ret, expected)

    def test_get_game_history_restores_expected_history(self):
        self.game.history = [{"fen": "rnbqkbnr/pppppppp/8/8/P7/8/1PPPPPPP/RNBQKBNR b KQkq a3 0 1",
                              "movement": {"src": "a2", "tar": "a4"}},
                             {"fen": "rnbqkbnr/1ppppppp/8/p7/P7/8/1PPPPPPP/RNBQKBNR w KQkq a6 0 2",
                              "movement": {"src": "a7", "tar": "a5"}},
                             {"fen": "rnbqkbnr/1ppppppp/8/p7/P7/R7/1PPPPPPP/1NBQKBNR b Kkq - 1 2",
                              "movement": {"src": "a1", "tar": "a3"}},
                             {"fen": "1nbqkbnr/1ppppppp/r7/p7/P7/R7/1PPPPPPP/1NBQKBNR w Kk - 2 3",
                              "movement": {"src": "a8", "tar": "a6"}},
                             {"fen": "1nbqkbnr/1ppppppp/r7/p7/P6P/R7/1PPPPPP1/1NBQKBNR b Kk h3 0 3",
                              "movement": {"src": "h2", "tar": "h4"}},
                             {"fen": "1nbqkbnr/1pppppp1/r7/p6p/P6P/R7/1PPPPPP1/1NBQKBNR w Kk h6 0 4",
                              "movement": {"src": "h7", "tar": "h5"}},
                             {"fen": "1nbqkbnr/1pppppp1/r7/p6p/P6P/R6R/1PPPPPP1/1NBQKBN1 b k - 1 4",
                              "movement": {"src": "h1", "tar": "h3"}}]
        expected = [{"src": "a2", "tar": "a4"}, {"src": "a7", "tar": "a5"}, {"src": "a1", "tar": "a3"},
                    {"src": "a8", "tar": "a6"}, {"src": "h2", "tar": "h4"}, {"src": "h7", "tar": "h5"},
                    {"src": "h1", "tar": "h3"}]
        ret = self.game.get_game_history()
        self.assertEqual(ret, expected)
예제 #6
0
 def test_get_next_move_returns_correct_value(self):
     ai = AdvancedAI(ChessGame())
     move = ai.get_next_move()
     self.assertEqual(move, (0, 1, 2, 2))
     ai = AdvancedAI(ChessGame())
     ai.game.update((0, 1), (2, 2), "Queen", is_ai=True)
     move = ai.get_next_move()
     self.assertEqual(move, (6, 0, 5, 0))
예제 #7
0
 def setUp(self) -> None:
     self.game = ChessGame(fen="start")
     self.game.half_move_clock = 20
     self.game.full_move_clock = 100
     self.game.count = 200
     for row in range(8):
         for col in range(8):
             self.game.board[row][col] = Empty(None, Color.EMPTY, row, col)
예제 #8
0
    def test_get_next_move_returns_correct_value(self):
        simple_ai = SimpleAI(ChessGame())
        move = simple_ai.get_next_move()
        self.assertEqual(move, (0, 1, 2, 2))

        simple_ai = SimpleAI(ChessGame())
        simple_ai.game.update((0, 1), (2, 2), "Queen")
        move = simple_ai.get_next_move()
        self.assertEqual(move, (6, 2, 5, 2))
예제 #9
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
예제 #10
0
class TestGetTurnNotation(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_get_turn_notation_start(self):
        self.assertEqual(self.game.get_turn_notation(), "w")

    def test_get_turn_notation_during_game(self):
        self.game.turn = Color.BLACK
        self.assertEqual(self.game.get_turn_notation(), "b")
        self.game.turn = Color.WHITE
        self.assertEqual(self.game.get_turn_notation(), "w")
예제 #11
0
class TestKingCoordinate(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_king_coordinate_start(self):
        self.assertEqual(self.game.king_coordinate(Color.WHITE), (0, 4))
        self.assertEqual(self.game.king_coordinate(Color.BLACK), (7, 4))

    def test_king_coordinate(self):
        self.game.kings_coordinate = [(0, 0), (7, 3)]
        self.assertEqual(self.game.king_coordinate(Color.WHITE), (0, 0))
        self.assertEqual(self.game.king_coordinate(Color.BLACK), (7, 3))
예제 #12
0
    def __init__(self, db_url="init"):
        """
        Set up database using db_url. Connect to the database, fetch data and create dict sessions where key is
        session_id and value is chess (game instance, username).
        :param db_url: if db_url is "init", the db_url is
            'postgresql+psycopg2://postgres:[email protected]:5432'
        Otherwise, db_url can be the value of the parameter passed in
        """
        if db_url == "init":
            db_url = 'postgresql+psycopg2://postgres:[email protected]:5432'
        self.engine = create_engine(db_url)
        meta = MetaData()

        self.current_game = Table(
            'game', meta, Column('username', String),
            Column('session_id', Integer, primary_key=True),
            Column('fen', String), Column('status', String),
            Column('mode', String), Column('start_time', DateTime),
            Column('last_update', DateTime))

        self.history = Table('history', meta,
                             Column('session_id', Integer, primary_key=True),
                             Column('step', Integer, primary_key=True),
                             Column('src', String), Column('tar', String),
                             Column('fen', String))

        self.users = Table('users', meta,
                           Column('username', String, primary_key=True),
                           Column('password', String),
                           Column('total_hours', Float),
                           Column('score', Integer))

        meta.create_all(self.engine)

        self.sessions = {}
        self.modes = {}
        conn = self.engine.connect()
        sessions_info = conn.execute(self.current_game.select())
        for session in sessions_info:
            session_id = session["session_id"]
            fen = session["fen"]
            game = ChessGame(fen)
            self.sessions[session_id] = (game, session["username"])
            self.modes[session_id] = session["mode"]

        for session_id in self.sessions:
            session_history = conn.execute(self.history.select().where(
                self.history.c.session_id == session_id).order_by(
                    self.history.c.step)).all()
            game = self.sessions[session_id][0]
            game.init_history(session_history)
        conn.close()
예제 #13
0
class TestGetTurn(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_get_turn_start(self):
        self.assertEqual(self.game.get_turn(), "White")

    def test_switch_turn_during_game(self):
        self.game.turn = Color.BLACK
        self.assertEqual(self.game.get_turn(), "Black")

        self.game.turn = Color.WHITE
        self.assertEqual(self.game.get_turn(), "White")
예제 #14
0
class TestGetCheckedMoves(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")
        self.game.half_move_clock = 20
        self.game.full_move_clock = 100
        self.game.count = 200
        for row in range(8):
            for col in range(8):
                self.game.board[row][col] = Empty(None, Color.EMPTY, row, col)

    def test_get_checked_moves_checkmate(self):
        self.game.board[0][0] = King(self.game, Color.WHITE, 0, 0)
        self.game.board[7][4] = King(self.game, Color.BLACK, 7, 4)
        self.game.board[1][0] = Pawn(self.game, Color.BLACK, 1, 0)
        self.game.board[4][5] = Pawn(self.game, Color.WHITE, 4, 5)
        self.game.board[4][1] = Rook(self.game, Color.WHITE, 4, 1)
        self.game.board[3][3] = Bishop(self.game, Color.BLACK, 3, 3)
        self.game.turn = Color.WHITE

        checked_moves = self.game.get_checked_moves((4, 1))
        moves = checked_moves["moves"]
        for move in moves:
            self.assertTrue(move in ["b2"])

        checked_moves = self.game.get_checked_moves((0, 0))
        moves = checked_moves["moves"]
        for move in moves:
            self.assertTrue(move in ["a2"])

        checked_moves = self.game.get_checked_moves((4, 5))
        moves = checked_moves["moves"]
        for move in moves:
            self.assertTrue(move in [])

    def test_get_checked_moves_checkmate2(self):
        self.game.board[0][3] = King(self.game, Color.WHITE, 0, 3)
        self.game.board[7][4] = King(self.game, Color.BLACK, 7, 4)
        self.game.board[1][2] = Pawn(self.game, Color.BLACK, 1, 2)
        self.game.board[4][1] = Rook(self.game, Color.WHITE, 4, 1)
        self.game.board[3][4] = Bishop(self.game, Color.BLACK, 3, 4)
        self.game.turn = Color.WHITE

        checked_moves = self.game.get_checked_moves((0, 3))
        moves = checked_moves["moves"]
        for move in moves:
            self.assertTrue(move in ["c1", "d2", "e1", "e2"])

        checked_moves = self.game.get_checked_moves((4, 1))
        moves = checked_moves["moves"]
        for move in moves:
            self.assertTrue(move in [])
예제 #15
0
 def setUp(self) -> None:
     fen = "8/8/8/8/8/8/8/8 w KQkq - 0 1"
     self.chess_game = ChessGame(fen=fen)  # empty board
     self.chess_game.board[0][4] = King(self.chess_game, Color.WHITE, 0, 4)
     self.chess_game.board[0][7] = Rook(self.chess_game, Color.WHITE, 0, 7)
     self.chess_game.board[0][0] = Rook(self.chess_game, Color.WHITE, 0, 0)
     self.chess_game.board[7][4] = King(self.chess_game, Color.BLACK, 7, 4)
     self.chess_game.board[7][0] = Rook(self.chess_game, Color.BLACK, 7, 0)
예제 #16
0
 def setUp(self) -> None:
     fen = "8/8/8/8/8/8/8/8 w KQkq - 0 1"
     self.chess_game = ChessGame(fen=fen)  # empty board
     self.chess_game.board[0][0] = Rook(self.chess_game, Color.WHITE, 0, 0)
     self.chess_game.board[2][3] = Rook(self.chess_game, Color.WHITE, 2, 3)
     self.chess_game.board[0][3] = King(self.chess_game, Color.WHITE, 0, 3)
     self.chess_game.board[3][3] = Rook(self.chess_game, Color.BLACK, 3, 3)
     self.chess_game.kings_coordinate = [(0, 3), (None, None)]
예제 #17
0
 def setUp(self) -> None:
     fen = "8/8/8/8/8/8/8/8 w KQkq - 0 1"
     self.chess_game = ChessGame(fen=fen)  # empty board
     self.chess_game.board[4][4] = King(self.chess_game, Color.WHITE, 4, 4)
     self.chess_game.board[4][1] = King(self.chess_game, Color.BLACK, 4, 1)
     self.chess_game.kings_coordinate = [(4, 4), (4, 1)]
     self.chess_game.board[3][3] = Rook(self.chess_game, Color.BLACK, 3, 3)
     self.chess_game.board[3][2] = Rook(self.chess_game, Color.WHITE, 3, 2)
예제 #18
0
    def test_get_value_returns_correct_value(self):
        simple_ai = SimpleAI(ChessGame())
        self.assertEqual(simple_ai.get_value(simple_ai.game.board), -39)

        simple_ai.game.board[6][0] = simple_ai.game.empty_cell
        self.assertEqual(simple_ai.get_value(simple_ai.game.board), -38)

        simple_ai.game.board[6][0] = Rook(simple_ai.game, Color.BLACK, 6, 0)
        self.assertEqual(simple_ai.get_value(simple_ai.game.board), -43)
예제 #19
0
 def setUp(self) -> None:
     fen = "8/8/8/8/8/8/8/8 w KQkq - 0 1"
     self.chess_game = ChessGame(fen=fen)  # empty board
     self.chess_game.board[0][0] = Bishop(self.chess_game, Color.WHITE, 0,
                                          0)
     self.chess_game.board[4][4] = Bishop(self.chess_game, Color.BLACK, 4,
                                          4)
     self.chess_game.board[3][3] = Bishop(self.chess_game, Color.BLACK, 3,
                                          3)
예제 #20
0
class TestGetHistory(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_get_history_start(self):
        self.assertEqual(self.game.get_history(), {})

    def test_get_history_during_game(self):
        self.game.history = [{"fen": "rnbqkbnr/pppppppp/8/8/P7/8/1PPPPPPP/RNBQKBNR b KQkq a3 0 1",
                             "movement": {"src": "a2", "tar": "a4"}},
                             {"fen": "rnbqkbnr/1ppppppp/8/p7/P7/8/1PPPPPPP/RNBQKBNR w KQkq a6 0 2",
                              "movement": {"src": "a7", "tar": "a5"}},
                             {"fen": "rnbqkbnr/1ppppppp/8/p7/P7/R7/1PPPPPPP/1NBQKBNR b Kkq - 1 2",
                              "movement": {"src": "a1", "tar": "a3"}},
                             {"fen": "1nbqkbnr/1ppppppp/r7/p7/P7/R7/1PPPPPP1/1NBQKBNR w Kk - 2 3",
                              "movement": {"src": "a8", "tar": "a6"}}]
        expect = {"src": "a8", "tar": "a6", "fen": "1nbqkbnr/1ppppppp/r7/p7/P7/R7/1PPPPPP1/1NBQKBNR w Kk - 2 3",
                  "step": 4}
        self.assertEqual(self.game.get_history(), expect)
예제 #21
0
 def setUp(self) -> None:
     fen = "8/8/8/8/8/8/8/8 w KQkq - 0 1"
     self.chess_game = ChessGame(fen=fen)  # empty board
     self.chess_game.board[0][0] = Knight(self.chess_game, Color.WHITE, 0,
                                          0)
     self.chess_game.board[0][2] = Knight(self.chess_game, Color.WHITE, 0,
                                          2)
     self.chess_game.board[1][0] = Knight(self.chess_game, Color.BLACK, 1,
                                          0)
     self.chess_game.board[1][2] = Knight(self.chess_game, Color.BLACK, 1,
                                          2)
예제 #22
0
class TestGetCastlingNotation(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_get_castling_notation_start(self):
        self.assertEqual(self.game.get_castling_notation(), "KQkq")

    def test_get_castling_notation_during_game(self):
        self.game.board[0][4].firstMove = True
        self.game.board[7][4].firstMove = True
        self.game.board[0][0].firstMove = True
        self.game.board[0][7].firstMove = True
        self.game.board[7][0].firstMove = True
        self.game.board[7][7].firstMove = True
        self.assertEqual(self.game.get_castling_notation(), "KQkq")

        self.game.board[0][0].firstMove = False
        self.assertEqual(self.game.get_castling_notation(), "Kkq")

        self.game.board[0][7].firstMove = False
        self.assertEqual(self.game.get_castling_notation(), "kq")

        self.game.board[7][0].firstMove = False
        self.assertEqual(self.game.get_castling_notation(), "k")

        self.game.board[7][7].firstMove = False
        self.assertEqual(self.game.get_castling_notation(), "-")
예제 #23
0
class TestUpdateEnPassant(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_update_implement_en_passant(self):
        self.game.half_move_clock = 0
        self.game.full_move_clock = 10
        self.game.count = 20
        self.game.empty_cell = Empty(None, Color.EMPTY, -1, -1)
        self.game.history = [{"fen": "3q4/8/8/8/Pp6/8/8/5K2 b - a3 0 10",
                             "movement": {"src": "a2", "tar": "a4"}}]
        self.game.castling_notation = "-"
        self.game.turn = Color.BLACK
        for row in range(8):
            for col in range(8):
                self.game.board[row][col] = self.game.empty_cell
        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.game.board[3][0] = Pawn(self.game, Color.WHITE, 3, 0)
        self.game.board[3][1] = Pawn(self.game, Color.BLACK, 3, 1)
        self.game.update_en_passant((3, 1), (2, 0))
        self.assertEqual(self.game.board[3][0], self.game.empty_cell)
예제 #24
0
class TestInitHistory(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_init_history_restores_expected_history(self):
        history = [["", 1, "a2", "a4", "rnbqkbnr/pppppppp/8/8/P7/8/1PPPPPPP/RNBQKBNR b KQkq a3 0 1"],
                   ["", 2, "a7", "a5", "rnbqkbnr/1ppppppp/8/p7/P7/8/1PPPPPPP/RNBQKBNR w KQkq a6 0 2"],
                   ["", 3, "a1", "a3", "rnbqkbnr/1ppppppp/8/p7/P7/R7/1PPPPPPP/1NBQKBNR b Kkq - 1 2"],
                   ["", 4, "a8", "a6", "1nbqkbnr/1ppppppp/r7/p7/P7/R7/1PPPPPPP/1NBQKBNR w Kk - 2 3"],
                   ["", 5, "h2", "h4", "1nbqkbnr/1ppppppp/r7/p7/P6P/R7/1PPPPPP1/1NBQKBNR b Kk h3 0 3"],
                   ["", 6, "h7", "h5", "1nbqkbnr/1pppppp1/r7/p6p/P6P/R7/1PPPPPP1/1NBQKBNR w Kk h6 0 4"],
                   ["", 7, "h1", "h3", "1nbqkbnr/1pppppp1/r7/p6p/P6P/R6R/1PPPPPP1/1NBQKBN1 b k - 1 4"]]

        self.game.init_history(history)
        expected = [{"fen": "rnbqkbnr/pppppppp/8/8/P7/8/1PPPPPPP/RNBQKBNR b KQkq a3 0 1",
                     "movement": {"src": "a2", "tar": "a4"}},
                    {"fen": "rnbqkbnr/1ppppppp/8/p7/P7/8/1PPPPPPP/RNBQKBNR w KQkq a6 0 2",
                     "movement": {"src": "a7", "tar": "a5"}},
                    {"fen": "rnbqkbnr/1ppppppp/8/p7/P7/R7/1PPPPPPP/1NBQKBNR b Kkq - 1 2",
                     "movement": {"src": "a1", "tar": "a3"}},
                    {"fen": "1nbqkbnr/1ppppppp/r7/p7/P7/R7/1PPPPPPP/1NBQKBNR w Kk - 2 3",
                     "movement": {"src": "a8", "tar": "a6"}},
                    {"fen": "1nbqkbnr/1ppppppp/r7/p7/P6P/R7/1PPPPPP1/1NBQKBNR b Kk h3 0 3",
                     "movement": {"src": "h2", "tar": "h4"}},
                    {"fen": "1nbqkbnr/1pppppp1/r7/p6p/P6P/R7/1PPPPPP1/1NBQKBNR w Kk h6 0 4",
                     "movement": {"src": "h7", "tar": "h5"}},
                    {"fen": "1nbqkbnr/1pppppp1/r7/p6p/P6P/R6R/1PPPPPP1/1NBQKBN1 b k - 1 4",
                     "movement": {"src": "h1", "tar": "h3"}}]
        self.assertEqual(self.game.history[0], expected[0])
        self.assertEqual(self.game.history[1], expected[1])
        self.assertEqual(self.game.history[2], expected[2])
        self.assertEqual(self.game.history[3], expected[3])
        self.assertEqual(self.game.history[4], expected[4])
        self.assertEqual(self.game.history[5], expected[5])
        self.assertEqual(self.game.history[6], expected[6])

        self.assertEqual(len(history), 7)
        self.assertEqual(len(self.game.history), 7)
예제 #25
0
    def test_load_fen_restores_correct_moves_and_clock(self):
        game = ChessGame()
        game.load_fen("8/8/8/8/8/8/8/8 w KQkq - 0 1")
        self.assertEqual(game.half_move_clock, 0)
        self.assertEqual(game.full_move_clock, 1)
        self.assertEqual(game.count, 0)

        game.load_fen("8/8/8/8/8/8/8/8 b KQkq - 10 15")
        self.assertEqual(game.half_move_clock, 10)
        self.assertEqual(game.full_move_clock, 15)
        self.assertEqual(game.count, 29)

        game.load_fen("8/8/8/8/8/8/8/8 w - - 20 14")
        self.assertEqual(game.half_move_clock, 20)
        self.assertEqual(game.full_move_clock, 14)
        self.assertEqual(game.count, 26)
예제 #26
0
    def test_load_fen_gives_correct_board(self):
        game = ChessGame()
        game.load_fen("8/8/8/8/8/8/8/8 w KQkq - 0 1")
        for row in range(8):
            for col in range(8):
                self.assertEqual(type(game.board[row][col]), Empty)

        game.load_fen("8/8/1r1R4/8/8/8/8/8 w KQkq - 0 1")
        self.assertEqual(type(game.board[5][1]), Rook)
        self.assertEqual(game.board[5][1].color, Color.BLACK)

        self.assertEqual(type(game.board[5][3]), Rook)
        self.assertEqual(game.board[5][3].color, Color.WHITE)

        game.load_fen("8/8/8/8/8/8/8/k7 w KQkq - 0 1")
        self.assertEqual(type(game.board[0][0]), King)
        self.assertEqual(game.board[0][0].color, Color.BLACK)
예제 #27
0
class TestIsBeingCheckedAfterMove(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_is_being_checked_after_move_start(self):
        self.assertFalse(self.game.is_being_checked_after_move((1, 4), (3, 4)))

    def test_is_being_checked_after_move_in_few_moves(self):
        self.assertFalse(self.game.is_being_checked_after_move((6, 2), (4, 2)))
        self.assertFalse(self.game.is_being_checked_after_move((0, 6), (2, 5)))
        self.assertFalse(self.game.is_being_checked_after_move((0, 6), (2, 5)))
        self.assertFalse(self.game.is_being_checked_after_move((6, 0), (4, 0)))
        self.assertFalse(self.game.is_being_checked_after_move((0, 7), (0, 6)))
        self.assertFalse(self.game.is_being_checked_after_move((7, 0), (6, 0)))
        self.assertFalse(self.game.is_being_checked_after_move((1, 0), (3, 0)))
        self.assertFalse(self.game.is_being_checked_after_move((6, 7), (4, 7)))
        self.assertFalse(self.game.is_being_checked_after_move((0, 0), (1, 0)))
        self.assertFalse(self.game.is_being_checked_after_move((7, 7), (6, 7)))

    def test_is_being_checked_after_move_during_game_true(self):
        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[0][0] = King(self.game, Color.WHITE, 0, 0)
        self.game.board[7][3] = King(self.game, Color.BLACK, 7, 3)
        self.game.kings_coordinate = [(0, 0), (7, 3)]
        self.game.board[1][0] = Pawn(self.game, Color.BLACK, 1, 0)
        self.game.board[4][5] = Pawn(self.game, Color.WHITE, 4, 5)
        self.game.board[4][1] = Rook(self.game, Color.WHITE, 4, 1)
        self.game.board[4][2] = Bishop(self.game, Color.BLACK, 4, 2)
        self.assertTrue(self.game.is_being_checked_after_move((4, 2), (3, 3)))

    def test_is_being_checked_after_move_during_game_false(self):
        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[0][4] = King(self.game, Color.WHITE, 0, 4)
        self.game.board[7][3] = King(self.game, Color.BLACK, 7, 3)
        self.game.kings_coordinate = [(0, 4), (7, 3)]
        self.game.board[1][0] = Pawn(self.game, Color.BLACK, 1, 0)
        self.game.board[4][5] = Pawn(self.game, Color.WHITE, 4, 5)
        self.game.board[4][1] = Rook(self.game, Color.WHITE, 4, 1)
        self.game.board[4][2] = Bishop(self.game, Color.BLACK, 4, 2)
        self.assertFalse(self.game.is_being_checked_after_move((4, 2), (2, 4)))
예제 #28
0
 def test_get_checked_moves_include_castling(self):
     fen = "8/8/8/8/8/8/8/8 w KQkq - 0 1"
     chess_game2 = ChessGame(fen=fen)
     chess_game2.board[0][4] = King(chess_game2, Color.WHITE, 0, 4)
     chess_game2.board[7][4] = King(chess_game2, Color.BLACK, 7, 4)
     chess_game2.board[0][7] = Rook(chess_game2, Color.WHITE, 0, 7)
     chess_game2.board[0][0] = Rook(chess_game2, Color.WHITE, 0, 0)
     actual = chess_game2.board[0][4].get_checked_moves()
     expected = {
         'moves': [(1, 4), (1, 5), (0, 5), (0, 3), (1, 3), (0, 6), (0, 2)]
     }
     self.assertEqual(actual, expected)
예제 #29
0
class TestUndo(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_undo_init(self):
        self.game.undo()
        self.assertEqual(self.game.turn, Color.WHITE)
        self.assertEqual(self.game.history, [])

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

    def test_undo(self):
        self.game.history = [{"fen": "rnbqkbnr/pppppppp/8/8/P7/8/1PPPPPPP/RNBQKBNR b KQkq a3 0 1",
                             "movement": {"src": "a2", "tar": "a4"}},
                             {"fen": "rnbqkbnr/1ppppppp/8/p7/P7/8/1PPPPPPP/RNBQKBNR w KQkq a6 0 2",
                              "movement": {"src": "a7", "tar": "a5"}},
                             {"fen": "rnbqkbnr/1ppppppp/8/p7/P7/R7/1PPPPPPP/1NBQKBNR b Kkq - 1 2",
                              "movement": {"src": "a1", "tar": "a3"}},
                             {"fen": "1nbqkbnr/1ppppppp/r7/p7/P7/R7/1PPPPPP1/1NBQKBNR w Kk - 2 3",
                              "movement": {"src": "a8", "tar": "a6"}}]
        self.game.undo()
        color = Color.BLACK
        self.assertEqual(self.game.turn, color)
        self.assertEqual(self.game.castling_notation, "Kkq")
        self.assertEqual(self.game.en_passant_target_notation, "-")
        self.assertEqual(self.game.half_move_clock, 1)
        self.assertEqual(self.game.full_move_clock, 2)
        self.assertEqual(self.game.board[0][0], self.game.empty_cell)
        self.assertEqual(type(self.game.board[0][1]), Knight)
        self.assertEqual(self.game.board[0][1].color, Color.WHITE)
        self.assertEqual(type(self.game.board[0][2]), Bishop)
        self.assertEqual(type(self.game.board[0][3]), Queen)
        self.assertEqual(type(self.game.board[0][4]), King)
        self.assertEqual(type(self.game.board[0][5]), Bishop)
        self.assertEqual(type(self.game.board[0][6]), Knight)
        self.assertEqual(type(self.game.board[0][7]), Rook)
        self.assertEqual(type(self.game.board[7][0]), Rook)
        self.assertEqual(type(self.game.board[7][1]), Knight)
        self.assertEqual(self.game.board[7][1].color, Color.BLACK)
        self.assertEqual(type(self.game.board[7][2]), Bishop)
        self.assertEqual(type(self.game.board[7][3]), Queen)
        self.assertEqual(type(self.game.board[7][4]), King)
        self.assertEqual(type(self.game.board[7][5]), Bishop)
        self.assertEqual(type(self.game.board[7][6]), Knight)
        self.assertEqual(type(self.game.board[7][7]), Rook)
예제 #30
0
class TestUpdatePromotion(unittest.TestCase):
    def setUp(self) -> None:
        self.game = ChessGame(fen="start")

    def test_update_implement_promotion(self):
        self.game.half_move_clock = 0
        self.game.full_move_clock = 10
        self.game.count = 20
        self.game.empty_cell = Empty(None, Color.EMPTY, -1, -1)
        self.game.history = [{"fen": "3bk3/PP6/8/8/8/8/6pp/4KB2 w - - 0 10",
                              "movement": {"src": "a6", "tar": "a7"}}]
        self.game.turn = Color.WHITE
        for row in range(8):
            for col in range(8):
                self.game.board[row][col] = self.game.empty_cell
        self.game.board[7][4] = King(self.game, Color.BLACK, 7, 4)
        self.game.board[7][3] = Bishop(self.game, Color.BLACK, 7, 3)
        self.game.board[7][4].firstMove = True
        self.game.board[0][4] = King(self.game, Color.WHITE, 0, 4)
        self.game.board[0][5] = Rook(self.game, Color.WHITE, 0, 5)
        self.game.board[0][4].firstMove = True
        self.game.board[6][0] = Pawn(self.game, Color.WHITE, 6, 0)
        self.game.board[1][7] = Pawn(self.game, Color.BLACK, 1, 7)
        self.game.board[6][1] = Pawn(self.game, Color.WHITE, 6, 1)
        self.game.board[1][6] = Pawn(self.game, Color.BLACK, 1, 6)

        self.game.update_promotion((6, 0), (7, 0), "Queen")
        self.assertEqual(type(self.game.board[7][0]), Queen)
        self.assertEqual(self.game.board[7][0].color, Color.WHITE)

        self.game.update_promotion((1, 7), (0, 7), "Rook")
        self.assertEqual(type(self.game.board[0][7]), Rook)
        self.assertEqual(self.game.board[0][7].color, Color.BLACK)

        self.game.update_promotion((6, 1), (7, 1), "Bishop")
        self.assertEqual(type(self.game.board[7][1]), Bishop)
        self.assertEqual(self.game.board[7][0].color, Color.WHITE)

        self.game.update_promotion((1, 6), (0, 6), "Knight")
        self.assertEqual(type(self.game.board[0][6]), Knight)
        self.assertEqual(self.game.board[0][6].color, Color.BLACK)