def setUpClass(cls): cls.round = Round(round_id=1) cls.ctx = QueueContext(cls.round) cls.p1 = Player(discord_id=1, name="Player_1") cls.p2 = Player(discord_id=2, name="Player_2") cls.p3 = Player(discord_id=3, name="Player_3") cls.p4 = Player(discord_id=4, name="Player_4") cls.t1 = Team(team_id=1, name="Team_1_2", player_one=cls.p1, player_two=cls.p2) cls.t2 = Team(team_id=2, name="Team_3_4", player_one=cls.p3, player_two=cls.p4) cls.t3 = Team(team_id=3, name="Team_1_3", player_one=cls.p1, player_two=cls.p3) cls.r = Result(result_id=1, team=cls.t1, points=0) cls.m1 = Match(match_id=1, round=cls.round, team_one=cls.r, team_two=cls.r) cls.m2 = Match(match_id=2, round=cls.round, team_one=cls.r, team_two=cls.r)
def setUpClass(cls): cls.round = Round(round_id=1) cls.principal = get_principal(cls.round, Config()) cls.p1 = Player(discord_id=1, name="Player_1") cls.p2 = Player(discord_id=2, name="Player_2") cls.p3 = Player(discord_id=3, name="Player_3") cls.p4 = Player(discord_id=4, name="Player_4") cls.t1 = Team(team_id=1, name="Team_1_2", player_one=cls.p1, player_two=cls.p2, elo=1000) cls.t2 = Team(team_id=2, name="Team_3_4", player_one=cls.p3, player_two=cls.p4, elo=1000) cls.r1 = Result(result_id=1, team=cls.t1, points=3.5, delta=0) cls.r2 = Result(result_id=2, team=cls.t2, points=3.5, delta=0) cls.m1 = Match(match_id=1, round=cls.round, team_one=cls.r1, team_two=cls.r2)
def setUpClass(cls): cls.db = Database("tests/full_mockdb.sqlite3") cls.mm = MatchMaker(Config(), cls.db, Round(round_id=1)) cls.p1 = Player(discord_id=1, name="Player_1") cls.p2 = Player(discord_id=2, name="Player_2") cls.p3 = Player(discord_id=3, name="Player_3") cls.p4 = Player(discord_id=4, name="Player_4") cls.t1 = Team(team_id=1, name="Team_1_2", player_one=cls.p1, player_two=cls.p2) cls.t2 = Team(team_id=2, name="Team_3_4", player_one=cls.p3, player_two=cls.p4) cls.t3 = Team(team_id=3, name="Team_1_3", player_one=cls.p1, player_two=cls.p3) cls.t4 = Team(team_id=4, name="Team_2_4", player_one=cls.p2, player_two=cls.p4)
def format_team(query): tid, tname, p1id, p1name, p2id, p2name, delta = query elo = ctx.bot.mm.config.base_elo + delta return Team( team_id=tid, name=tname, player_one=Player(discord_id=p1id, name=p1name), player_two=Player(discord_id=p2id, name=p2name), elo=elo, )
async def result(self, ctx, result: ToMatchResult): """ insert a result for a match """ current = Player(ctx.message.author.id, ctx.message.author.name) mm = ctx.bot.mm match = mm.get_match_of_player(current) if match is None: message = ctx.bot.fmterr("You're not in a game!") await ctx.message.channel.send(content=message, reference=ctx.message) return result.match_id = match.match_id assert result.team_one is not None assert result.team_two is not None assert match.team_one is not None assert match.team_two is not None result.team_one.team = match.team_one.team result.team_two.team = match.team_two.team err = mm.insert_result(result) if isinstance(err, error.DuplicateResultError): message = ctx.bot.fmterr( f"Result for match '{match.match_id}' has already been entered!" ) await ctx.message.channel.send(content=message, reference=ctx.message) return if isinstance(err, Error): raise err message = ctx.bot.fmtok( f"Successfully registered result for match {match.match_id}" ) await ctx.message.channel.send(content=message, reference=ctx.message)
async def queue(self, ctx, *, team: ToRegisteredTeam): """ queue a team with its qualified name """ mm = ctx.bot.mm current = Player(ctx.message.author.id, ctx.message.author.name) if not team.has_player(current): message = ctx.bot.fmterr("You are not part of this team!") await ctx.message.channel.send(content=message, reference=ctx.message) return err = mm.queue_team(team) if isinstance(err, error.AlreadyQueuedError): err_player = err.player err_team = err.team message = ctx.bot.fmterr( f"'{err_player.name}' is queuing in team '{err_team.name}'!" ) await ctx.message.channel.send(content=message, reference=ctx.message) return if isinstance(err, Error): raise err message = ctx.bot.fmtok(f"Successfully queued {team}!") await ctx.message.channel.send(content=message, reference=ctx.message)
async def register(self, ctx, teammate: ToPlayer, *, team_name: str): """ register the caller with his teammate as a new team """ bot = ctx.bot current = Player(ctx.message.author.id, ctx.message.author.name) if current.discord_id == teammate.discord_id: message = bot.fmterr( f"{current.name} you can't play with yourself!") await ctx.message.channel.send(content=message, reference=ctx.message) return if not bot.db.exists(current, "RegisterUnregisteredPlayer"): assert bot.db.insert(current) if not bot.db.exists(teammate, "RegisterUnregisteredPlayer"): assert bot.db.insert(teammate) if bot.db.exists(Team(name=team_name), "IsDuplicateTeamName"): message = f"'{team_name}' is already present, use a different name!" message = bot.fmterr(message) await ctx.message.channel.send(content=message, reference=ctx.message) return query = ColumnQuery( QueryKind.EXISTS, "team", ["name"], Where( Or( And( Eq("player_one", current.discord_id), Eq("player_two", teammate.discord_id), ), And( Eq("player_one", teammate.discord_id), Eq("player_two", current.discord_id), ), )), ) execq = bot.db.execute(query, "PlayerHasTeam") assert execq is not None if execq.fetchone()[0] == 1: query.kind = QueryKind.SELECT cursor = bot.db.execute(query, "FetchTeamName") assert cursor is not None team_name = cursor.fetchone()[0] message = bot.fmterr( f"'{current.name}' is already in a team with '{teammate.name}' ('{team_name}')!" ) await ctx.message.channel.send(content=message, reference=ctx.message) else: assert bot.db.insert( Team(name=team_name, player_one=current, player_two=teammate)) message = bot.fmtok( f"registered {current.name}'s and {teammate.name}'s team {team_name}" ) await ctx.message.channel.send(content=message, reference=ctx.message)
async def teams(self, ctx, who: Optional[ToPlayer] = None): """ send the list of teams for a player """ current = Player(ctx.message.author.id, ctx.message.author.name) if who is not None: current = who query = ColumnQuery( QueryKind.SELECT, "team_details_with_delta", "*", [ Where( Or( Eq("player_one_id", current.discord_id), Eq("player_two_id", current.discord_id), )), ], ) def format_team(query): tid, tname, _, p1name, _, p2name, delta = query elo = ctx.bot.mm.config.base_elo + delta return f"{tid} | {tname}({elo}): {p1name} & {p2name}" execq = ctx.bot.db.execute(query, "FetchTeamsWithElo") assert execq is not None content = "\n".join(map(format_team, execq.fetchall())) message = f"""```{content}\n```""" await ctx.message.channel.send(content=message, reference=ctx.message)
def test_all_teams_for_player(self): current = Player(discord_id=1, name="Player_1") query = ColumnQuery( QueryKind.SELECT, "team", [ "team.team_id", "team.name", "p1.discord_id", "p1.name", "p2.discord_id", "p2.name", ], [ InnerJoin(Alias("player", "p1"), on=Eq("p1.discord_id ", "team.player_one")), InnerJoin(Alias("player", "p2"), on=Eq("p2.discord_id ", "team.player_two")), Where( Or( Eq("player_one", current.discord_id), Eq("player_two", current.discord_id), )), ], ) res = self.db.execute(query, "TestAllTeamsForPlayer").fetchall() for result in res: p1id = result[2] p2id = result[4] assert current.discord_id == p1id or current.discord_id == p2id
def test_queue_trigger(self): self.games.clear() self.qctx.clear() t1 = Team( team_id=42, elo=1000, player_one=Player(discord_id=1), player_two=Player(discord_id=2), ) t2 = Team( team_id=69, elo=1000, player_one=Player(discord_id=3), player_two=Player(discord_id=4), ) evmap = EventMap.new() evmap.register(MatchTriggerHandler(self.config, self.games, evmap)) evmap.register( EqHandler( tag=1, key="round", expect=Round(round_id=self.qctx.round.round_id), kind=EventKind.ROUND_START, persistent=False, )) prev_round = self.qctx.round.round_id self.qctx.queue.append(t1) q1 = QueueEvent(self.qctx, t1) assert not isinstance(evmap.handle(q1), HandlingError) self.qctx.queue.append(t2) q2 = QueueEvent(self.qctx, t2) assert not isinstance(evmap.handle(q2), HandlingError) assert evmap[EventKind.RESULT][0].tag == prev_round assert self.qctx.round.round_id == prev_round + 1 assert self.qctx.is_empty() assert len(evmap[EventKind.QUEUE]) == 1 assert len(evmap[EventKind.ROUND_START]) == 0
def generate(db): players = [] for i in range(1, PLAYERS + 1): player = Player(i, f"Player_{i}") assert db.insert(player) players.append(player) print(f"-- Generated {len(players)} players") teams = [] for i, team in enumerate(combinations(players, 2), 1): one, two = team team = Team( team_id=i, name=f"Team_{one.discord_id}_{two.discord_id}", player_one=one, player_two=two, ) teams.append(team) assert db.insert(team) print(f"-- Generated {len(teams)} teams") assert len(teams) == no_teams() prev_round = None matches = 0 prev_time = datetime.now() for i, team in enumerate(combinations(teams, 2), 1): if (i - 1) % ROUND_EVERY == 0: start = prev_time prev_time += timedelta(minutes=15) prev_round = Round( round_id=i // ROUND_EVERY + 1, start_time=start, end_time=prev_time, participants=4, ) assert db.insert(prev_round) res1 = Result(result_id=i, team=team[0], points=7, delta=1.0) res2 = Result(result_id=i + 1, team=team[1], points=6, delta=-1.0) assert db.insert(res1) assert db.insert(res2) assert db.insert( Match(match_id=i, round=prev_round, team_one=res1, team_two=res2, odds_ratio=1)) matches = i assert matches == no_matches() print(f"-- Generated {matches} matches") print(f"-- Generated {matches//ROUND_EVERY} rounds")
def test_select_name_of_team(self): one = Player(discord_id=1, name="Player_1") two = Player(discord_id=2, name="Player_2") query = ColumnQuery( QueryKind.SELECT, "team", ["name"], Where( Or( And( Eq("player_one", one.discord_id), Eq("player_two", two.discord_id), ), And( Eq("player_one", two.discord_id), Eq("player_two", one.discord_id), ), )), ) name = self.db.execute(query, "RegisterFetchTeamName").fetchone()[0] name_one = f"Team_{one.discord_id}_{two.discord_id}" name_two = f"Team_{two.discord_id}_{one.discord_id}" assert name == name_one or name == name_two
def setUpClass(cls): cls.round = Round(round_id=1) cls.t1 = Team( team_id=42, elo=1000, player_one=Player(discord_id=1), player_two=Player(discord_id=2), ) cls.t2 = Team( team_id=69, elo=1000, player_one=Player(discord_id=3), player_two=Player(discord_id=4), ) m = Match( match_id=1, round=cls.round, team_one=Result(result_id=1, team=cls.t1), team_two=Result(result_id=2, team=cls.t2), ) cls.principal = get_principal(cls.round, Config()) cls.games = Games( {cls.round.round_id: InGameContext(cls.principal, [m])})
async def dequeue(self, ctx): """ dequeue a queued team """ current = Player(ctx.message.author.id, ctx.message.author.name) mm = ctx.bot.mm if not mm.has_queued_player(current): message = ctx.bot.fmterr("You don't have a queued team!") await ctx.message.channel.send(content=message, reference=ctx.message) return team = mm.qctx[current] assert team is not None err = mm.dequeue_team(team) if isinstance(err, Error): raise err message = ctx.bot.fmtok(f"Successfully dequeued {team.name}({team.elo})") await ctx.message.channel.send(content=message, reference=ctx.message)
async def convert(self, ctx, argument): member = await super().convert(ctx, argument) return Player(member.id, member.name)
def test_load_player(self): for i in range(1, PLAYERS + 1): player = self.db.load(Player(discord_id=i)) assert player is not None assert player.discord_id == i assert player.name == f"Player_{i}"
def test_exists_player(self): for i in range(1, PLAYERS + 1): assert self.db.exists(Player(discord_id=i))
def setUpClass(cls): cls.db = Database("tests/full_mockdb.sqlite3") cls.p1 = Player(discord_id=1, name="aa") cls.p2 = Player(discord_id=1, name="bb") cls.p3 = Player(discord_id=2, name="aa")