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

Top comments (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 •

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