def test_save_games(self):
        chess_bot = Chess()
        board1 = chess.Board()
        board1.push_san("e4")
        board1.push_san("e5")
        game1 = Game()
        game1.board = board1
        game1.player1 = FakeDiscordUser(id=1)
        game1.player2 = FakeDiscordUser(id=2)
        asyncio.run(game1.save())
        board2 = chess.Board()
        board2.push_san("Nf3")
        game2 = Game()
        game2.board = board2
        game2.player1 = FakeDiscordUser(id=2)
        game2.player2 = FakeDiscordUser(id=3)
        chess_bot.games = [game1, game2]

        asyncio.run(chess_bot.save_games())

        expected = [
            Game.from_chess_game_model(x)
            for x in self.db_session.query(ChessGame)
        ]

        self.assertEqual(chess_bot.games, expected)
        self.assertEqual(game1.color_schema, expected[0].color_schema)
        self.assertEqual(game1.cpu_level, expected[0].cpu_level)
        self.assertEqual(game2.color_schema, expected[1].color_schema)
        self.assertEqual(game2.cpu_level, expected[1].cpu_level)
    def test_get_all_boards_png_three_games(self):
        chess_bot = Chess()

        board1 = chess.Board()
        board1.push_san("e4")
        board1.push_san("e5")
        game1 = Game()
        game1.color_schema = "blue"
        game1.board = board1
        chess_bot.games.append(game1)

        board2 = chess.Board()
        board2.push_san("Nf3")
        board2.push_san("d6")
        game2 = Game()
        game2.color_schema = "wood"
        game2.board = board2
        chess_bot.games.append(game2)

        board3 = chess.Board()
        board3.push_san("Nf3")
        game3 = Game()
        game3.color_schema = "green"
        game3.board = board3
        chess_bot.games.append(game3)

        image_bytesio = asyncio.run(chess_bot.get_all_boards_png())

        with open(
                os.path.join('tests', 'support',
                             'get_all_boards_png_three_games.png'), 'rb') as f:
            self.assertEqual(image_bytesio.read(), f.read())
    def test_load_games_entries_exist(self):
        warnings.simplefilter('ignore')
        board1 = chess.Board()
        board1.push_san("e4")
        board1.push_san("e5")
        game1 = Game()
        game1.board = board1
        game1.player1 = FakeDiscordUser(id=1)
        game1.player2 = FakeDiscordUser(id=2)
        asyncio.run(game1.save())
        board2 = chess.Board()
        board2.push_san("Nf3")
        game2 = Game()
        game2.board = board2
        game2.player1 = FakeDiscordUser(id=2)
        game2.player2 = FakeDiscordUser(id=3)
        asyncio.run(game2.save())
        game3 = Game()
        game3.board = chess.Board(
            'rnbqkbnr/ppppp2p/8/5ppQ/4P3/2N5/PPPP1PPP/R1B1KBNR b KQkq - 0 1')
        game3.player1 = FakeDiscordUser(id=2)
        game3.player2 = FakeDiscordUser(id=3)
        game3.result = '1-0'
        asyncio.run(game3.save())

        expected_games = [game1, game2]

        chess_bot = Chess()

        actual = asyncio.run(chess_bot.load_games())

        self.assertListEqual(expected_games, actual)
    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 _build_puzzle_bot_with_one_puzzle(self):
     puzzle_bot = Puzzle()
     game = Game()
     game.board = Board("8/7p/4p1p1/1p5k/8/PB4PK/2P2q1P/4R3 w - - 0 37")
     game.board.push_san("g4+")
     puzzle_id = "557ca53de13823b83a98100e"
     puzzle_bot.puzzles = {
         puzzle_id: {
             "game": game,
             "correct_sequence": ["Kg5", "Rf1", "Qxf1+", "Kg3", "Qf4+"]
         }
     }
     return puzzle_bot, puzzle_id
    def test_get_game_by_id_game_invalid_uuid(self):
        warnings.simplefilter('ignore')
        board1 = chess.Board()
        board1.push_san("e4")
        board1.push_san("e5")
        game1 = Game()
        game1.board = board1
        game1.player1 = FakeDiscordUser(id=1)
        game1.player2 = FakeDiscordUser(id=2)
        asyncio.run(game1.save())

        result = asyncio.run(Chess().get_game_by_id("invalid_id"))

        self.assertIsNone(result)
    def test_get_game_by_id_game_exists(self):
        warnings.simplefilter('ignore')
        board1 = chess.Board()
        board1.push_san("e4")
        board1.push_san("e5")
        game1 = Game()
        game1.board = board1
        game1.player1 = FakeDiscordUser(id=1)
        game1.player2 = FakeDiscordUser(id=2)
        asyncio.run(game1.save())

        result = asyncio.run(Chess().get_game_by_id(game1.id))

        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_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_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_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_get_all_boards_png_one_game(self):
        chess_bot = Chess()

        board1 = chess.Board()
        board1.push_san("e4")
        board1.push_san("e5")
        board1.push_san("Bc4")
        game1 = Game()
        game1.color_schema = "green"
        game1.board = board1
        chess_bot.games.append(game1)

        image_bytesio = asyncio.run(chess_bot.get_all_boards_png())

        with open(
                os.path.join('tests', 'support',
                             'get_all_boards_png_one_game.png'), 'rb') as f:
            self.assertEqual(image_bytesio.read(), f.read())
    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_build_animated_sequence_gif_invalid_move_in_sequence(self):
        board = chess.Board()
        board.push_san('e4')
        board.push_san('c5')
        board.push_san('Nc3')
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)

        chess_bot = Chess()
        chess_bot.games.append(game)
        sequence = ['Nf3', 'd6', 'd4', 'Rxa8', 'Nxd4', 'Nf6', 'Nc3', 'a6']

        result = asyncio.run(
            chess_bot.build_animated_sequence_gif(game, 2, sequence))

        self.assertIsNone(result)
    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_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_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"])
Example #21
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
Example #22
0
    def build_animated_sequence_gif(self, game: Game, game_move: int,
                                    sequence: list) -> BytesIO:
        """
        Builds an animated GIF for illustrating a given game's possible variation

        :param game: Game to be used for variation
        :type game: Game
        :param game_move: Number of game's move for the start of variation
        :type game_move: int
        :param sequence: Variation's sequence of move
        :type sequence: str[]
        :return: Animated gif's bytesIO
        :rtype: BytesIO
        """
        game_moves = game.board.move_stack
        new_board = chess.Board()
        new_game = Game()
        new_game.board = new_board
        new_game.color_schema = game.color_schema
        for move in game_moves[:game_move]:
            new_board.push(move)

        first_gif_frame = Image.open(self.build_png_board(new_game))
        gif_frames = []
        for variant_move in sequence:
            variant_chess_move = self._parse_str_move(new_game, variant_move)
            if not variant_chess_move:
                return
            new_board.push(variant_chess_move)
            gif_frame = Image.open(self.build_png_board(new_game))
            gif_frames.append(gif_frame)

        bytesio = BytesIO()
        first_gif_frame.save(bytesio,
                             format='gif',
                             save_all=True,
                             append_images=gif_frames,
                             duration=1000,
                             loop=0)
        bytesio.seek(0)
        return bytesio
    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_build_animated_sequence_gif_valid_params(self):
        board = chess.Board()
        board.push_san('e4')
        board.push_san('c5')
        board.push_san('Nc3')
        game = Game()
        game.board = board
        game.player1 = FakeDiscordUser(id=1)
        game.player2 = FakeDiscordUser(id=2)

        chess_bot = Chess()
        chess_bot.games.append(game)
        sequence = ['Nf3', 'd6', 'd4', 'cxd4', 'Nxd4', 'Nf6', 'Nc3', 'a6']

        result = asyncio.run(
            chess_bot.build_animated_sequence_gif(game, 2, sequence))

        with open(
                os.path.join('tests', 'support',
                             'build_animated_sequence_gif.gif'), 'rb') as f:
            self.assertEqual(result.getvalue(), f.read())
    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_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"])
Example #27
0
    def build_puzzle(self, puzzle_dict):
        try:
            puzzle_id = puzzle_dict["data"]["id"]
            first_move = puzzle_dict["data"]["blunderMove"]
            fen = puzzle_dict["data"]["fenBefore"]
            correct_sequence = puzzle_dict["data"]["forcedLine"]

            board = Board(fen)
            board.push_san(first_move)
            game = Game()
            game.board = board
            game.color_schema = "default"
            self.puzzles[puzzle_id] = {
                "id": puzzle_id,
                "game": game,
                "correct_sequence": correct_sequence
            }
            return self.puzzles[puzzle_id]
        except KeyError:
            return {"error": "Missing required keys"}
        except:
            return {"error": "Invalid FEN or move"}
    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)