The Idea

Central to the tabletop RPG is the rolling of dice. In a typical D&D 4e session, you’ll roll a lot of d20s (twenty-sided dice), and then depending on what you’ve got equipped and what powers you have, lots of other dice with other amounts of sides. So I set out to write a dice-rolling program. After I did that, I wrote a few other versions, but those are for next time.

The Core

I wanted to build on the simple, standard dice notation of mds+a, where m = how many dice with s sides + whatever additional modifiers should be added. For example, a barbarian wielding a two-handed executioner’s axe upon landing a hit might do 1d12+5 damage.

For me, I knew I had to elicit three variables from the user, write a randomizer that could handle (correctly) those three variables, and then spit out the result.

The trickiest part was figuring out how to take a random integer between 1 and 12 (for a d12) 8 times (for example). In ruby, this is pretty easy, since there’s the built-in function of 8.times do *whatever*. In python, there’s no such easy way (a damn shame, I might add), but after a bit of googling, I found I needed to use the itertools module with the special _ character. Both of these were new concepts to me, and I don’t quite know how they work (or why, really), but this is what I ended up with:

def dice_roller(m, d, a):
    #what we're going for: 3d6+10
    sides = 0
    for _ in itertools.repeat(d, m):    #this makes accurate dice rolls
        side = random.randint(1,d)
        sides += side
    roll = str(m) + "d" + str(d) + "+" + str(a)
    value = sides + a
    print('you rolled', roll, 'getting', value)
    return value

The Design

Like I mentioned before, I knew I’d have to grab 3 variables from the user, so I also decided that since the user will have to be looking at a command or terminal screen, I 1) might as well make it look alright and 2) incude an option to make multiple rolls.

For the prettyfication, I looked around online until I found Colorama and decided on a decent ASCII art maker, TAAG. The end result looks like so in a win7 console window:

diceroll!

Not too shabby. That ‘the original’ in there is because–as I state in the comments in my code, and up above–I ended up making a few versions.

As for the rest of the design, I wanted to keep it pretty simple, just getting the info that the program needs. And that looks like this:

times = int(input('how many times do you want to roll? '))
roll_set = {}                           #saving the set in a dict

while times > 0:
    roll = input('\nname this roll: ')  #make sure each name is unique
    m = int(input('how many dice? '))   #integers only on these three
    d = int(input('how many sides? '))
    a = int(input('plus how much? '))
    roll_set[roll] = dice_roller(m, d, a)
    times -= 1

print(roll_set)

So the user provides how many rolls he or she will be making and the type of roll, then the program crunches it and spits out a dictionary of the rolls. About the names rolls: I had originally thought of this as a character generator, or at least for the stats thereof, and so you could name a roll ‘strength’ or ‘constitution.’ Because of the the way I wrote the program, each roll needs to have a unique name, because otherwise the program would be overwriting the same key/value pair over and over.

Yeah, it’s kind of limiting and a bit annoying, but hey, that’s why I wrote multiple versions!

Give it a Spin

You can grab/fork the diceroll script from its github page, and if you have any suggestions/comments (and you don’t want to fork it), tweet me up @thunderchao



Published

21 June 2012

Tags