Beispiel #1
0
    async def make_move(self, game: Game, move: str) -> Game:
        """
        Makes a move in given game, if valid

        :param game: Game to be played
        :type game: Game
        :param move: Chess move in SAN or UCI notation
        :type move: str
        :return: Updated game
        :rtype: Game
        """
        chess_move = self._parse_str_move(game, move)
        if not chess_move:
            raise InvalidMove()
        game.board.push(chess_move)

        game.current_player = game.player1 if game.current_player == game.player2 else game.player2

        if self.is_pve_game(game) and not self.is_game_over(game):
            stockfish_result = await self._play_move(game)
            game.board.push(stockfish_result.move)
            game.current_player = game.player1

        if self.is_game_over(game):
            game.result = game.board.result(claim_draw=True)
            self.games.remove(game)

        await game.save()
        return game
    def test_make_move_legal_move_pve(self):
        board = chess.Board(
            'rn2kb1r/pp1qpppp/2ppbn2/1B6/3PP3/2N2N2/PPP2PPP/R1BQK2R w KQkq - 0 6'
        )
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1
        game.cpu_level = 0

        chess_bot = Chess()
        chess_bot.games.append(game)
        chess_bot.stockfish_limit['time'] = 1
        result = asyncio.run(chess_bot.make_move(game, 'b5d3'))

        self.assertIsInstance(result, Game)
        if chess_bot.is_stockfish_enabled():
            self.assertEqual(len(result.board.move_stack), 2)
            self.assertEqual(result.current_player, game.player1)

        updated_chess_game = self.db_session.query(ChessGame).filter_by(
            player1_id=result.player1.id).first()
        updated_game_from_db = Game.from_chess_game_model(updated_chess_game)
        self.assertEqual(updated_game_from_db.board.move_stack,
                         result.board.move_stack)
    def test_make_move_draw_by_threefold_repetition(self):
        board = chess.Board()
        board.push_san("Nf3")
        board.push_san("Nf6")
        board.push_san("Ng1")
        board.push_san("Ng8")
        board.push_san("Nf3")
        board.push_san("Nf6")
        board.push_san("Ng1")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player2

        chess_bot = Chess()
        chess_bot.games.append(game)

        self.assertFalse(chess_bot.is_game_over(game))

        result = asyncio.run(chess_bot.make_move(game, 'Ng8'))

        self.assertIsInstance(result, Game)
        self.assertEqual(len(chess_bot.games), 0)
        self.assertEqual(
            self.db_session.query(ChessGame).filter_by(result=0).count(), 1)
        self.assertTrue(chess_bot.is_game_over(result))
        self.assertEqual(result.result, '1/2-1/2')
    def test_find_current_game_other_player_not_found(self):
        chess_bot = Chess()

        board = chess.Board()
        board.push_san("e4")
        board.push_san("e5")
        game1 = Game()
        game1.board = board
        game1.player1 = FakeDiscordUser(id=1)
        game1.player2 = FakeDiscordUser(id=2)
        game1.current_player = game1.player1
        chess_bot.games.append(game1)

        game2 = Game()
        game2.board = board
        game2.player1 = FakeDiscordUser(id=1)
        game2.player2 = FakeDiscordUser(id=3)
        game2.current_player = game2.player1
        chess_bot.games.append(game2)

        with self.assertRaises(Exception) as e:
            chess_bot.find_current_game(user=FakeDiscordUser(id=14))

            self.assertIn("Partida não encontrada", str(e))
    def test_find_current_game_player_playing_themselves_and_others(self):
        chess_bot = Chess()

        board = chess.Board()
        board.push_san("e4")
        board.push_san("e5")
        game1 = Game()
        game1.board = board
        game1.player1 = FakeDiscordUser(id=1)
        game1.player2 = FakeDiscordUser(id=2)
        game1.current_player = game1.player1
        chess_bot.games.append(game1)

        game2 = Game()
        game2.board = board
        game2.player1 = FakeDiscordUser(id=1)
        game2.player2 = FakeDiscordUser(id=1)
        game2.current_player = game2.player1
        chess_bot.games.append(game2)

        result = chess_bot.find_current_game(user=game2.player1,
                                             other_user=game2.player2)

        self.assertEqual(result, game2)
    def test_find_current_game_in_players_turn_amibiguity_solved(self):
        chess_bot = Chess()

        board = chess.Board()
        board.push_san("e4")
        board.push_san("e5")
        game1 = Game()
        game1.board = board
        game1.player1 = FakeDiscordUser(id=1)
        game1.player2 = FakeDiscordUser(id=2)
        game1.current_player = game1.player1
        chess_bot.games.append(game1)

        game2 = Game()
        game2.board = board
        game2.player1 = FakeDiscordUser(id=1)
        game2.player2 = FakeDiscordUser(id=3)
        game2.current_player = game2.player1
        chess_bot.games.append(game2)

        result = chess_bot.find_current_game(user=game1.player1,
                                             other_user=game1.player2)

        self.assertEqual(result, game1)
    def test_find_current_game_in_players_turn_with_amibiguity(self):
        chess_bot = Chess()

        board = chess.Board()
        board.push_san("e4")
        board.push_san("e5")
        game1 = Game()
        game1.board = board
        game1.player1 = FakeDiscordUser(id=1)
        game1.player2 = FakeDiscordUser(id=2)
        game1.current_player = game1.player1
        chess_bot.games.append(game1)

        game2 = Game()
        game2.board = board
        game2.player1 = FakeDiscordUser(id=1)
        game2.player2 = FakeDiscordUser(id=3)
        game2.current_player = game2.player1
        chess_bot.games.append(game2)

        with self.assertRaises(Exception) as e:
            chess_bot.find_current_game(user=game1.player1)

            self.assertIn("Informe contra qual jogador", str(e))
    def test_find_current_game_in_players_turn_no_ambiguity(self):
        board = chess.Board()
        board.push_san("e4")
        board.push_san("e5")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1

        chess_bot = Chess()
        chess_bot.games.append(game)

        result = chess_bot.find_current_game(user=game.player1)

        self.assertEqual(result, game)
    def test_resign_game_found(self):
        board = chess.Board()
        board.push_san("e4")
        board.push_san("e5")
        board.push_san("Nf3")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1

        chess_bot = Chess()
        chess_bot.games.append(game)
        result = asyncio.run(chess_bot.resign(game))

        self.assertEqual(len(chess_bot.games), 0)
        self.assertEqual(
            self.db_session.query(ChessGame).filter_by(result=1).count(), 1)
    def test_make_move_illegal_move_in_players_turn(self):
        board = chess.Board()
        board.push_san("e4")
        board.push_san("e5")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1

        chess_bot = Chess()
        chess_bot.games.append(game)

        with self.assertRaises(InvalidMove) as e:
            asyncio.run(chess_bot.make_move(game, 'invalid'))

        self.assertEqual(len(game.board.move_stack), 2)
        self.assertEqual(game.current_player, game.player1)
    def test_eval_last_move_no_blunder_no_mate(self):
        board = chess.Board()
        board.push_san("g4")
        board.push_san("e5")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1
        game.last_eval = Cp(0)

        chess_bot = Chess()
        chess_bot.games.append(game)
        chess_bot.stockfish_limit["time"] = 2

        result = asyncio.run(chess_bot.eval_last_move(game))

        self.assertFalse(result["blunder"])
        self.assertIsNone(result["mate_in"])
    def test_generate_pgn(self):
        board = chess.Board()
        board.push_san("g4")
        board.push_san("e5")
        board.push_san("f4")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1, name='Player1')
        game.player2 = FakeDiscordUser(id=2, name='Player2')
        game.current_player = game.player1
        game.result = game.board.result()

        chess_bot = Chess()
        chess_bot.games.append(game)
        result = chess_bot.generate_pgn(game)

        self.assertIn('[White "Player1"]', result)
        self.assertIn('[Black "Player2"]', result)
        self.assertIn('1. g4 e5 2. f4 *', result)
    def test_eval_last_move_no_blunder_mate_in_two(self):
        board = chess.Board(
            "Q2r4/1p1k4/1P3ppp/1Kp1r3/4p2b/1B3P2/2P2q2/8 w - - 6 44")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1
        game.last_eval = Mate(2)

        chess_bot = Chess()
        chess_bot.games.append(game)

        result = asyncio.run(chess_bot.eval_last_move(game))

        self.assertFalse(result["blunder"])
        if chess_bot.is_stockfish_enabled():
            self.assertEqual(result["mate_in"], 2)
        else:
            self.assertIsNone(result["mate_in"])
Beispiel #14
0
    def new_game(self, user1, user2, color_schema=None, cpu_level=None):
        player1, player2 = convert_users_to_players(user1, user2)
        current_players_pairs = map(lambda x: [x.player1, x.player2],
                                    self.games)
        given_players_pairs = [player1, player2]

        if given_players_pairs in current_players_pairs:
            raise GameAlreadyInProgress()

        game = Game()
        game.board = chess.Board()
        game.player1 = player1
        game.player2 = player2
        game.current_player = player1
        game.result = game.board.result()
        game.color_schema = color_schema
        game.cpu_level = cpu_level

        self.games.append(game)
        return game
    def test_eval_last_move_lost_position_blunders_mate(self):
        board = chess.Board(
            "Q1kr4/1p6/1P3ppp/1Kp1r3/4p2b/1B3P2/2P2q2/8 b - - 5 43")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1
        game.last_eval = Cp(1000)

        chess_bot = Chess()
        chess_bot.games.append(game)

        result = asyncio.run(chess_bot.eval_last_move(game))

        if chess_bot.is_stockfish_enabled():
            self.assertTrue(result["blunder"])
            self.assertEqual(result["mate_in"], -2)
        else:
            self.assertFalse(result["blunder"])
            self.assertIsNone(result["mate_in"])
    def test_make_move_finish_game(self):
        board = chess.Board()
        board.push_san("g4")
        board.push_san("e5")
        board.push_san("f4")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1

        chess_bot = Chess()
        chess_bot.games.append(game)
        result = asyncio.run(chess_bot.make_move(game, 'd8h4'))

        self.assertIsInstance(result, Game)
        self.assertEqual(len(chess_bot.games), 0)
        self.assertEqual(
            self.db_session.query(ChessGame).filter_by(result=-1).count(), 1)
        self.assertTrue(chess_bot.is_game_over(result))
        self.assertEqual(result.result, '0-1')
    def test_eval_last_move_last_move_blunder_mate_in_one(self):
        board = chess.Board()
        board.push_san("g4")
        board.push_san("e5")
        board.push_san("f4")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1
        game.last_eval = Cp(0)

        chess_bot = Chess()
        chess_bot.games.append(game)
        result = asyncio.run(chess_bot.eval_last_move(game))

        if chess_bot.is_stockfish_enabled():
            self.assertTrue(result["blunder"])
            self.assertEqual(result["mate_in"], 1)
        else:
            self.assertFalse(result["blunder"])
            self.assertIsNone(result["mate_in"])
    def test_make_move_legal_san_move_in_players_turn(self):
        board = chess.Board()
        board.push_san("e4")
        board.push_san("e5")
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)
        game.current_player = game.player1

        chess_bot = Chess()
        chess_bot.games.append(game)
        result = asyncio.run(chess_bot.make_move(game, 'Nf3'))

        self.assertIsInstance(result, Game)
        self.assertEqual(len(result.board.move_stack), 3)
        self.assertEqual(result.current_player, game.player2)

        updated_chess_game = self.db_session.query(ChessGame).filter_by(
            player1_id=result.player1.id).first()
        updated_game_from_db = Game.from_chess_game_model(updated_chess_game)
        self.assertEqual(updated_game_from_db.board.move_stack,
                         result.board.move_stack)