Reputation: 55
As a starting project in Python 3.4, I am trying to write some code that emulates rolling some dice and applies some simple rules to the results, I however am having difficulty.
10 sided dice are rolled, in this example the function is passed the parameter of 6 10 sided dice to roll. The function is also passed a target number, in this case 6. The function also takes a boolean value.
For each individual die that is equal too, or greater than the target number, a success is scored.
If any 1's are rolled, they “remove” a success.
I found this fairly straight forward, however when applying the following rule I become unstuck;
If the boolean value of True is passed to the function, any 10's rolled count as a success but may be rolled again. 1's cancel 10's before any other “normal” success.
Initially the code I have written seemed to work, however the re-rolled 10's do not add to the successes properly.
I have been through the debugger on a number of occasions and I cannot see what I am doing wrong, although I am convinced that it must lie somewhere in where I am making my successes = successes + 1 statements.
Any help or advice is greatly appreciated.
import random
def rollDice(numberOfDice, difficulty = 6, specialism = False):
diceRoll = []
rolledOnes = 0
rolledTens = 0
successes = 0
for i in range (numberOfDice):
diceRoll.append(random.randint(1,10))
rolledOnes = diceRoll.count(1)
rolledTens = diceRoll.count(10)
for i in range (numberOfDice):
if diceRoll[i] >= difficulty:
successes = successes +1
if specialism == True:
if rolledOnes > 0:
successes = successes - rolledOnes
rolledTens = rolledTens - rolledOnes
if rolledTens > 0:
for i in range (rolledTens):
reRoll = random.randint(1,10)
if reRoll <= difficulty < 10:
successes = successes + 1
while reRoll == 10:
if reRoll == 10:
successes = successes + 1
reRoll = random.randint(1,10)
else:
for i in range (rolledTens):
reRoll = random.randint(1,10)
while reRoll == 10:
if reRoll >= difficulty:
successes = successes + 1
reRoll = random.randint(1,10)
elif specialism == False:
if rolledOnes > 0:
successes = successes - rolledOnes
return successes
print ('You have', rollDice(6, 6, True), 'Successes!')
Upvotes: 2
Views: 71
Reputation: 55
Thanks to the above answer and comments, the below now works as intended.
import random
def rollDice(numberOfDice, difficulty = 6, specialism = False):
diceRoll = []
rolledOnes = 0
rolledTens = 0
successes = 0
for i in range (numberOfDice):
diceRoll.append(random.randint(1,10))
rolledOnes = diceRoll.count(1)
rolledTens = diceRoll.count(10)
for i in range (numberOfDice):
if diceRoll[i] >= difficulty:
successes = successes +1
if specialism:
if rolledOnes > 0:
successes = successes - rolledOnes
rolledTens = rolledTens - rolledOnes
if rolledTens > 0:
for i in range (rolledTens):
reRoll = random.randint(1,10)
while reRoll == 10:
successes = successes + 1
reRoll = random.randint(1,10)
if reRoll >= difficulty < 10:
successes = successes + 1
else:
if rolledOnes > 0:
successes = successes - rolledOnes
else:
return successes
#MAIN
print ('You have', rollDice(7), 'Successes!')
Upvotes: 1
Reputation: 366133
It's hard to be sure, but I think your problem is happening when there are 10s but no 1s, because you do this:
for i in range (rolledTens):
reRoll = random.randint(1,10)
while reRoll == 10:
if reRoll >= difficulty:
successes = successes + 1
reRoll = random.randint(1,10)
So if you reroll, say, a 9, that's >= difficulty
, but since it's not == 10
, you're never going to get to that check, so you're never going to add to successes
.
So, if the code for the previous case (where there were ones) is correct, this code—which is clearly supposed to be doing the same thing—is incorrect.
This is why you never want to write the same code twice. It's very easy to get it right in every place but one. Try to run the same code in all places if you want the same effect. For example, here, you could do:
if rolledOnes > 0:
successes = successes - rolledOnes
rolledTens = rolledTens - rolledOnes
# everything else should be the same whether there were any ones or not
if rolledTens > 0:
for i in range (rolledTens):
reRoll = random.randint(1,10)
if reRoll <= difficulty < 10:
successes = successes + 1
while reRoll == 10:
if reRoll == 10:
successes = successes + 1
reRoll = random.randint(1,10)
Meanwhile, you seem to be doing a ton of extra work that doesn't do anything. For example:
if rolledTens > 0:
for i in range (rolledTens):
What's the test there for? If rolledTens
is 0 or negative, what happens with for i in range(rolledTens)
?
while reRoll == 10:
if reRoll == 10:
How could reRoll == 10
not be true when we've just entered a loop controlled by while reRoll == 10
?
while reRoll == 10:
if reRoll >= difficulty:
Again, how could reRoll >= difficulty
not be true at the top of this loop?
elif specialism == False:
This is an elif
to if specialism == True
. So, unless you want to allow some third value other than True
or False
to mean "1s don't do anything", what is this test for?
Since I don't know what your thought processes were, I can't say whether these tests are useless, or whether they're important but written wrong (possibly explaining part of your problem). But hopefully you understand what each of these tests is supposed to do.
Finally, as a side note: You usually don't want to compare anything to True
or False
. Just write if specialism:
or if not specialism:
. The one exception is when you explicitly want to treat True
or False
different from other truthy or falsey values (and that's pretty rare; more often you want to treat is None
specially, then treat every other falsey value the same…)
Upvotes: 1