[Tutor] Help with if-elif-else structure

Robert Sjoblom robert.sjoblom at gmail.com
Thu Aug 25 09:51:29 CEST 2011


I've written a function that rolls (standard) dice. There are a few
special cases though:
Any sixes rolled are removed and 2*number of sixes new dice are rolled
in their place.
Initial roll is important to keep track of.

I've solved it with the following function:

from random import randint

def roll_dice(count, sides=6):
    """Rolls specified number of dice, returns a tuple with the format
    (result, number of 1's rolled, number of 6's rolled)."""
    initial_mins = None
    initial_max = None
    result = 0
    while count:
        dice = [randint(1, sides) for die in range(count)]
        if initial_mins == None: initial_mins = dice.count(1)
        if initial_max == None: initial_max = dice.count(sides)
        result += sum(result for result in dice if result != sides)
        count = 2 * dice.count(sides) # number to roll the next time through.
    return (result, initial_mins, initial_max)

Now, when I test against a target number (this is from a Swedish RPG
system, btw -- I just wanted to see if I could write it), several
things can happen:
If I roll two sixes (on the initial roll) and below the target number
(in total), it's a failure.
If I roll two sixes (on the initial roll) and above the target number
(in total), it's a critical failure.
If I roll two ones (on the initial roll) and above the target number
(in total), it's a success.
If I roll two ones (on the initial roll) and below the target number
(in total), it's a critical success.
If I roll below the target number (in total), it's a success.
If I roll above the target number (in total), it's a failure.

I've written a horrible-looking piece of code to solve this, but I'm
sure there are better ways to structure it:

#assuming target number 15
roll = (result, initial_mins, initial_max)
if roll[0] > 15:
    if roll[1] >= 2:
        print("Success")
    elif roll[2] >= 2:
        print("Critical failure!")
    else:
        print("Failure.")
elif roll[0] <= 15:
    if roll[1] >= 2:
        print("Critical success!")
    elif roll[2] >= 2:
        print("Failure")
    else:
        print("Success")

This handles all the test cases I've come up with, but it feels very
ugly. Is there a better way to do this?

-- 
best regards,
Robert S.


More information about the Tutor mailing list