I am new to python and coding in general. I wrote a program to simulate a dice mechanic. Now I want to calculate the successchance for different scenarios. My function works...sometimes and I´m not able to figure ot why it does not. If the iterations are low it works, if I use higher numbers it fails. I get: ValueError: too many values to unpack (expected 7) in the for loop in simple_check_success_statistic I would be glad for hints.
Thank you for considering.
import random
import math
def roll_dice(sides):
#get result of dice roll
return random.randint(1, sides)
def simple_check(skillvalue, targetnumber, temptationdice, luckydice, temptfate):
# Roll 3D20
dice_rolls = sorted([roll_dice(20) for _ in range(3)])
# Check for automatic failure
if dice_rolls.count(1) >= 2:
return "Automatic Failure"
# Roll Temptation Dice and Lucky Dice
td_rolls = [roll_dice(4) for _ in range(temptationdice)]
ld_rolls = [roll_dice(4) for _ in range(luckydice)]
# Check for 4 in TD and LD
td_4 = 4 in td_rolls
ld_4 = 4 in ld_rolls
# Determine the chosen value
if td_4 and ld_4:
chosen_value = dice_rolls[1] # Middle value
elif td_4:
chosen_value = dice_rolls[0] # Lowest value
elif ld_4 or tf == 1:
chosen_value = dice_rolls[2] # Highest value
else:
chosen_value = dice_rolls[1] # Middle value
# Calculate the Check Result
cr = skillvalue + chosen_value - 10
# Calculate Measure of Success
if cr >= targetnumber:
marks = math.floor((cr - tn) / 3)
else:
marks = 0
# Determine success or failure
if cr >= targetnumber:
return "Success", cr, dice_rolls, td_rolls, ld_rolls, marks, temptfate
else:
return "Failure", cr, dice_rolls, td_rolls, ld_rolls, marks, temptfate
def userinput():
#get values for the check
skillvalue = int(input("Enter Skill Value (0-20): "))
targetnumber = int(input("Enter Target Number (0-20): "))
temptationdice = int(input("Enter number of Temptation Dice in pool: "))
luckydice = int(input("Enter number of Lucky Dice in pool: "))
while True:
user_input = input("Tempt fate? (y/n): ").strip().lower()
if user_input == "y":
temptfate = True
break
elif user_input == "n":
temptfate = False
break
else:
print("Invalid input. Please enter 'Y' or 'N'.")
return skillvalue, targetnumber, temptationdice, luckydice, temptfate
def simple_check_success_statistic(iterations, skillvalue, targetnumber, temptationdice, luckydice, temptfate):
success_array = []
#get a number of results
for i in range(iterations):
result, cr, dice_rolls, td_rolls, ld_rolls, marks, tempted = simple_check(skillvalue, targetnumber, temptationdice, luckydice, temptfate)
success_array.append(result)
#determine percentage of successful results
print(str(success_array.count("Success")/iterations)+"%")
sv, tn, td, ld, tf = userinput()
simple_check_success_statistic(1000, sv, tn, td, ld, tf)
I ran the code through chatgpt (...no comment please ;) ) but it did not spot an error. I looked up arrays and checked the number of variables i return from simple check function. But as i said it sometimes works, othertimes not. I´m a bit lost.
In the "simple_check" function you are expecting it to return 7 different values and then assign those values to variables, but in the:
# Check for automatic failure
if dice_rolls.count(1) >= 2:
return "Automatic Failure"
section you are only returning one value. I fixed this by returning 6 zeroes with what you expected like so:
# Check for automatic failure
if dice_rolls.count(1) >= 2:
return "Automatic Failure", 0, 0, 0, 0, 0, 0
Something you could consider is returning this all as a list and then checking its length with an if statement to determine what to do next. You could say if its length is equal to 7, then we can access all 7 of those indices and there was no issue. If its length is 1, then we got an automatic failure.
Hope this helps! And if you need anymore clarification please comment and I'll edit my answer.