从随机生成的数字中减去数字

问题描述 投票:0回答:1

我正在尝试在程序中实现一项功能,即用户可以使用特定的双面模具添加或减去随机生成的数字。我的代码的基础发布在这里:

import discord
import random

DND_1d20 = range(1, 21)

# Roll d20
    if message.content == ";roll 1d20":
        response = random.choice(DND_1d20)
        response_str = "You rolled {0}".format(response)
        if response_str == "You rolled 20":
            await message.channel.send("**Critical Hit!**\n You rolled 20")
        if response_str == "You rolled 1":
            await message.channel.send("**Critical Fail!**\n You rolled 1")

我希望用户能够指定骰子掷骰子“; 1d20”,但也可以从骰子中添加“; 1d20 +(x)”或减去“; 1d20-(x)”任意数字(x)生成骰子卷。逻辑看起来像这样]

-用户“; 1d20 + 2”假设生成的随机数为6。由于用户希望将2加到生成的随机数中,因此结果为8。

-机器人“您掷8”

# Roll d20
    if message.content == ";roll 1d20":
        response = random.choice(DND_1d20)
        response_str = "You rolled {0}".format(response)
        if response_str == "You rolled 20":
            await message.channel.send("**Critical Hit!**\n You rolled 20")
        if response_str == "You rolled 1":
            await message.channel.send("**Critical Fail!**\n You rolled 1")
        else:
            if message.content == "-":

我将如何去做?我真的对从哪里开始感到困惑。我认为上面的代码不正确,因为该消息必须完全是“-”。另外,由于值(x)可能是大量数字或来自用户输入的+/-号,因此如何合并值(x)?

感谢您的任何帮助!

python-3.x bots discord.py dice
1个回答
1
投票

这是一个更高级的解决方案,使用一个名为lark的库为这些骰子表达式(从lark抄录)定义语法,将这些表达式解析为语法树,然后评估这些树。使用以下字符串创建一个名为this question的文件:

dice_grammar.py

如果您不熟悉这样的语法,请不要惊慌。这说明我们可以掷骰子,加法和减法。然后,我们可以使用grammar=""" start: expr expr: add | subtract | roll | NUMBER add: expr "+" expr subtract: expr "-" expr roll: NUMBER? ("d"|"D") (NUMBER|PERCENT) NUMBER: ("0".."9")+ PERCENT: "%" %ignore " " """ 消耗解析器将生成的树:

dice_transformer.py

from lark import Transformer, v_args from random import randint class DiceTransformer(Transformer): PERCENT = lambda self, percent: 100 NUMBER = int def __init__(self): super().__init__(visit_tokens=True) @v_args(inline=True) def start(self, expr): return expr @v_args(inline=True) def expr(self, e): return e @v_args(inline=True) def add(self, left, right): return left + right @v_args(inline=True) def subtract(self, left, right): return left - right def roll(self, children): if len(children) == 1: qty = 1 size = children[0] else: qty, size = children return sum(randint(1, size) for _ in range(qty)) ,使用它们来评估用户的骰子表达式:

dice_bot.py

这使我们可以要求计算更复杂的卷,例如

from discord.ext import commands
from lark import Lark
from lark.exceptions import LarkError
from dice_grammar import grammar
from dice_transformer import DiceTransformer

bot = commands.Bot(";")

parser = Lark(grammar)
transformer = DiceTransformer()

@bot.command()
async def roll(ctx, *, expression):
    try:
        tree = parser.parse(expression)
    except LarkError:
        await ctx.send("Bad Expression")
        return
    print(tree.pretty()) # Log the roll
    result = transformer.transform(tree)
    await ctx.send(f"You rolled: {result}")

bot.run("token")

根据评论中Erez的建议,我将答案更改为使用;roll 2d6 +7 + d% - 3d4 。您应该可以在此答案的编辑历史记录中看到我的原始代码。

© www.soinside.com 2019 - 2024. All rights reserved.