我正在学习用 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 命令)可以提交他们的选择,这将非常有用(并且不会造成混淆)
答案 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
语句之后是随机化机器人选择以及检查两个选择结果的代码。 (您确定结果的代码可能与我的不同;我只是编写了我的方法,因此整个代码示例都有意义。)