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

如何创建整合扫雷与掷币命令的Discord机器人main.py文件

解决Discord机器人同时运行扫雷和掷币命令的问题

问题根源

  1. mines_game.py末尾的bot.run(BOTTOKEN)会在被导入时直接执行,导致运行gambling_bot.py时实际启动的是扫雷的Bot实例
  2. 两个文件各自创建独立的Bot/Client实例,无法同时运行,正确做法是使用Discord.py的Cog系统整合所有命令

步骤1:修改mines_game.py为Cog格式

移除独立的Bot实例和bot.run,将命令封装到Cog类中:

import discord
import random
from discord.ext import commands
from keys import *

class MinesGame(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.games = {}  # 游戏状态存储到类内部

    @commands.command()
    async def mines(self, ctx):
        message_data = self.games.get(ctx.author.id)
        if message_data:
            if message_data.get('game_over', False):
                grid_message = ':black_large_square:  A     B      C      D       E\n'
                for number in ['1', '2', '3', '4', '5']:
                    row = [f'{number} ']
                    for letter in ['A', 'B', 'C', 'D', 'E']:
                        row.append(':blue_square:')
                    grid_message += '   '.join(row) + '\n'
                message = await ctx.send(grid_message)
                self.games[ctx.author.id] = {
                    'message_id': message.id,
                    'grid': {},
                    'game_over': False
                }
                for letter in ['A', 'B', 'C', 'D', 'E']:
                    for number in ['1', '2', '3', '4', '5']:
                        self.games[ctx.author.id]['grid'][letter + number] = {
                            'status': ':blue_square:',
                            'updated': False
                        }
            else:
                message = await ctx.channel.fetch_message(message_data['message_id'])
                grid_message = ':black_large_square:  A     B      C      D       E\n'
                for number in ['1', '2', '3', '4', '5']:
                    row = [f'{number} ']
                    for letter in ['A', 'B', 'C', 'D', 'E']:
                        row.append(message_data['grid'][letter + number]['status'])
                    grid_message += '   '.join(row) + '\n'
                await message.edit(content=grid_message)
        else:
            grid_message = ':black_large_square:  A     B      C      D       E\n'
            for number in ['1', '2', '3', '4', '5']:
                row = [f'{number} ']
                for letter in ['A', 'B', 'C', 'D', 'E']:
                    row.append(':blue_square:')
                grid_message += '   '.join(row) + '\n'
            message = await ctx.send(grid_message)
            self.games[ctx.author.id] = {
                'message_id': message.id,
                'grid': {},
                'game_over': False
            }
            for letter in ['A', 'B', 'C', 'D', 'E']:
                for number in ['1', '2', '3', '4', '5']:
                    self.games[ctx.author.id]['grid'][letter + number] = {
                        'status': ':blue_square:',
                        'updated': False
                    }

    @commands.command(aliases=['u'])
    async def update(self, ctx, *squares: str):
        if self.games.get(ctx.author.id, {}).get('game_over', False):
            await ctx.send(f"{ctx.author.mention} 游戏已结束!使用 !mines 重新开始。")
            return

        message_data = self.games.get(ctx.author.id)
        if not message_data or 'message_id' not in message_data:
            await ctx.send(f"{ctx.author.mention} 你还未启动扫雷游戏!")
            return

        if 'grid' not in message_data:
            message_data['grid'] = {}
            for letter in ['A', 'B', 'C', 'D', 'E']:
                for number in ['1', '2', '3', '4', '5']:
                    message_data['grid'][letter + number] = {
                        'status': ':blue_square:',
                        'updated': False
                    }

        for square in squares:
            square = square.upper()
            if len(square) < 2 or square[0] not in ['A', 'B', 'C', 'D', 'E'] or square[1] not in ['1', '2', '3', '4', '5']:
                await ctx.send(f"{ctx.author.mention} 无效格子 '{square}'!")
                continue
            if message_data['grid'][square]['updated']:
                await ctx.send(f"{ctx.author.mention} 每个格子只能操作一次!")
                continue

            message_data['grid'][square]['updated'] = True
            if random.random() < 0.2:
                message_data['grid'][square]['status'] = ':bomb:'
                message_data['game_over'] = True
                await ctx.send(f"{ctx.author.mention} 踩到炸弹了 ): 使用 !mines 重新开始")
            else:
                message_data['grid'][square]['status'] = ':green_square:'

        message = await ctx.channel.fetch_message(message_data['message_id'])
        grid_message = ':black_large_square:  A     B      C      D       E\n'
        for number in ['1', '2', '3', '4', '5']:
            row = [f'{number} ']
            for letter in ['A', 'B', 'C', 'D', 'E']:
                row.append(message_data['grid'][letter + number]['status'])
            grid_message += '   '.join(row) + '\n'
        await message.edit(content=grid_message)

async def setup(bot):
    await bot.add_cog(MinesGame(bot))

步骤2:修改gambling_bot.py为Cog格式

移除独立的Client实例和client.run,将掷币命令封装到Cog类中:

import discord
import random
from discord.ext import commands
from keys import *

class GamblingGame(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def flip(self, ctx, odds: float = 0.1):
        if not 0 <= odds <= 1:
            await ctx.send("概率值必须在0到1之间!")
            return
        result = 'heads' if random.random() < odds else 'tails'
        await ctx.send(f"The coin landed on {result}!")

async def setup(bot):
    await bot.add_cog(GamblingGame(bot))

步骤3:创建main.py作为唯一启动入口

这是机器人的核心启动文件,负责加载所有游戏模块:

import discord
from discord.ext import commands
from keys import *

# 配置Intents(必须开启消息内容权限)
intents = discord.Intents.all()
intents.message_content = True

# 创建唯一的Bot实例
bot = commands.Bot(command_prefix='!', intents=intents)

@bot.event
async def on_ready():
    print(f'Logged in as {bot.user}')
    # 加载所有游戏模块
    await bot.load_extension('mines_game')
    await bot.load_extension('gambling_bot')
    print("所有游戏模块已加载完成")

# 启动机器人
bot.run(BOTTOKEN)

注意事项

  1. 确保Discord开发者平台中,你的机器人已开启Message Content Intent权限
  2. 三个文件需放在同一目录下,keys.py文件包含正确的BOTTOKEN
  3. 运行时仅需执行python main.py,不要单独运行mines_game.py或gambling_bot.py

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:17:15