[Python] How to add mathematical operations with dice rolls to my Discord bot?

Discussão em 'Python' iniciado por Stack, Fevereiro 3, 2025.

  1. Stack

    Stack Membro Participativo

    I’m building a Discord bot using Python and discord.ext.commands. My bot already supports basic dice rolls using commands like !r 1d20 or !r 2d6. Now, I want to expand its functionality to allow mathematical operations with multiple dice rolls and modifiers in a single command.

    Example of what I want:

    Input: !r 1d20 + 1d6 + 2d6 + 10

    Output: You rolled: 1d20 (10) + 1d6 (3) + 2d6 (4+2) + 10 (Total: 29)

    And the bot should:

    Parse the input string to identify multiple dice rolls (e.g., 1d20, 2d6).

    Roll the dice for each group and calculate the total.

    Include constants (e.g., +10) in the final calculation.

    Handle expressions with mixed operators (+, -).

    Here’s the code I currently have:

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

    intents = Intents.default()
    intents.message_content = True # Enables reading the content of messages

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

    @bot.command(name='s')
    async def soma(ctx, a: float, b: float):
    resultado = int(a + b)
    await ctx.reply(f"```➕ The sum of {int(a)} and {int(b)} is {resultado}.```")

    @bot.command(name='m')
    async def multiplicacao(ctx, a: float, b: float):
    resultado = int(a * b)
    await ctx.reply(f"```✖️ The multiplication of {int(a)} and {int(b)} is {resultado}.```")

    @bot.command(name='soma_dados')
    async def soma_dados(ctx, *, dados: str):
    try:
    padrao = re.compile(r'(\d+)d(\d+)|(\d+)')
    partes = padrao.findall(dados)
    total = 0
    detalhes = []

    for parte in partes:
    if parte[0] and parte[1]: # is a dice, e.g., 1d20
    num_dice = int(parte[0])
    dice_type = int(parte[1])
    rolls = [random.randint(1, dice_type) for _ in range(num_dice)]
    subtotal = sum(rolls)
    total += subtotal
    detalhes.append(f"{num_dice}d{dice_type}: {rolls} (Subtotal: {subtotal})")
    else: # is a flat number
    total += int(parte[2])
    detalhes.append(f"{parte[2]}")

    await ctx.reply(f"``` You rolled: {', '.join(detalhes)} (Total: {total})```")
    except Exception as e:
    await ctx.reply(f"```Error in expression: {str(e)}```")

    @bot.command(name='r')
    async def rolar_dado(ctx, expression: str):
    try:
    if '+' in expression:
    dice_part, modifier_part = expression.split('+')
    modifier = int(modifier_part)
    elif '-' in expression:
    dice_part, modifier_part = expression.split('-')
    modifier = -int(modifier_part)
    else:
    dice_part = expression
    modifier = 0

    num_dice, dice_type = map(int, dice_part.split('d'))
    rolls = [random.randint(1, dice_type) for _ in range(num_dice)]
    total = sum(rolls) + modifier

    await ctx.reply(f"``` You rolled: {rolls} (Modifier: {modifier}) (Total: {total})```")
    except Exception as e:
    await ctx.reply(f"```Error in expression: {str(e)}```")

    @bot.command(name='p')
    async def porcentagem(ctx, parte: float, total: float):
    if total == 0:
    await ctx.reply("```Error: Total cannot be zero.```")
    else:
    resultado = (parte / total) * 100
    await ctx.reply(f"``` {parte} is {resultado:.2f}% of {total}```")

    bot.run('Bot token :p')


    How can I modify this to handle multiple dice groups and operations in the input string?

    Continue reading...

Compartilhe esta Página