pyDie is a library designed to simulate dice of various types and the random rolls of such. It has been designed to be reusable and with some intelligent decision making capabilities.
1. pyDie
I created pyDie as a re-usable die class program for games or for any program that need a random
probabilities based upon dice or dice like entities. In order to use pyDie you must import the class just
like any Python library. It contains two classes (die and cup).
The die class can be initialized simply by passing a single parameter defining the number of sides
(myDie = pyDie.die(6)) The library will then proceed to create a default die using the number of sides
provided with values starting at 1 and incrementing by 1's till all sides are filled. You may also pass a
second parameter for the low value and create a specialized die based upon the sides and the low value
you assign (such as myDie = pyDie.die(6, 4) creates a die with values from 4 through 9). A third
parameter can be use to set the high value but beware if you specify a low and high value that does not
have a large enough range for the number of sides you specify pyDie will create the die with the right
number of sides and try to make an intelligent decision about the range. Also if you mistakenly make
the low value greater than the high value, pyDie will again attempt to make an intelligent decision
regarding the layout of the die. The last possible parameter for initializing your die is the
incrementation value. This allows you to create dice that increment greater than one number at a time.
An example of this would be (myDie = pyDie.die(8, 1, 16, 2) results in a die with possible values of 1,
3, 5, 7, 9, 11, 13, 15).
Once you have initialized your die you can call the roll method which will randomly choose a value
from your list of possibilities. You can accomplish this by using myDie.roll(), you can then access this
result using the newly created attribute called value (print myDie.value).
The second class in pyDie is the cup class which allows you to store multiple dice and even roll them
all at one time. You can create your cup simply by using myCup = pyDie.cup(). You would then add
your die to the cup using myCup.add(myDie). You can then use the throw method to throw all dice in
the cup (myCup.throw()). You would then access each die's value using the attribute for each die in the
cup. The cup class also has an empty method which clears all dice from the cup, and a remove method
which can be used to remove a single die from the cup simply by using myCup.remove(myDie).
The following is an example of die and cup creation:
import pyDie
myDie = []
cup = pyDie.cup()
# Create 4 standard die
for i in range (1, 5):
myDie.append(pyDie.die(6))
# Create one eight sided that starts with 10
# and increments by 5's
myDie.append(pyDie.die(8, 10, 50, 5))
# Create one final die that is 10 sided
# and begins with 0 and decrements by 2's
myDie.append(pyDie.die(10, -20, 0, -2))
for die in myDie:
cup.add(die)
cup.throw()
total=0
2. print "Die paramaters: (sides, low, high, [range])"
for die in cup.dice:
total = total + die.value
print "(%i, %i, %i, %s)"%(die.sides, die.low, die.high, die.possible)
print "Result of throw for this die: %i"%die.value
print "--------------------------------------------"
print "Total of all dice: %i"%total
The first four die are standard followed by two non-standard configurations.
In this example we create five standard dice:
import pyDie
myDie = []
cup = pyDie.cup()
# Create 5 standard die
for i in range (1, 6):
myDie.append(pyDie.die(6))
for die in myDie:
cup.add(die)
cup.throw()
for die in cup.dice:
print die.value
3. Now we will look at some of the intelligent choices that pyDie makes when odd parameters are passed
to it. This test script was used to test pyDie, and although not pretty, it does demonstrate the power and
flexibility of this library.
import pyDie
print "A cup for the dice"
cup = pyDie.cup()
print "A standard die..."
die1 = pyDie.die(6)
print "Die sides=%i, low=%i, high=%i, range=%s"%(die1.sides, die1.low, die1.high, die1.possible)
die1.roll()
print "Result of roll %i"%die1.value
print "Add die to cup"
cup.add(die1)
print "--------------------------------------n"
print "A non-standard 8 sided die"
die2 = pyDie.die(8)
print "Die sides=%i, low=%i, high=%i, range=%s"%(die2.sides, die2.low, die2.high, die2.possible)
die2.roll()
print "Result of roll %i"%die2.value
print "Add die to cup"
cup.add(die2)
print "--------------------------------------n"
print "An 8 sided die with low > high"
die3 = pyDie.die(8, 4, -3)
print "Die sides=%i, low=%i, high=%i, range=%s"%(die3.sides, die3.low, die3.high, die3.possible)
4. die3.roll()
print "Result of roll %i"%die3.value
print "Add die to cup"
cup.add(die3)
print "--------------------------------------n"
print "Parameters 6, 2, 8, 1"
die4 = pyDie.die(6, 2, 8)
print "Die sides=%i, low=%i, high=%i, range=%s"%(die4.sides, die4.low, die4.high, die4.possible)
die4.roll()
print "Result of roll %i"%die4.value
print "Add die to cup"
cup.add(die4)
print "--------------------------------------n"
print "An eight sided die starting at 10..."
die5 = pyDie.die(8, 10)
print "Die sides=%i, low=%i, high=%i, range=%s"%(die5.sides, die5.low, die5.high, die5.possible)
die5.roll()
print "Result of roll %i"%die5.value
print "Add die to cup"
cup.add(die5)
print "--------------------------------------n"
print "A six sided die (6, 0, -5, -1)"
die6 = pyDie.die(6, 0, -5, -1)
print "Die sides=%i, low=%i, high=%i, range=%s"%(die6.sides, die6.low, die6.high, die6.possible)
die6.roll()
print "Result of roll %i"%die6.value
print "Add die to cup"
cup.add(die6)
print "--------------------------------------n"
print "Roll all die in cup at once"
cup.throw()
for die in cup.dice:
print die.value
Note: Each highlighted line above illustrates different features of die creation
5. The first thing to note is that die1 = pyDie.die(6) is a simple default die creation. This is then followed by
die2 = pyDie.die(8) which is a non-standard eight sided die. The interesting part occurs with the third die
die3 = pyDie.die(8, 4, -3) which is created as an eight sided die but the low value is actually higher than the
high value which additionally is a negative number (Note: pyDie ignores the high value and creates the
die beginning with the low value and working up from there, and then sets the high value to the
appropriate value).
6. The next die created die4 = pyDie.die(6, 2, 8) is a six sided die starting at two and going to eight (since the
high value is outside of the range it is changed to the appropriate value). Following that is an eight
sided die beginning with 10 die5 = pyDie.die(8, 10), this is then followed by a six sided die die6 =
pyDie.die(6, 0, -5, -1) that starts at zero and decrements by one to -5. This is then followed by the throw of
the cup.
Roll all die in cup at once
3
8
7
4
16
-1
As you can see pyDie has been designed with simplicity in mind while still incorporating some
intelligence in order to avoid potential errors.
7. Source Code
The following is the pyDie source code.
# Program: pyDie.py
# Author: James D. Coen
# Date: 2009.12.11
# Purpose: This program is used to create a generic
# die roll class so that it can be imported
# and re-used in various ways
from random import randint, seed
from time import time
class die(object):
""" A single die. """
def __init__(self, sides, low=1, high=6, incr=1):
""" The first argument is the number of sides
the second is the lowest # possible (default 1)
the third is the highest # possible (default 6)
the fourth is the number to increment by (default 1)
"""
self.sides = sides
possible = []
if incr == 0:
incr = 1
if incr < 0:
if low < high:
for i in range(high, low-1, incr):
possible.append(i)
elif low > high:
for i in range(low, high-1, incr):
possible.append(i)
else:
for i in range(0, sides+1*-1, incr):
possible.append(i)
possible.sort()
while len(possible) > self.sides:
possible.remove(possible[0])
low = possible[0]
while len(possible) < self.sides:
possible.append(possible[0] + incr)
possible.sort()
low = possible[0]
else:
if low < high:
for i in range(low, high+1, incr):
possible.append(i)
else:
for i in range(low, low+sides+1, incr):
possible.append(i)
possible.sort()
while len(possible) > self.sides:
possible.remove(possible[len(possible)-1])
high = possible[len(possible)-1]
8. while len(possible) < self.sides:
possible.append(possible[len(possible)-1] + incr)
high = possible[len(possible)-1]
if low < high:
self.high = high
self.low = low
elif low > high:
self.low = high
self.high = low
else:
self.low = possible[0]
self.high = possible[len(possible)-1]
self.possible = possible
def roll(self):
""" Role the die """
seed(time() * time() * self.sides)
self.value = randint(self.low, self.high)
if self.value not in self.possible:
while self.value not in self.possible:
self.value = randint(self.low, self.high)
class cup(object):
""" A cup full of dice. """
def __init__(self):
self.dice = []
def empty(self):
self.dice = []
def add(self, die):
self.dice.append(die)
def remove(self, die):
self.dice.remove(die)
def throw(self):
for die in self.dice:
die.roll()
It must be noted that pyDie works extremely well on Linux but there seems to be a problem with the
randomness on the Window's platform that I have not take time to analyze as I do not use this platform
regularly.