Search code examples
discorddiscord.py

How can I make the interaction continous by constantly waiting user input?


I found this flag code online, but i would like to make it loop by starting another game after one finishes. How do I keep the bot in the context and keep waiting for inputs?

@bot.command(name='flags', description='Play a flag guessing game')
async def flag_game(ctx:commands.Context):
    """Start a flag guessing game."""
    # Randomly select a flag from the list.
    random_flag = random.choice(list(flags.keys()))

    # Send a "Drawing..." message with an emoji.
    drawing_message = await ctx.send("Drawing... :checkered_flag:")
    await ctx.reply("Flag Game Started")
    await ctx.channel.purge(limit=1)

    # Wait for 3 seconds.
    await asyncio.sleep(3)

    # Edit the message to show the flag.
    flag_emoji = flags[random_flag]
    embed = discord.Embed(title='Flag Game', description=f"Here is the flag of one of the countries. What is the name of this country?")
    embed.add_field(name="Flag:", value=flag_emoji, inline=False)
    await drawing_message.edit(content=None, embed=embed)

    # Wait for the user's response.
    try:
        response = await bot.wait_for("message", check=lambda m: m.author == ctx.author, timeout=30.0)

        # Check the response, ignoring case.
        if response.content.lower() == random_flag.lower():
            await ctx.send(f"Congratulations! Correct answer. It's the flag of {random_flag}.")  
        else:
            await ctx.send(f"Sorry, that's not the correct answer. The correct answer is {random_flag}.")

    except asyncio.TimeoutError:
        await ctx.send("Time for a response has expired. Game over.")
        embed.add_field(name="Flag:", value=flag_emoji, inline=False)
        await drawing_message.edit(content=None, embed=embed)
    else:
        return

It runs perfectly fine, but i would like to make it continuous by constantly starting a new game after one finishes.


Solution

  • If you are trying to bot to keep waiting for message events you already got that in your code.

    response = await bot.wait_for("message", check=lambda m: m.author == ctx.author, timeout=30.0)

    I just wrapped it in a while loop with game_on boolean.

    @bot.command(name='flags', description='Play a flag guessing game.')
    async def flag_game(ctx:commands.Context):
        game_on = True
    
        # Send a "Drawing..." message with an emoji.
        drawing_message = await ctx.send("Drawing... :checkered_flag:")
        await ctx.reply("Flag Game Started")
        await ctx.channel.purge(limit=1)
    
        # Wait for 3 seconds.
        await asyncio.sleep(3)
    
        # Keep playing until game is over
        while game_on:
            random_flag = random.choice(list(flags.keys())) #Pick random every turn
            flag_emoji = flags[random_flag]
            embed = discord.Embed(title='Flag Game', description=f"Here is the flag of one of the countries. What is the name of this country?")
            embed.add_field(name="Flag:", value=flag_emoji, inline=False)
            await ctx.send(embed=embed)# drawing_message.edit(content=None, embed=embed)
    
            # Wait for the user's response.
            try:
                response = await bot.wait_for("message", check=lambda m: m.author == ctx.author, timeout=30.0)
    
                # Check the response, ignoring case.
                if response.content.lower() == random_flag.lower():
                    await ctx.send(f"Congratulations! Correct answer. It's the flag of {random_flag}.")
                elif response.content.lower() == "exit":
                    await ctx.send("Exiting the game.")
                    game_on = False
                    continue
                else:
                    await ctx.send(f"Sorry, that's not the correct answer. The correct answer is {random_flag}.")
            except asyncio.TimeoutError:
                await ctx.send("Time for a response has expired. Game over.")
                game_on = False
                continue
    

    Now the game exits when you type "exit" or 30 seconds passes without message.

    Accepting the answer closes the question.