Roll
dice for successThe 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:
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