async def test_win_and_in_then_lost_and_out(self): game_id = id8() game = Game( self.app, game_id, "crazyhouse", "", self.strong_player, self.weak_player, rated=True, chess960=True, create=True, ) self.app["games"][game.id] = game self.assertEqual(game.status, CREATED) self.assertEqual(len(game.crosstable["r"]), 0) self.print_game_highscore(game) # weak_player resign 1-0 await self.play_and_resign(game, self.weak_player) self.print_game_highscore(game) self.assertEqual(len(game.crosstable["r"]), 1) print(game.crosstable) self.assertTrue(self.weak_player.username not in game.highscore["crazyhouse960"].keys()[:10]) self.assertTrue(self.strong_player.username in game.highscore["crazyhouse960"].keys()[:10]) # now strong player will lose to weak_player and should be out from leaderboard game_id = id8() game = Game( self.app, game_id, "crazyhouse", "", self.strong_player, self.weak_player, rated=True, chess960=True, create=True, ) self.app["games"][game.id] = game print(game.crosstable) # strong_player resign 0-1 await self.play_and_resign(game, self.strong_player) self.print_game_highscore(game) print(game.crosstable) self.assertEqual(len(game.crosstable["r"]), 2) self.assertTrue(self.weak_player.username not in game.highscore["crazyhouse960"].keys()[:10]) self.assertTrue(self.strong_player.username not in game.highscore["crazyhouse960"].keys()[:10])
async def join_players(self, nb_players): self.game_tasks = set() for i in range(nb_players): name = (id8() + id8())[:random.randint(1, 16)] player = User(self.app, username=name, title="TEST", perfs=PERFS) self.app["users"][player.username] = player player.tournament_sockets[self.id] = set((None, )) await self.join(player)
async def test_tournament_pairing_1_min_ARENA(self): self.app["db"] = None NB_PLAYERS = 15 tid = id8() self.tournament = ArenaTestTournament(self.app, tid, before_start=0.1, minutes=1) self.app["tournaments"][tid] = self.tournament await self.tournament.join_players(NB_PLAYERS) # withdraw one player await self.tournament.withdraw( list(self.tournament.players.keys())[-1]) self.assertEqual(self.tournament.nb_players, NB_PLAYERS - 1) # make the first player leave the tournament lobby del list(self.tournament.players.keys())[0].tournament_sockets[ self.tournament.id] self.assertEqual(len(self.tournament.waiting_players()), NB_PLAYERS - 2) await self.tournament.clock_task self.assertEqual(self.tournament.status, T_FINISHED)
async def test_tournament_with_3_active_players(self): self.app["db"] = None NB_PLAYERS = 15 tid = id8() self.tournament = ArenaTestTournament(self.app, tid, before_start=0.1, minutes=1) self.app["tournaments"][tid] = self.tournament await self.tournament.join_players(NB_PLAYERS) # 12 player leave the tournament lobby for i in range(12): print(i) del list(self.tournament.players.keys())[i].tournament_sockets[ self.tournament.id] self.assertEqual(len(self.tournament.waiting_players()), NB_PLAYERS - 12) await self.tournament.clock_task self.assertEqual(self.tournament.status, T_FINISHED) for user in self.tournament.players: self.assertTrue(self.tournament.players[user].nb_not_paired <= 1)
async def test_lost_and_out(self): game_id = id8() game = Game( self.app, game_id, "crazyhouse", "", self.wplayer, self.strong_player, rated=True, chess960=True, create=True, ) self.app["games"][game.id] = game self.assertEqual(game.status, CREATED) self.assertEqual(len(game.crosstable["r"]), 0) self.print_game_highscore(game) highscore0 = game.highscore["crazyhouse960"].peekitem(7) # wplayer resign 0-1 await self.play_and_resign(game, self.wplayer) self.print_game_highscore(game) highscore1 = game.highscore["crazyhouse960"].peekitem(7) self.assertEqual(len(game.crosstable["r"]), 1) self.assertNotEqual(highscore0, highscore1) self.assertTrue(self.wplayer.username not in game.highscore["crazyhouse960"].keys()[:10])
async def test_game_play(self): """Playtest test_player vs Random-Mover""" for i, variant in enumerate(VARIANTS): print(i, variant) variant960 = variant.endswith("960") variant_name = variant[:-3] if variant960 else variant game_id = id8() game = Game( self.app, game_id, variant_name, "", self.test_player, self.random_mover, rated=False, chess960=variant960, create=True, ) self.app["games"][game.id] = game self.random_mover.game_queues[game_id] = None await self.play_random(game) pgn = game.pgn pgn_result = pgn[pgn.rfind(" ") + 1:-1] self.assertIn(game.result, ("1-0", "0-1", "1/2-1/2")) self.assertEqual(game.result, pgn_result)
def __init__( self, app, bot=False, username=None, anon=False, title="", perfs=None, enabled=True, ): self.app = app self.db = app["db"] if "db" in app else None self.bot = False if username == "PyChessBot" else bot self.anon = anon if username is None: self.anon = True self.username = "******" + id8() else: self.username = username self.seeks = {} self.lobby_sockets = set() self.tournament_sockets = {} # {tournamentId: set()} self.game_sockets = {} self.title = title self.game_in_progress = None if self.bot: self.event_queue = asyncio.Queue() self.game_queues = {} self.title = "BOT" self.online = False if perfs is None: if (not anon) and (not bot) and (title != "TEST"): raise MissingRatingsException(username) self.perfs = {variant: DEFAULT_PERF for variant in VARIANTS} else: self.perfs = { variant: perfs[variant] if variant in perfs else DEFAULT_PERF for variant in VARIANTS } self.enabled = enabled self.fen960_as_white = None # last game played self.tv = None # lobby chat spammer time out (10 min) self.silence = 0 # purge inactive anon users after ANON_TIMEOUT sec if self.anon and self.username not in RESERVED_USERS: self.remove_task = asyncio.create_task(self.remove())
async def test_tournament_without_players(self): self.app["db"] = None tid = id8() self.tournament = ArenaTestTournament(self.app, tid, before_start=1.0 / 60.0, minutes=2.0 / 60.0) self.app["tournaments"][tid] = self.tournament self.assertEqual(self.tournament.status, T_CREATED) await asyncio.sleep((self.tournament.before_start * 60) + 0.1) self.assertEqual(self.tournament.status, T_STARTED) await asyncio.sleep((self.tournament.minutes * 60) + 0.1) self.assertEqual(self.tournament.status, T_FINISHED) await self.tournament.clock_task
async def test_tournament_pairing_5_round_SWISS(self): self.app["db"] = None NB_PLAYERS = 15 NB_ROUNDS = 5 tid = id8() self.tournament = SwissTestTournament(self.app, tid, before_start=0, rounds=NB_ROUNDS) self.app["tournaments"][tid] = self.tournament await self.tournament.join_players(NB_PLAYERS) await self.tournament.clock_task self.assertEqual(self.tournament.status, T_FINISHED) self.assertEqual( [len(player.games) for player in self.tournament.players.values()], NB_PLAYERS * [NB_ROUNDS], )
async def test_tournament_players(self): self.app["db"] = None NB_PLAYERS = 15 tid = id8() self.tournament = ArenaTestTournament(self.app, tid, before_start=0, minutes=0) self.app["tournaments"][tid] = self.tournament await self.tournament.join_players(NB_PLAYERS) self.assertEqual(len(self.tournament.leaderboard), NB_PLAYERS) withdrawn_player = next(iter(self.tournament.players)) await self.tournament.withdraw(withdrawn_player) self.assertNotIn(withdrawn_player, self.tournament.leaderboard) self.assertEqual(len(self.tournament.players), NB_PLAYERS) self.assertEqual(len(self.tournament.leaderboard), NB_PLAYERS - 1) await self.tournament.clock_task self.assertEqual(self.tournament.status, T_FINISHED)
def __init__(self): self.username = "******" + id8() self.seeks = [] self.playing = False
from newid import id8 logging.basicConfig(level=logging.DEBUG) URI = os.getenv("URI", "http://127.0.0.1:8080") DEV = ("heroku" in URI) or URI.startswith("http:") BR_EXTENSION = ".br" if URI.startswith("https") else "" REDIRECT_PATH = "/oauth" # path of oauth callback in app # lichess.org OAuth Apps Callback URL: https://pychess-variants.herokuapp.com/oauth REDIRECT_URI = URI + REDIRECT_PATH # client app id and secret from lichess.org CLIENT_ID = os.getenv("CLIENT_ID", "pychess") CLIENT_SECRET = os.getenv("CLIENT_SECRET", id8())[:8] LICHESS_OAUTH_AUTHORIZE_URL = 'https://lichess.org/oauth' LICHESS_OAUTH_TOKEN_URL = 'https://lichess.org/api/token' LICHESS_ACCOUNT_API_URL = 'https://lichess.org/api/account' # secret_key for session encryption # key must be 32 url-safe base64-encoded bytes FERNET_KEY = os.getenv("FERNET_KEY", string.ascii_letters[:42] + "_=") SECRET_KEY = base64.urlsafe_b64decode(FERNET_KEY) MAX_AGE = 3600 * 24 * 365 MONGO_HOST = os.getenv("MONGO_HOST", "mongodb://127.0.0.1:27017") MONGO_DB_NAME = "pychess-variants" BOT_TOKENS = json.loads(os.getenv("BOT_TOKENS", "{}"))