Reputation: 71
When I run my code and get to the battle part of my game, I get random values assigned to my characters attack, defense, damage and health. However, after their first turn, they keep getting the same values and they can't reset.
For example, the user's attack is a random number from 4 to 11. The program "rolls" 5 and assigns it to the variable userAtk
userAtk = random.randint(4,11)
I assumed that everytime the loop ran, it would generate a new value. But its not, and every time I print the variable its the same value it was first assigned. Am I missing something?
Below is my code
import random
# VARIABLES
#
#
# This variable is the user's character name
userName = input("Brave warrior, what is your name? ")
# This variable is used in the input function to pause the game
enterNext = ("Press enter to continue...")
# This variable is used to format the user input prompt
# as well as the battle text
prompt = ">>>>> "
# This variable is used to add a new line to a string
newLine = "\n"
# This variable is used to display a message when the hero dies
heroDeadmsg = userName + " has fallen!"
# These variables represent the dragon's stats (HP, ATK & DEF)
dragonHp = 100
dragonAtk = random.randint(5,10)
dragonDef = random.randrange(8)
# These variables represent the user's stats (HP, ATK & DEF)
userHp = 90
userAtk = random.randint(4,11)
userDef = random.randrange(8)
# These variables calculate battle damage and HP
dragonDmg = (userAtk - dragonDef)
dragonHp -= dragonDmg
userDmg = (dragonAtk - userDef)
userHp -= userDmg
# This variable prints the options in the battle menu
battleMenu = """Attack (a) - Magic (m) - Item (i) - Run (r)"""
# This variable determines who goes first
cointoss = random.randint(0, 1)
# These variables print the actions in each turn
dragonAttack = \
prompt + "Crimson Dragon attacks you with " + str(dragonAtk) + " ATK!"\
+ newLine + prompt + "You defend with " + str(userDef) + " DEF!"\
+ newLine + prompt
userAttack = \
prompt + "You attacked with " + str(userAtk) + " ATK!"\
+ newLine + prompt + "Crimson Dragon defends with " + str(dragonDef) + " DEF!"\
+ newLine + prompt
userMagic = \
prompt + userName + " tried to use Magic!"\
+ newLine + prompt + userName + " has no magic!"\
+ newLine + prompt
userItem = \
prompt + userName + " tried use an Item!"\
+ newLine + prompt + userName + " has no Items!"\
+ newLine + prompt
userRetreat = \
prompt + userName + " tries to retreat!"\
+ newLine + prompt + "The enemy won't let you escape!"\
+ newLine + prompt
# These variables show health during battle
printDragonhp = "Crismon Dragon has " + str(dragonHp) + " HP remaining!"
printUserhp = userName + " has " + str(userHp) + " HP remaining!"
# This variable simulates the results of a coin toss
coinToss = random.randint(0, 1)
#
#
# CONDTITIONS
#
#
# These conditions determines who attacks first
if coinToss == 0:
currentTurn = "dragon"
elif coinToss == 1:
currentTurn = "user"
else:
print("The Coin Toss Failed!")
#
#
# BATTLE MECHANICS
#
#
while currentTurn:
# Mechanics for the Crimson Dragon's Turn
if currentTurn == "dragon":
# Prints the Crimson Dragon's Attack and ends the turn
print(newLine + prompt + "Crimson Dragon moves!"\
+ newLine + prompt + newLine + dragonAttack\
+ newLine + prompt + userName + " takes " + str(userDmg) + " DMG!"\
+ newLine + prompt + printUserhp)
currentTurn = "user"
input(prompt)
# Need to implent a way to reset ATK and DEF
# Mechanics for the User's Turn
if currentTurn == "user":
# Prints the Battle Menu and asks for the User's choice
print(newLine + prompt + battleMenu\
+ newLine + prompt)
userChoice = input(prompt)
# Prints the User's Attack and ends the turn
if userChoice == "a":
print(userAttack)
if userHp < 1:
print(heroDeadmsg)
break
input (prompt)
currentTurn = "dragon"
# Prints the User's Magic and ends the turn
elif userChoice == "m":
print(userMagic)
input (prompt)
currentTurn = "dragon"
# Prints the User's Item and ends the turn
elif userChoice == "i":
print(userItem)
input (prompt)
currentTurn = "dragon"
# Prints the User's Retreat and ends the turn
elif userChoice == "r":
print(userRetreat)
input (prompt)
currentTurn = "dragon"
# Prints an error message for invalid entries
else:
print(newLine + prompt + "That is not a valid menu item."\
+ newLine + prompt + "Please try again.")
Upvotes: 0
Views: 8802
Reputation: 365747
random.randint(4,11)
just chooses an integer in range [4, 11]
and returns you that number. So, when you do userAtk = random.randint(4,11)
, you're just getting a number and storing it as userAtk
, and every time you access userAtk
you'll get the same number back.
If you were hoping for userAtk
to be a magic kind of thing that acts like a different number in the range [4, 11]
each time you access it… well, that's not impossible (see here for a quick & dirty stab at it)… but it will almost certainly lead to more confusion than benefit.
For example, you have code that tries to print out str(userAtk)
… but if the value is different each time you access it, what gets printed out will be different from what's used to calculate the damage! Imagine if you were playing tabletop D&D, and the dungeon master rolled a die to tell you your roll, and then immediately forgot the result and rolled again to figure out whether you hit. So he might say, "You rolled a 20. You missed." That's no good.
What might be useful is to make userAtk
actually be a function:
def userAtk():
return random.randint(4, 11)
And similarly for all of your similar variables. Then, everywhere you were just accessing a number, you'll instead call the function:
def dragonDmg():
return userAtk() - dragonDef()
Then somewhere, you're going to want to store the results of calling those functions in some local variables within each loop.
But the key is that, however you do it, you have to have variables that you re-calculate each time through the loop.
Upvotes: 3
Reputation: 314
I believe even if you call randint() a million times, you will still get repeats (I'm sure you know this). I used to use a dictionary to keep track of the used / unused random numbers, and simply check the dictionary if it's already been used. Might have misunderstood the question.
Upvotes: 0
Reputation: 10663
Because userAtk
isn't within a loop, as far as I can see. If you want it to be reset within a loop, call random.randint(4,11)
within a loop.
Upvotes: 2