You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何限制Python编写的Discord猜数字游戏机器人同一时间仅单用户使用

单用户游玩限制实现方案(适合初学者)

核心实现逻辑非常简单,只需要加2个全局变量做游戏状态标记即可,不需要用到复杂的并发锁技术,代码改动很小:

需要修改的核心点

  • 删掉原来嵌套在numpuz命令内部的num命令定义,嵌套注册命令会触发重复注册的BUG,两个命令都要放在全局位置
  • 新增2个全局变量:
    • game_running:布尔类型,标记当前是否有正在进行的游戏
    • current_player_id:数值类型,记录当前正在玩游戏的用户Discord ID
  • 启动游戏的numpuz命令入口先做校验:如果已有游戏在进行,直接返回提示,不开启新游戏
  • 猜数字的num命令入口做两层校验:没有正在进行的游戏就提示先启动游戏;不是当前正在玩的用户就提示无权操作
  • 游戏结束(玩家赢/输光生命)时重置两个全局标记,释放游戏权限

修改后的完整代码

import keep_alive
import discord
import os
from discord.ext import commands
import random
import sys

client = commands.Bot(command_prefix=".")

# 新增的全局状态变量
game_running = False
current_player_id = None
# 游戏参数
target_num = None
lives = None

@client.event
async def on_ready():
    print("The bot is online")

@client.command()
async def numpuz(ctx):
    global game_running, current_player_id, target_num, lives
    # 先判断有没有正在进行的游戏
    if game_running:
        await ctx.send("当前有其他用户正在游玩,请等对方结束后再尝试哦")
        return
    # 没有游戏就初始化游戏数据
    game_running = True
    current_player_id = ctx.author.id
    target_num = random.randint(1, 100)
    lives = 8
    print(f"新游戏开启,目标数字:{target_num},玩家ID:{current_player_id}")
    await ctx.send("游戏开始!请输入1-100之间的数字开始猜哦")

@client.command()
async def num(ctx, guessednumber):
    global game_running, current_player_id, target_num, lives
    # 第一层校验:有没有正在进行的游戏
    if not game_running:
        await ctx.send("当前没有正在进行的游戏,请先发送 .numpuz 开启游戏")
        return
    # 第二层校验:是不是当前正在玩的用户
    if ctx.author.id != current_player_id:
        await ctx.send("现在不是你在游玩哦,等当前玩家结束后再参与吧")
        return
    # 转成整数
    guess = int(guessednumber)
    # 猜数字逻辑
    if guess > target_num:
        await ctx.send("猜大了,再试一次!")
        lives -= 1
    elif guess < target_num:
        await ctx.send("猜小了,再试一次!")
        lives -= 1
    else:
        await ctx.send(f"恭喜你猜对了!你还剩 {lives} 条生命")
        # 重置游戏状态
        game_running = False
        current_player_id = None
        target_num = random.randint(1, 100)
        return
    # 判断生命是否用完
    if lives <= 0:
        await ctx.send(f"你已经用完了所有生命,游戏失败!正确数字是 {target_num}")
        # 重置游戏状态
        game_running = False
        current_player_id = None
        target_num = random.randint(1, 100)

keep_alive.keep_alive()
client.run(os.getenv("token"))

效果说明

你可以用两个Discord账号测试:

  • 账号A发送.numpuz开启游戏后,账号B再发送.numpuz会收到游玩中的提示
  • 游戏进行中账号B发送.num 50也会收到无权操作的提示
  • 账号A赢或输结束游戏后,其他账号就可以正常开启新游戏了

内容的提问来源于stack exchange,提问作者sir_blob4534

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 04:42:03