ActiveState Code

Recipe 68422: Rolling dice


A simple function to permit you to generate random numbers by emulating a dice roll. The number of dice and the number of sides to each die are the parameters of the function. In order to (for example) roll 4d6, you would call dice( 4, 6 ).

Python
1
2
def dice( num, sides ):
	return reduce(lambda x, y, s = sides: x + random.randrange(s), range( num + 1 )) + num

Discussion

Simulating a dice roll is a good way to generate a random number with an expected profile. For example, 3d6 will generate a bell-shaped probability curve with an average of 10.5.

After trying a more manual approach (for loop with an accumulator), I found that using reduce is generally faster. It's possible this implementation could be faster still, as I haven't profiled it very aggressively; it's fast enough for my purposes :)

Comments

  1. 1. At 1:20 p.m. on 4 apr 2005, Tim Keating (the author) said:

    Getting rid of reduce. Since reduce() is probably going away sometime soon, using a list comprehension or generator expression is a better way to do this in future Python:

    from random import randrange
    
    def dice(num, sides):
        return sum(randrange(sides)+1 for die in range(num))
    

    Which is also more straightforward, come to think of it.

  2. 2. At 2:58 p.m. on 11 jul 2005, Frank P Mora said:

    A list comprehension version. The inner most (furthest left) comprehension is an accumulator. The furthest right, an initializer. The result is a triply nested list so the stuff at the end is there to get only the final single digit result.

    >>> dice=lambda s,n: [[[j for j in (j+randrange(s)+1,)] for die in range(n)] for j in (0,)]   [0][-1][0]
    

Sign in to comment