Добавление или вычитание числа из случайно сгенерированного числа - PullRequest
0 голосов
/ 07 апреля 2020

Я пытаюсь реализовать в моей программе функцию, позволяющую пользователю добавлять или вычитать случайно сгенерированное число, используя указанный c двусторонний d ie. Основа моего кода размещена здесь:

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) из сгенерированного броска костей. Logi c будет выглядеть примерно так было бы 8.

-bot "Вы бросили 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 == "-":

Как бы я go сделал это? Я действительно не понимаю, с чего начать. Я не думаю, что приведенный выше код является правильным, потому что сообщение должно быть точно "-". Кроме того, как бы я включил значение (x), поскольку это может быть огромный массив чисел или знаки +/- из пользовательского ввода?

Любая помощь приветствуется!

1 Ответ

1 голос
/ 08 апреля 2020

Вот более продвинутое решение, использующее библиотеку с именем 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 " "
"""

Если вы не знакомы с такими грамматиками, не панируйте c. Все это показывает, что мы можем бросать кости, складывать и вычитать. Тогда у нас может быть 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

. По совету Эреза в комментариях я изменил свой ответ на использование lark.Transformer. Вы должны увидеть мой оригинальный код в истории редактирования этого ответа.

...