rcline6
rcline6

Reputation: 13

Python data structure for dice roll emulator

So I made a dice rolling simulator in python, and while it does everything that I want it to I was told I could implement lists or a dictionary and it would be "better" code. I have tried adding both to my code and am completely lost. If any of you could help/show me that would be awesome. Here's my code, thanks so much.

from random import randint
print ""
die_amount = raw_input(">How many dice would you like to roll?: " )
die_amount = int(die_amount)
print ""
print "\t %s die are being rolled:" % die_amount

def dieroll(die_amount):
    one = 0
    two = 0
    three = 0
    four = 0
    five = 0
    six = 0
    for i in range(1, die_amount+1):
        roll = randint(1,6)
        print "\t You rolled: %s" % roll

        if roll == 1:
                one +=1
        elif roll == 2:
                two +=1
        elif roll ==3:
                three +=1
        elif roll == 4:
                four +=1
        elif roll == 5:
                five+=1
        elif roll == 6:
                six +=1

    print """  
        One's rolled: %s
        Two's rolled: %s
        Three's rolled: %s
        Four's rolled: %s
        Five's rolled: %s
        Six's rolled: %s
        """ % (one, two, three, four, five, six )
    return [one, two, three, four, five, six]

dieroll(die_amount)

Upvotes: 1

Views: 349

Answers (2)

Brad Budlong
Brad Budlong

Reputation: 1785

If you want an answer that more closely matches your original implementation, but uses a list instead, here is a replacement for dieroll():

def dieroll(die_amount):
    rolls = [0] * 6
    for i in range(die_amount):
        roll = randint(1,6)
        print "\t You rolled: %s" % roll
        rolls[roll-1] += 1

    print """  
        One's rolled: %s
        Two's rolled: %s
        Three's rolled: %s
        Four's rolled: %s
        Five's rolled: %s
        Six's rolled: %s
        """ % tuple(rolls)
    return rolls

Upvotes: 0

Pascal Bugnion
Pascal Bugnion

Reputation: 4928

A Counter data structure does exactly what you are trying to do.

from collections import Counter
c = Counter()

for i in range(die_amount):
    roll = randint(1,6)
    c[roll] += 1

Or, even easier:

c = Counter(randint(1,6) for i in range(die_amount))

c[1] then contains the number of times 1 was rolled etc.

To print out the roll counts, you can use

for number, count in c.iteritems():
    print "{}'s rolled: {}".format(number, count)

A Counter is basically a Python dictionary with a default value of zero. This makes it particularly suitable for counting how many objects occur in a list, for instance.

There are several reasons why this approach works better than keeping a separate variable for each count.

  • If you wanted to have a hundred-sided dice, you would have to define 100 separate variables. That's much more error prone.

  • It's, in principle, much faster. Having six different variables necessitates looping through them with a series of if-statements. Imagine you roll a six. You will have to evaluate five different if-statements until you get to if roll == 6. By contrast, the counter uses a hash table, so c[roll] takes the same amount of time, regardless of how many rolls you make.

This begs the question: how can you know when you should be using a collection as opposed to a set of variables? The rule of thumb is that if a set of objects are different instances of the same thing, and we intend to use each object in exactly the same manner, they probably belong in a collection. In this case, a roll of 1 or a roll of 4 is essentially identical as far as the program flow is concerned. We will always treat them identically. They should therefore be kept in a collection.

Upvotes: 3

Related Questions