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

如何为基于discord.ext.commands的Python Discord骰子机器人添加多骰子与混合数学运算支持?

如何为基于discord.ext.commands的Python Discord骰子机器人添加多骰子与混合数学运算支持?

嘿,我看了你的问题和现有代码,核心就是要让!r命令能解析包含多个骰子组、常数以及加减运算符的完整表达式对吧?咱们可以从正则匹配和逻辑重构入手,一步步解决这个问题:

核心思路

  • 改进正则匹配:要能捕获每个带符号的项(比如+1d6、-10、2d20),这样不管有多少个加减项都能逐个处理。
  • 逐项解析计算:对每个匹配到的项,区分是骰子组还是常数,分别计算结果并记录详细的掷骰过程(比如2d6的两次掷出值)。
  • 构建友好输出:把每个项的详情拼接起来,最后显示总和,和你想要的示例格式一致。
  • 完善错误处理:捕获无效格式、非数字输入等情况,给用户清晰的提示。

修改后的完整代码

我们直接重构!r命令,让它支持所有需求,替换你原来的rolar_dado函数即可:

import random
from discord.ext import commands
from discord import Intents
import re

intents = Intents.default()
intents.message_content = True  # 启用消息内容读取权限

bot = commands.Bot(command_prefix='!', intents=intents)

# 保留你原来的其他命令(s、m、soma_dados、p)不变,只修改rolar_dado

@bot.command(name='r')
async def rolar_dado(ctx, *, expression: str):
    try:
        # 正则表达式:匹配带符号的骰子组或常数,比如 +1d20、-5、3d6
        pattern = re.compile(r'([+-]?)(\d+d\d+|\d+)')
        matches = pattern.findall(expression)
        
        if not matches:
            await ctx.reply("```❌ 无效的表达式格式,请使用类似 1d20+1d6-10 的格式```")
            return
        
        total = 0
        roll_details = []
        
        for sign, term in matches:
            # 处理符号,默认是正号
            multiplier = 1 if sign == '+' or sign == '' else -1
            
            if 'd' in term:
                # 处理骰子组,比如 1d20、2d6
                num_dice, dice_type = map(int, term.split('d'))
                if num_dice <= 0 or dice_type <= 0:
                    await ctx.reply(f"```❌ 无效的骰子格式:{term},骰子数量和类型必须大于0```")
                    return
                
                rolls = [random.randint(1, dice_type) for _ in range(num_dice)]
                subtotal = sum(rolls) * multiplier
                total += subtotal
                
                # 构建骰子详情字符串,比如 "1d20 (10)" 或 "2d6 (4+2)"
                roll_str = '+'.join(map(str, rolls))
                detail = f"{sign}{term} ({roll_str})"
                roll_details.append(detail)
            else:
                # 处理常数,比如 10、-5
                constant = int(term) * multiplier
                total += constant
                roll_details.append(f"{sign}{term}")
        
        # 拼接最终输出,优化符号显示
        output = f"🎲 You rolled: {' + '.join(roll_details).replace('+ -', '- ')} (Total: {total})"
        await ctx.reply(f"``` {output} ```")
    
    except ValueError:
        await ctx.reply("```❌ 表达式中包含无效的数字,请检查输入格式```")
    except Exception as e:
        await ctx.reply(f"```❌ 表达式错误:{str(e)}```")

# 其他命令(s、m、soma_dados、p)保持不变

bot.run('你的Bot Token')

代码关键点解释

  • 正则表达式:([+-]?)(\d+d\d+|\d+) 会把整个表达式拆分成一个个带符号的项,比如输入1d20 + 1d6 - 2d6 + 10会被拆分为('', '1d20')、('+', '1d6')、('-', '2d6')、('+', '10')。
  • 符号处理:每个项的符号决定了它是加还是减,默认没有符号的项是正数。
  • 骰子组处理:拆分骰子数量和类型,生成随机掷骰结果,计算子总和并记录掷出的每个数值。
  • 输出格式优化:用replace('+ -', '- ')把多余的加号去掉,让输出更自然,比如把+ -2d6变成- 2d6。

测试示例

输入:!r 1d20 + 1d6 - 2d6 + 10
输出:

🎲 You rolled: 1d20 (10) + 1d6 (3) - 2d6 (4+2) + 10 (Total: 17)

这样就完全实现了你想要的功能,支持多个骰子组、加减混合运算,还能清晰展示每个项的详情和最终总和。

备注:内容来源于stack exchange,提问作者An0Mi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 12:19:33