DEV Community

Cover image for Dice Roller
Scott Gordon
Scott Gordon

Posted on

Dice Roller

Console Output

# dice_roller.py
#   This program simulates dice rolls using dice roll notation,
#   it is widely used in tabletop RPGs like D&D, Pathfinder etc.
# by: Scott Gordon

import random
import sys

print('***** Welcome to Dice Roller *****')
print('''Enter what kind and how many dice to roll. For example:
            3d20, will roll 3 20 sided dice.
            2d8+1, rolls 2 8 sided dice +1 modifier
            Type QUIT to leave Dice Roller.''')

while True:
    try:
        dice_str = input('> ')
        if dice_str.upper() == 'QUIT':
            print('Thanks for playing!')
            sys.exit()

        dice_str = dice_str.lower().replace(' ', '')

        d_index = dice_str.find('d')
        if d_index == -1:
            raise Exception('Missing the "d" character.')

        number_of_dice = dice_str[:d_index]
        if not number_of_dice.isdecimal():
            raise Exception('Missing the number of dice.')
        number_of_dice = int(number_of_dice)

        mod_index = dice_str.find('+')
        if mod_index == -1:
            mod_index = dice_str.find('-')

        if mod_index == -1:
            number_of_sides = dice_str[d_index + 1:]
        else:
            number_of_sides = dice_str[d_index + 1: mod_index]
        if not number_of_sides.isdecimal():
            raise Exception('Missing the number of sides.')
        number_of_sides = int(number_of_sides)

        if mod_index == -1:
            mod_amount = 0
        else:
            mod_amount = int(dice_str[mod_index + 1:])
            if dice_str[mod_index] == '-':
                mod_amount = -mod_amount

        # Simulate dice rolls:
        rolls = []
        for i in range(number_of_dice):
            roll_result = random.randint(1, number_of_sides)
            rolls.append(roll_result)

        print('Total:', sum(rolls) + mod_amount, '(Each die:', end='')

        for i, roll in enumerate(rolls):
            rolls[i] = str(roll)
        print(', '.join(rolls), end='')

        if mod_amount != 0:
            mod_sign = dice_str[mod_index]
            print(f', {mod_sign}{abs(mod_amount)}', end='')
        print(')')

    except Exception as exc:
        print('Invalid input. Enter something like "3d6" or "1d10+2".')
        print(f'Input was invalide because: {str(exc)}')
        continue

Enter fullscreen mode Exit fullscreen mode

Photo by Lucas Santos on Unsplash

Discussion (2)

Collapse
iceorfiresite profile image
Ice or Fire

Nice but breaking it into functions would make it easier to understand.

Collapse
sagordondev profile image
Scott Gordon Author

Of course, I will get on that this weekend! Thank you for the feedback, it is appreciated.