从随机生成的数字中添加或减去数字
Adding or Subtracting a number from a randomly generated number
我正在尝试在我的程序中实现一项功能,即用户可以使用特定的双面骰子添加或减去随机生成的数字。我的代码基础贴在这里:
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 ) 来自生成的骰子。逻辑看起来像这样
-user ";1d20+2" 假设生成的随机数为 6。由于用户想要将 2 添加到我们生成的随机数,因此结果为 8。
-机器人"You rolled 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),因为它可能是大量数字,或者来自用户输入的 +/- 符号?
感谢任何帮助!
这里有一个更高级的解决方案,它使用名为 lark
to define a grammar for these dice expressions (cribbed from 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 add(self, left, right):
return left + right
@v_args(inline=True)
def subtract(self, left, right):
return left - right
@v_args(inline=True)
def roll(self, qty, size):
qty = qty or 1
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, maybe_placeholders=True)
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")
这允许我们要求计算更复杂的滚动,例如
;roll 2d6 +7 + d% - 3d4
根据评论中 Erez 的建议,我将答案更改为使用 lark.Transformer
。您应该能够在此答案的编辑历史中看到我的原始代码。
我正在尝试在我的程序中实现一项功能,即用户可以使用特定的双面骰子添加或减去随机生成的数字。我的代码基础贴在这里:
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 ) 来自生成的骰子。逻辑看起来像这样
-user ";1d20+2" 假设生成的随机数为 6。由于用户想要将 2 添加到我们生成的随机数,因此结果为 8。
-机器人"You rolled 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),因为它可能是大量数字,或者来自用户输入的 +/- 符号?
感谢任何帮助!
这里有一个更高级的解决方案,它使用名为 lark
to define a grammar for these dice expressions (cribbed from 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 add(self, left, right):
return left + right
@v_args(inline=True)
def subtract(self, left, right):
return left - right
@v_args(inline=True)
def roll(self, qty, size):
qty = qty or 1
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, maybe_placeholders=True)
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")
这允许我们要求计算更复杂的滚动,例如
;roll 2d6 +7 + d% - 3d4
根据评论中 Erez 的建议,我将答案更改为使用 lark.Transformer
。您应该能够在此答案的编辑历史中看到我的原始代码。