def test_matchmaking_logic():

    game_queue.reset_queue()

    # We queue for everything except the red support
    for player_id in range(0, 9):
        game_queue.add_player(player_id, roles_list[player_id % 5], 0, 0)

        assert not find_best_game(GameQueue(0))

    # We add the last player
    game_queue.add_player(9, "SUP", 0, 0)

    game = find_best_game(GameQueue(0))

    assert game

    # We commit the game to the database
    with session_scope() as session:
        session.add(game)

    # We say player 0 won his last game on server 0
    score_game_from_winning_player(0, 0)

    # We check that everything got changed
    with session_scope() as session:
        # We recreate the game object so it’s associated with this new session
        game = session.query(Game).order_by(Game.start.desc()).first()

        for side, role in game.participants:
            participant = game.participants[side, role]

            assert participant.player.ratings[role].trueskill_mu != 25
Esempio n. 2
0
    async def games(self, ctx: commands.Context):
        """
        Creates 100 games in the database with random results
        """
        game_queue.reset_queue()

        for game_count in range(100):

            # We add the context creator as well
            game_queue.add_player(
                ctx.author.id, roles_list[4], ctx.channel.id, ctx.guild.id, name=ctx.author.display_name
            )

            # We put 15 people in the queue, but only the first ones should get picked
            for i in range(0, 15):
                game_queue.add_player(i, roles_list[i % 5], ctx.channel.id, ctx.guild.id, name=str(i))

            game = matchmaking_logic.find_best_game(GameQueue(ctx.channel.id))

            with session_scope() as session:
                session.add(game)
                winner = game.player_ids_list[int(random.random() * 10)]

            game_queue.start_ready_check([i for i in range(0, 9)] + [ctx.author.id], ctx.channel.id, 0)
            game_queue.validate_ready_check(0)

            matchmaking_logic.score_game_from_winning_player(player_id=winner, server_id=ctx.guild.id)

            await ranking_channel_handler.update_ranking_channels(self.bot, ctx.guild.id)

        await ctx.send("100 games have been created in the database")
        await queue_channel_handler.update_queue_channels(bot=self.bot, server_id=ctx.guild.id)
Esempio n. 3
0
    async def reset(self,
                    ctx: commands.Context,
                    member_or_channel: Union[discord.Member,
                                             discord.TextChannel] = None):
        """
        Resets the queue status for a channel or a player

        If no argument is given, resets the queue in the current channel
        """
        if not member_or_channel or type(
                member_or_channel) == discord.TextChannel:
            channel = ctx.channel if not member_or_channel else member_or_channel
            game_queue.reset_queue(channel.id)

            # TODO Find a way to cancel the ongoing ready-checks as they *will* bug out
            #   The current code organisation does not allow to do it easily, so maybe it’ll need some structure changes
            await ctx.send(f"Queue has been reset in {channel.name}")

        elif type(member_or_channel) == discord.Member:
            game_queue.remove_player(member_or_channel.id)
            await ctx.send(
                f"{member_or_channel.name} has been removed from all queues")

        await queue_channel_handler.update_queue_channels(
            bot=self.bot, server_id=ctx.guild.id)
def test_multiple_queues():
    game_queue.reset_queue()
    game_queue.add_player(0, roles_list[0], 0, 0, name="0")

    # This will take a few seconds
    for i in range(1000):
        GameQueue(0)
def test_multiple_queues():
    game_queue.reset_queue()
    game_queue.add_player(0, roles_list[0], 0, 0)

    # This will take at least 30s to crash because of the queue timeout
    for i in range(1000):
        GameQueue(0)
def test_duo_queue():
    game_queue.reset_queue()

    # Adding it all except last support
    for player_id in range(0, 9):
        game_queue.add_player(player_id,
                              roles_list[player_id % 5],
                              0,
                              0,
                              name=str(player_id))

    # Marking players 0 and 9 as duo
    game_queue.add_duo(0,
                       "TOP",
                       9,
                       "SUP",
                       0,
                       0,
                       first_player_name="0",
                       second_player_name="9")

    print(GameQueue(0))
    print(GameQueue(0).duos)

    assert len(GameQueue(0)) == 10
    assert len(GameQueue(0).duos) == 1

    # Removing their duo status with 0 calling !solo
    game_queue.remove_duo(0, 0)

    assert len(GameQueue(0)) == 10
    assert len(GameQueue(0).duos) == 0
def test_queue_full():
    game_queue.reset_queue()

    for player_id in range(0, 10):
        game_queue.add_player(player_id,
                              roles_list[player_id % 5],
                              0,
                              0,
                              name=str(player_id))

    assert len(GameQueue(0)) == 10

    # We queue our player 0 in channel 1, which he should be allowed to do
    game_queue.add_player(0, roles_list[0], 1, 0, name="0")
    assert len(GameQueue(1)) == 1

    # We queue our player 0 for every other role in channel 0
    for role in roles_list:
        game_queue.add_player(0, role, 0, 0, name="0")

    assert len(GameQueue(
        0)) == 14  # Every role should count as a different QueuePlayer

    # Assuming our matchmaking logic found a good game (id 0)
    game_queue.start_ready_check(list(range(0, 10)), 0, 0)
    assert len(
        GameQueue(0)
    ) == 0  # Player 0 should not be counted in queue for any role anymore

    # Our player 0 in channel 1 should not be counted in queue either
    assert len(GameQueue(1)) == 0

    # We check that our player 0 is not allowed to queue in other channels
    with pytest.raises(game_queue.PlayerInReadyCheck):
        game_queue.add_player(0, roles_list[0], 2, 0, name="0")

    # We cancel the ready check and drop player 0 from all queues on the server
    game_queue.cancel_ready_check(ready_check_id=0,
                                  ids_to_drop=[0],
                                  server_id=0)

    assert len(GameQueue(0)) == 9

    # We check player 0 got dropped from queue 1 too
    assert len(GameQueue(1)) == 0

    # We queue again, with player 10
    game_queue.add_player(10, roles_list[0], 0, 0, name="10")

    # We start and validate the ready check (message id 1)
    game_queue.start_ready_check(list(range(1, 11)), 0, 1)
    game_queue.validate_ready_check(1)

    # We verify that both queues are empty
    assert len(GameQueue(0)) == 0
    assert len(GameQueue(1)) == 0
    def unmark_queue_channel(self, channel_id):
        game_queue.reset_queue(channel_id)

        with session_scope() as session:
            channel_query = session.query(ChannelInformation).filter(ChannelInformation.id == channel_id)
            channel_query.delete(synchronize_session=False)

        self._queue_channels = [c for c in self._queue_channels if c.id != channel_id]

        queue_logger.info(f"Unmarked {channel_id} as a queue channel")
def test_queue_remove():
    game_queue.reset_queue()

    game_queue.add_player(0, roles_list[0], 0, 0, name="0")

    assert len(GameQueue(0)) == 1

    # We queue our player 0 in channel 1, which he should be allowed to do
    game_queue.remove_player(0, 0)

    assert len(GameQueue(0)) == 0
Esempio n. 10
0
    def daily_jobs(self):
        """
        Runs a timer every 60 seconds, triggering jobs at the appropriate minute mark
        """
        threading.Timer(60, self.daily_jobs).start()
        now = datetime.now()

        if now.strftime("%H:%M") == QUEUE_RESET_TIME:
            with session_scope() as session:
                server_config = get_server_config(server_id=self.guilds[0].id, session=session)
                if server_config.config.get('queue_reset'):
                    game_queue.reset_queue()
                    self.loop.create_task(queue_channel_handler.update_queue_channels(bot=self, server_id=None))
Esempio n. 11
0
    def remove_queue_channel(self, channel_id):
        game_queue.reset_queue(channel_id)

        with session_scope() as session:
            reset_queue(channel_id)

            channel_query = session.query(ChannelInformation).filter(
                ChannelInformation.id == channel_id)

            channel_query.delete(synchronize_session=False)

        self._queue_channels = [
            c for c in self._queue_channels if c.id != channel_id
        ]
def test_duo_matchmaking():
    game_queue.reset_queue()

    # Playing 100 games with random outcomes and making sure 0 and 9 are always on the same team
    for game_count in range(100):

        # We queue for everything except the red support
        for player_id in range(0, 9):
            game_queue.add_player(player_id,
                                  roles_list[player_id % 5],
                                  0,
                                  0,
                                  name=str(player_id))

        # We add the last player as duo with player 0
        game_queue.add_duo(
            0,
            "TOP",
            9,
            "SUP",
            0,
            0,
            second_player_name="9",
            first_player_name="0",
        )

        game = find_best_game(GameQueue(0))

        player_0 = next(p for p in game.participants.values()
                        if p.player_id == 0)
        player_9 = next(p for p in game.participants.values()
                        if p.player_id == 9)

        assert player_0.side == player_9.side

        with session_scope() as session:
            session.add(game)
            winner = game.player_ids_list[int(random.random() * 10)]

        game_queue.start_ready_check([i for i in range(0, 10)], 0, 0)
        game_queue.validate_ready_check(0)

        score_game_from_winning_player(player_id=winner, server_id=0)
def test_matchmaking_logic_priority():
    """
    Making sure players who spent more time in queue will be considered first
    """
    game_queue.reset_queue()

    # TODO LOW PRIO Rewrite the test to make it properly test age-based matchmaking, even with an empty DB
    #   I think even without age-based matchmaking it could pass at the moment, since on an empty DB the first
    #   tested game has a perfect 50% evaluation. Won’t happen after other tests though so ok atm

    # We queue for everything, with 0, 1, 2, 3 being top, 4, 5, 6, 7 being jgl, ...
    for player_id in range(0, 20):
        game_queue.add_player(player_id, roles_list[int(player_id / 4 % 5)], 0,
                              0)

    game = find_best_game(GameQueue(0))
    print(game.blue_expected_winrate)

    # Assert we chose 0, 1, 4, 5, 8, 9, 13, 13, 16, 17 players
    for participant in game.participants.values():
        assert participant.player_id % 4 < 2
Esempio n. 14
0
    async def reset(
        self, ctx: commands.Context, member_or_channel: Union[discord.Member, discord.TextChannel] = None
    ):
        """
        Resets the queue status for a channel or a player

        If no argument is given, resets the queue in the current channel
        """
        # TODO LOW PRIO RESEND THE QUEUE (but it’s a QueueCog function, so will need some code rearrangement)

        if not member_or_channel or type(member_or_channel) == discord.TextChannel:
            channel = ctx.channel if not member_or_channel else member_or_channel
            game_queue.reset_queue(channel.id)

            await ctx.send(f"Queue has been reset in {channel.name}")
            await queue_channel_handler.update_server_queues(bot=self.bot, server_id=ctx.guild.id)

        elif type(member_or_channel) == discord.Member:
            game_queue.remove_player(member_or_channel.id)
            await ctx.send(f"{member_or_channel.name} has been removed from all queues")
            await queue_channel_handler.update_server_queues(bot=self.bot, server_id=ctx.guild.id)
Esempio n. 15
0
    async def reset(self,
                    ctx: commands.Context,
                    member_or_channel: Union[discord.Member,
                                             discord.TextChannel] = None):
        """
        Resets the queue status for a channel or a player

        If no argument is given, resets the queue in the current channel
        """
        if not member_or_channel or type(
                member_or_channel) == discord.TextChannel:
            channel = ctx.channel if not member_or_channel else member_or_channel
            game_queue.reset_queue(channel.id)

            await ctx.send(f"Queue has been reset in {channel.name}")

        elif type(member_or_channel) == discord.Member:
            game_queue.remove_player(member_or_channel.id)
            await ctx.send(
                f"{member_or_channel.name} has been removed from all queues")

        await queue_channel_handler.update_queue_channels(
            bot=self.bot, server_id=ctx.guild.id)