Python- Variable Won't Subtract? - python

I'm trying to create a simple question and answer game in Python (version 3.3.2), but can't figure out how to make an expression work. The "health" and "oppHealth" variables seen below will not change as the program runs, or at least the string display won't show them changing. Source code:
import time
#Variables
health = 30
oppHealth = 30
playStr = str(health)
oppStr = str(oppHealth)
def startBattle():
print()
print('You face off against your opponent.')
print()
print("Your health is " + playStr + ".")
print("Your opponent's health is " + oppStr + ".")
time.sleep(2)
print()
print('The opponent attacks with Fire!')
time.sleep(2)
print()
attack = input('How do you counter? Fire, Water, Electricity, or Ice?')
if attack == ('Fire'):
print("You're evenly matched! No damage is done!")
time.sleep(3)
startBattle()
elif attack == ('Water'):
print("Water beats fire! Your opponent takes 5 damage!")
oppHealth - 5
time.sleep(3)
startBattle()
elif attack == ('Electricity'):
print("You both damage each other!")
health - 5
oppHealth - 5
time.sleep(3)
startBattle()
elif attack == ('Ice'):
print("Fire beats ice! You take 5 damage.")
health - 5
time.sleep(3)
startBattle()
startBattle()
I simply want to make the appropriate health variables decrease by 5- and for the health displaying strings to reflect the change- every time a battle occurs. If anyone can help me with this, I'd greatly appreciate it. Please let me know if I've excluded any information that might help you help me.

the lines
health - 5
oppHealth - 5
and similar, do not actually modify anything, to save the subtraction back in the variables, use the -= operator instead
health -= 5
or you can also say
health = health - 5
The above two examples both achieve the same result. When you just say health - 5 you don't actually save it anywhere.
In addition to this you will need to specify global at the top of your function to modify these values or you will get an error.
def startBattle():
global health
global oppHealth
# ... rest of function
Also you don't need the playStr and oppStr variables, you can print the numeric values like this:
print("Your health is", health, ".")
print("Your opponent's health is", oppHealth, ".")
These don't really need to be global at all though, they can be within the function, sitting in a loop, my version of your program would be this:
#!/usr/bin/env python3
import time
def startBattle():
# set initial values of healths
health = 30
oppHealth = 30
print('You face off against your opponent.', end='\n\n')
while health > 0 and oppHealth > 0: # loop until someone's health is 0
print("Your health is {0}.".format(health))
print("Your opponent's health is {0}.".format(oppHealth), end='\n\n')
time.sleep(2)
print('The opponent attacks with Fire!', end='\n\n')
time.sleep(2)
print('How do you counter? Fire, Water, Electricity, or Ice?')
attack = input('>> ').strip().lower()
if attack == 'fire':
print("You're evenly matched! No damage is done!")
elif attack == 'water':
print("Water beats fire! Your opponent takes 5 damage!")
oppHealth -= 5
elif attack == 'electricity':
print("You both damage each other!")
health -= 5
oppHealth -= 5
elif attack == 'ice':
print("Fire beats ice! You take 5 damage!")
health -= 5
else:
print("Invalid attack choice")
time.sleep(3)
if health <= 0 and oppHealth <= 0:
print("Draw!")
if health <= 0:
print("You lose")
else:
print("You win!")
startBattle()
Though I'd also get rid of all the sleeps. People don't enjoy waiting for a program to "do work" as much as you might think, it's just gonna cause people to click away.

Read a bit more about Python syntax. The correct way to change the value of a variable is, for example:
health = health - 5

oppHealth - 5 should be written as
oppHealth = oppHealth - 5
You're forgetting save the result of your computation

Related

How to make a character's health persist in a sort of RPG I am coding

I am trying to make a basic fight sequence for an RPG just to figure out how things should work in it.
here is the code I have written so far:
`import random
Situ = input("1 to attack, 2 to guard")
Inpu = int(Situ)
playing = True
Enemy_Damage = [25, 50]
Enemy_Guard = 0.5
Character_Damage = [10, 20]
Character_Guard = 0.5
while playing:
Character = None
Enemy = None
Character_Health = 100
Enemy_Health = 75
attack = [f"You Attacked The Enemy! Enemy Health: {Enemy_Health - random.choice(Character_Damage)}", f"You Attacked The Enemy! The Enemy succesfully guarded! Enemy Health: {Enemy_Health - random.choice(Character_Damage) * Enemy_Guard}"]
guard = [f"The Enemy Attacked! You successfully guarded! Your Health: {Character_Health - random.choice(Enemy_Damage) * Character_Guard}", f"The Enemy Attacked! You failed to guard. Your Health: {Character_Health - random.choice(Enemy_Damage)}"]
if Inpu == 1:
print(random.choice(attack))
elif Inpu == 2:
print(random.choice(guard))
PSit = input("1 to attack again, 2 to guard again")
PInp = int(PSit)
if Enemy_Health < Enemy_Health:
Situ = input("1 to attack again, 2 to guard again")
if Character_Health == 0:
playing = False
print("You Have Died!")
if Enemy_Health == 0:
playing = False
print("You Attacked The Enemy! Enemy Health: 0")
print("You Won The Fight!")`
it works fine for what I am trying to do as of now, except that as I continue to fight the enemy or the enemy fights me, the health that we have is based on the number I originally specify (Character_Health = 100, Enemy_Health = 100) so I can keep fighting and never win and never lose since it always goes back to the max health. How would I make it so that the health of me and the enemy changes until I restart the program?
I have not tried much to solve this because I have no idea where to start.
Shift Character_Health = 100 and Enemy_Health = 75 to outside of the while loop. If it is within the loop, every time the loop restarts it will set the health to 100 and 75 again.
As a side note, it's good practice to follow style conventions such as PEP 8 to make your code more readable and easily understandable for you and others.

UnboundLocalError: local variable 'ehp' referenced before assignment

I've been writing a shitty text-based game for the first time using python, and I've encountered a problem whilst making a function for a battle. It would be called upon each time you encounter an enemy, and the variables will be defined before each fight.
The problem I'm having is that my variable, 'ehp', is being referenced before the assignment of the variable. (Stands for Enemy Health Points). My code is listed below and I would like some help as to what to change to my code to prevent the error code that I'm getting with my program.
import random
hp = int(20)
ehp = int(10)
def fight():
print("You have encountered",(enemy))
if speed >= espeed:
first = "c"
for x in range(100):
if ehp <= 0:
print("You have won!")
break
elif hp <= 0:
print("You have died!")
break
else:
print("1: Light Attack")
print("2: Heavy Attack")
print("3: Dodge")
attack = input("1/2/3: ")
if attack == "1":
print("You have used, Light Attack!")
lightdam = (random.randint(0,damage/2))
print("You have inflicted,",edam,"to",enemy)
ehp = ehp - (random.randint(0,damage/2))
print("Enemy Health:",ehp)
print(character,"Health:",hp)
print(enemy,"Has used attack!")
eattack = (random.randint(0,edam/2))
print(enemy,"Has inflicted",eattack,"damage!")
hp = hp - eattack
print("Enemy Health:",ehp)
print(character,"Health:",hp)
elif attack == "2":
print("You have used, Heavy Attack!")
heavydam = (random.randint(0,damage))
print("You have inflicted,",heavydam,"to",enemy)
ehp = ehp - (random.randint(0,damage))
print("Enemy Health:",ehp)
print(character,"Health:",hp)
print(enemy,"Has used attack!")
eattack = (random.randint(0,edam))
print(enemy,"Has inflicted",eattack,"damage!")
hp = hp - eattack
print("Enemy Health:",ehp)
print(character,"Health:",hp)
print("Welcome to the tales of Iryophia, please enter your characters name.")
character = input("Character name: ")
print("Garnier the Honorable:")
print("Welcome to the city of Iryophia, do you remember how you got here?")
y0 = input("Y/N: ")
for x in range(6):
if y0 == "N":
print("Garnier the Honorable:")
print("Well",character,", all I can remember is a certain man entering a neighbouring town, and well, I'm not sure how to put this, but, you were killed.")
print("I understand how crazy this may sound but you were brought back to life. You would have lost all of your memory, but, you are alive!")
print("Do you remember the name of the man who killed you?")
nemesis = input("Nemesis: ")
print("Garnier the Honorable:")
print("Ah yes, I remember now,",nemesis,"was his name.")
break
if y0 == "Y":
print("Garnier the Honorable:")
print("Okay, well the man that attacked you, what was his name?")
nemesis = input("Nemesis: ")
print("Garnier the Honorable:")
print("Ah yes, I remember now,",nemesis,"was his name.")
break
print("Come back with me to my home.")
print("")
print("Garnier the Honorable:")
print("I have a bow, an axe, or a sword for you. Which one do you pick?")
weapon = input("Bow/Axe/Sword: ")
for x in range(6):
if weapon == "Bow":
damage = int(3)
speed = int(5)
break
if weapon == "Axe":
damage = int(7)
speed = int(3)
break
if weapon == "Sword":
damage = int(5)
speed = (4)
break
print("You have collected:",weapon+"!")
print("Damage:",damage)
print("Speed:",(speed))
print("Garnier the Honorable:")
print("Would you like to have a practice fight?")
fight0 = input("Y/N: ")
for x in range(6):
if fight0 == "Y":
ehp = int(10)
enemy = "Garnier the Honorable"
espeed = int(3)
edam = int(4)
fight()
break
Examine these two code lines in fight() (at least these two, though there may be others):
ehp = ehp - (random.randint(0,damage/2))
hp = hp - eattack
For variables not explicitly marked as global, Python makes some assumptions:
if you only use the variable, it will follow the scope up through different levels until it finds a matching name; and
if you set or change it anywhere in a function, it's considered a local variable everywhere in the function.
Hence a simple fix would be to explicitly mark it global in the function:
def fight():
global ehp
global hp
print("You have encountered",(enemy))
:
and so on
A better fix would probably involve not using globals at all :-)
You should probably also review your hit-point processing, which contains such things as:
heavydam = (random.randint(0,damage))
print("You have inflicted,",heavydam,"to",enemy)
ehp = ehp - (random.randint(0,damage))
Telling the player they've inflicted some amount of damage then subtracting a totally different number of hit points is likely to have players scratching their heads trying to figure out how things work :-)

Trying to write DnD combat script, need help printing enemy HP after dice roll

I'm new to coding, so if I make a careless mistake sorry in advance.
I'm trying to write a DnD (specifically, a Star Wars Knights of the Old Republic) combat script. Basically, whenever you attack the game rolls a 20 sided die and if the result is greater than the enemy's defense, you do a successful hit.
Here, I've created a script that does basically that. I am, however, having problems printing the enemy's HP. Instead of remembering the last number and continuing to subtract the damage till the enemy's HP reaches 0, the script keeps on subtracting it from 30 every time, so every roll I get a different number.
How would I make the program remember the HP values and subtract the damage from them accordingly?
import random
dice_min = 1
dice_max = 20
defense = 10
attack_bonus = 3
player_vitality = 30
enemy_vitality = 30
running = True
while running == True:
dice_roll = random.randint(dice_min, dice_max)
attack_roll = dice_roll + attack_bonus
enemy_damage = enemy_vitality - attack_roll
attack_prompt = input("Do you want to attack? [y/n]: ")
if attack_roll > defense:
print("successful hit, the enemy's health is now " + str(enemy_damage))
elif attack_roll < defense:
print("you missed, the enemy's health is " + str(enemy_damage))
What you need to do is saving the new hp value of the enemy into it's variable. In your code, you just calculate the remainding HP after the attack and print it but you are not saving it anywhere. In the next cycle you then just calculate what is essentially 30-damage expression and print the result.
Modify your code like this:
import random
dice_min = 1
dice_max = 20
defense = 10
attack_bonus = 3
player_vitality = 30
enemy_vitality = 30
running = True
while running == True:
dice_roll = random.randint(dice_min, dice_max)
attack_roll = dice_roll + attack_bonus
attack_prompt = input("Do you want to attack? [y/n]: ")
enemy_vitality = enemy_vitality - attack_roll
if attack_roll > defense:
print("successful hit, the enemy's health is now " + str(enemy_vitality))
elif attack_roll < defense:
print("you missed, the enemy's health is " + str(enemy_vitality))

How do I make a battle sequence count the enemy's health down?

I am trying to make a battle sequence against a wizard for a project in my game development class. It should just be a simple "when enemy's health is zero, proceed", "when player's health is zero, game over" sequence.
I have the sequence itself down, but there's an issue with the HP. I have tried to move the if statements for the player and enemy's HP over and over, into different functions, places in and before the while loop in wizardAttack(), but nothing.
import time
playerHealth = 15
wizardHealth = 15
inventory = ['Help Potion', 'Help Potion', 'Poison Dart', 'Dagger', 'Torch']
print('Your HP:', playerHealth)
print('Wizard\'s HP:', wizardHealth)
time.sleep(3)
if playerHealth <= 0:
print('The wizard is too strong! You black out and get dragged back to your dungeon.')
time.sleep(4)
print('Game Over')
playAgain()
if wizardHealth <= 0:
print('The wizard goes down with a THUD! You win the battle!')
time.sleep(4)
print('On the wizard\'s body, you notice a dagger and take it.')
time.sleep(4)
inventory.append('Dagger')
twowizards()
What should happen is the health of both the player and the wizard should tick down, and when one character's health equals 0, then the battle should end properly and move on to the next sequence, or a game over should the enemy win. What happens in reality is the health more or less resets to 15 and it gets me nowhere.
You seem to have not created a battle sequence. maybe something like:
import time
import random
playerHealth = 15
wizardHealth = 15
inventory = ['Help Potion', 'Help Potion', 'Poison Dart', 'Dagger', 'Torch']
print('Your HP:', playerHealth)
print('Wizard\'s HP:', wizardHealth)
time.sleep(3)
if 'Dagger' in inventory:
playerDamage = 4
while playerHealth >=1 and wizardHealth >=1:
wizardDamage = random.randint(1,5)
playerHealth -= wizardDamage
print("You bash the wizard, dealing "+str(playerDamage)+" damage!")
time.sleep(2)
wizardHealth -= playerDamage
print("The wizard bashes you, dealing "+str(wizardDamage)+" damage!")
time.sleep(2)
if playerHealth <= 0:
print('The wizard is too strong! You black out and get dragged back to your dungeon.')
time.sleep(4)
print('Game Over')
playAgain()
if wizardHealth <= 0:
print('The wizard goes down with a THUD! You win the battle!')
time.sleep(4)
print('On the wizard\'s body, you notice a dagger and take it.')
time.sleep(4)
inventory.append('Dagger')
twowizards()
Some of your functions are still not defined, though.

local variable 'fight_run' referenced before assignment

ive been looking around but ive been unable to fix this error.
also as a side problem before this error the program would always print your week was average nothing much happened and the other 2 variables that could of happened didn't
this is all in python
from random import randint
import time
money = 2000
week = 0
def stockmarket():
global money
global week
stock = int(randint(1,50))
fight_random = int(randint(1,4))
fight = int(randint(1,100))
gain_lose = int(randint(1,2))
win_lose_var = int(randint(1,30))
luck = int(0)
if money > 10000 :
print ("""congratulations you beat the game by earning 10,000
now that you have so much money you can go back to your life as a hip hop artist """)
time.sleep(4)
print("it took you ",week,"weeks's to compleate the game")
print("can you do it faster next time")
else:
print(" you have gained lots of money",money,"")
print("you must now invest it all the stock market")
human_stock = int(input("please pick a number between 1-100 not that it matters as the markets are rigged: "))
#need to make the user number matter
change1 = int(stock-40+luck)
change2 = float (change1/100)
change3 = float (1-change2)
money = money * change3
week = week+1
print ("you have" , money,"")
week = week +1
#THIS IS WHERE THE PROBLEM STARTS!
if fight == 3:
print("bad luck")
fight_run = str(input("""late at night you get approched by a bunch of bad, bad people. they attempt to mugg you but you see there is a chance to run away but you could fight
them and gain lots of money! do you fight or run"""))
if fight_run == "run":
print("you fled the scene but left some money behind which has been stolen.")
money *=.8
print(" ",money," ")
stockmarket()
if fight_run == "fight" :
print ("you chose to fight the oncoming enemys!")
if fight < 0 or fight > 11:
print("you where over powered by your enemys and died")
time.sleep(5)
quit()
elif fight <10 and fight >80 :
win_lose = int(input("the fight is close and you are both weak. /n please pick and number between 1 and 30 for a chance to gain money!"))
elif gain_lose == 1:
print("you deafeated your attacckers and take there money (its not a crime if no one saw)")
money_fight_win = (win_lose/100)+ 1
money = money * money_fight_win
print ("",money,"")
elif gain_lose == 2 :
print ("your attacker won and they took your money luckly you hide some just before the fight ")
money_fight_lose = (win_lose/100)+ 1 - (winlose/50)
money = money * money_fight_lose
else :
print("you mortaliy wounded the atackers (cause ur dench m8) and took their money")
money = money *1.5
#loop
stockmarket()
if fight == 4:
print ("you found a lucky penny and added it to your penny collection")
luck = +1
elif fight == 1 or 2:
print("your week was average nothing much happened")
#loop
stockmarket()
#gets program to start
stockmarket()
What if the value of fight is 1?
Then if fight == 3 is false, so the creation of the variable fight_run is skipped, so the variable fight_run doesn't exist. Then you are testing if fight_run == "run" and you are being told fight_run doesn't exist.
I think what you want to do is to indent the code:
if fight_run == "run":
print("you fled the scene but left some money behind which has been stolen.")
money *=.8
print(" ",money," ")
stockmarket()
if fight_run == "fight" :
print ("you chose to fight the oncoming enemys!")
So that it is part of the if fight == 3 block.
Instead of a long sequence of 'if's, I would also look at using elif and else and maybe putting the input in a loop. What if I typed "pee my pants" instead of "run" or "fight"?
Your immediate problem is indentation level. So, if fight != 3, then fight_run is never declared or set. So when you check fight_run in the next if statement there is a chance that it might not exist. Fix your indentation so it reads.
if fight == 3:
print("bad luck")
fight_run = str(input("""late at night you get approched by a bunch of bad, bad people. they attempt to mugg you but you see there is a chance to run away but you could fight them and gain lots of money! do you fight or run"""))
if fight_run == "run":
print("you fled the scene but left some money behind which has been stolen.")
money *=.8
print(" ",money," ")
stockmarket()
if fight_run == "fight" :
print ("you chose to fight the oncoming enemys!")
This way, if fight == 3, then the player is approached, then depending on the player choice he can fight or run. Addressing this will get you to your next error, your code has a bunch of issues, including some more indentation level issues like this one.
Regarding the other issue you mentioned, when you do elif fight == 1 or 2:, that will always be true because testing 2 as a boolean will always be true. This would need to be elif fight == 1 or fight == 2:.
Also, as Robert said in his answer, you have several fall through situations here where the user can input an instruction that will not match any checks. You should always verify that you the instruction cannot fall through and do nothing.

Categories

Resources