如何修复Python Discord石头剪刀布机器人无法识别任意反应的问题
修复后的Discord石头剪刀布机器人代码
import discord import random import asyncio TOKEN = '替换为你自己的机器人TOKEN' # 游戏基础配置 ALLOWED_EMOJIS = {'🪨', '📰', '✂️'} EMOJI_TO_CHOICE = { '🪨': '石头', '📰': '布', '✂️': '剪刀' } # 胜负规则:(用户选择, 机器人选择) 存在该配对则用户获胜 WIN_PAIRS = { ('石头', '剪刀'), ('剪刀', '布'), ('布', '石头') } # 适配discord.py v2+ 权限要求,使用前需在Discord开发者后台开启Message Content Intent client = discord.Client(intents=discord.Intents.default()) @client.event async def on_ready(): print(f'已登录为 {client.user}') @client.event async def on_message(message): # 忽略机器人自身发送的消息 if message.author == client.user: return if message.content.lower() == 'p!rps': channel = message.channel # 保存游戏提示消息对象,用于后续校验反应是否针对该消息 game_msg = await channel.send('欢迎来玩石头剪刀布!请对这条消息反应对应的表情参与游戏:\n🪨 = 石头 | 📰 = 布 | ✂️ = 剪刀') # 统一校验逻辑:发起游戏的用户 + 合法表情 + 反应作用于游戏提示消息 def check(reaction, user): return user == message.author and str(reaction.emoji) in ALLOWED_EMOJIS and reaction.message.id == game_msg.id try: reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check) except asyncio.TimeoutError: await channel.send('游戏超时,请重新输入 `p!rps` 开始游戏。') return # 解析用户选择、生成机器人随机选择 user_choice = EMOJI_TO_CHOICE[str(reaction.emoji)] bot_choice = random.choice(list(EMOJI_TO_CHOICE.values())) # 胜负判定 if user_choice == bot_choice: result = '平局!' elif (user_choice, bot_choice) in WIN_PAIRS: result = '你赢了!' else: result = '我赢了!' # 输出游戏结果 await channel.send(f'你选择了{user_choice},我选择了{bot_choice}。') await channel.send(result) client.run(TOKEN)
主要修改点
- 合并了原代码多次独立的反应监听逻辑,单次监听就支持匹配所有合法游戏表情,用户可以任意选择表情触发游戏,无需按固定顺序操作
- 新增剪刀(✂️)表情的支持,补全完整的石头剪刀布游戏规则
- 增加反应消息ID校验,避免用户在其他消息上反应误触发游戏逻辑
- 优化胜负判断逻辑,通过映射表和胜负配对集替代大量重复的if判断,代码更简洁易维护
- 修复原代码中超时提示的拼写错误
- 新增Intents权限声明,适配discord.py v2+版本的运行要求,避免启动报错
- 统一游戏配置为常量,后续修改表情、规则无需调整业务逻辑
内容的提问来源于stack exchange,提问作者TheFeatherMan
相关产品推荐
相关产品推荐

