如何为基于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
相关产品推荐
相关产品推荐

