有没有办法限制用户在使用命令后不和谐机器人读取的响应?

时间:2021-05-13 17:27:40

标签: python discord discord.py

我正在学习用 python 编写 discord 机器人,所以决定制作一个简单的石头剪刀布机器人。它目前的工作方式是用户输入 !RPS 开始游戏,然后必须输入他们的选择,机器人会回复他们是赢还是输

@bot.command(aliases = ['rps', 'RPS'])
async def rock_paper_scissors(ctx):
    global gaming
    gaming = True
    gamer = ctx.message.author.name
    await ctx.send('Pick Rock, Paper, or Scissors!')

@bot.event
async def on_message(message):
    global gaming
    global x
    x = 0
    while gaming == True:
        if message.author == bot.user:
            return
        if x > 4:
            channel = message.channel
            await message.channel.send('Too Many Bad Responses, Shutting Down')
            gaming = False
            break 
        elif str.upper(message.content) not in ['ROCK', 'PAPER', 'SCISSORS', 'R', 'P', 'S']:
            channel = message.channel
            await message.channel.send('Not A Valid Response')
            x = x + 1
            return
        else:
            response = random.choice(['Rock', 'Paper', 'Scissors'])
            if str.upper(response) == str.upper(message.content):
                channel = message.channel
                await message.channel.send(f'I picked {response}, we drew!')
                gaming = False
            elif str.upper(response) == 'PAPER' and str.upper(message.content) in ['SCISSORS', 'S']:
                channel = message.channel
                await message.channel.send(f'I picked {response}, you won!')
                gaming = False
            elif str.upper(response) == 'PAPER' and str.upper(message.content) in ['ROCK', 'R']:
                channel = message.channel
                await message.channel.send(f'I picked {response}, I won!')
                gaming = False
            elif str.upper(response) == 'ROCK' and str.upper(message.content) in ['SCISSORS', 'S']:
                channel = message.channel
                await message.channel.send(f'I picked {response}, I won!')
                gaming = False
            elif str.upper(response) == 'ROCK' and str.upper(message.content) in ['PAPER', 'P']:
                channel = message.channel
                await message.channel.send(f'I picked {response}, you won!')
                gaming = False
            elif str.upper(response) == 'SCISSORS' and str.upper(message.content) in ['ROCK', 'R']:
                channel = message.channel
                await message.channel.send(f'I picked {response}, you won!')
                gaming = False
            elif str.upper(response) == 'SCISSORS' and str.upper(message.content) in ['PAPER', 'P']:
                channel = message.channel
                await message.channel.send(f'I picked {response}, I won!')
                gaming = False
            else:
                break
    gaming = False
    await bot.process_commands(message)
    x = 0 

我遇到的问题是,如果一个用户键入 !RPS,然后第二个用户响应,即使他们没有玩游戏,机器人也会读取第二个用户的响应。有什么办法可以解决这个问题吗?

Two Users Interacting With The Bot

我计划为赢得的游戏实施“排行榜”,因此如果只有开始游戏的用户(使用 !RPS 命令)可以提交他们的选择,这将非常有用(并且不会造成混淆)

1 个答案:

答案 0 :(得分:0)

在您的 rock_paper_scissors() 函数中,您可以使用 Bot.wait_for() method。您可以创建一个检查,以验证响应的成员与调用命令的成员相同。

@bot.command(aliases = ['rps', 'RPS'])
async def rock_paper_scissors(ctx):
    await ctx.channel.send("Pick Rock, Paper, or Scissors")
    try:
        choice = await bot.wait_for(
            "message",
            timeout=60.0
            check=lambda msg: msg.author == ctx.author
        )
        choice = choice.lower().strip()[0]
        if choice not in ["r", "p", "s"]:
            await ctx.channel.send("Invalid selection")
    except asyncio.TimeoutError:
        await ctx.message.delete()
        return
    await check_result(choice)

async def check_result(user_choice):
    bot_choice = random.choice(["r", "p", "s"])
    await ctx.channel.send(f"User selected {user_choice}\nBot selected {bot_choice}")
    if bot_choice == user_choice:
        await ctx.channel.send("Result: Tie")
    elif (bot_choice, user_choice) in (("r", "s"), ("p", "r"), ("s", "p")):
        await ctx.channel.send("Result: Bot is victorious")
    elif (user_choice, bot_choice) in (("r", "s"), ("p", "r"), ("s", "p"):
        await ctx.channel.send("Result: User is victorious")

try 子句中,机器人等待 on_message() 事件,在 60.0 秒后超时(引发 asyncio.TimeoutError),并检查消息作者是否与调用的用户相同rock_paper_scissors 命令。

try/except 语句之后是随机化机器人选择以及检查两个选择结果的代码。 (您确定结果的代码可能与我的不同;我只是编写了我的方法,因此整个代码示例都有意义。)