Integral variable in function not working - python

I am trying to make first function, opt1(), make health go down by 50 points however for some reason it doesn’t work. The code works when not in a function.
The line that doesn’t work specifically: health = int(health) - 50
import random
health = "100"
p = "1"
def opt1():
print("Du förlorade striden")
health = int(health) - 50
print(health)
def opt2():
print("hej2")
def opt3():
print("hej3")
q = [opt1, opt2, opt3]
ind = random.randint(0,len(q)-1)
print("you have ", p, " potions")
print("Your health is ", health,)
while True:
print("Commands: Add, drink, sleep, fight, quest")
a = input("Enter a command: ")
if a == "add":
health = int(health)
p = int(p) + 1
print("you have ", p, " potions")
print("Your health is ", health,)
if a == "fight":
q[ind]()

So I have changed the health variable to an int.
And add the global to the function:
import random
health = 100
p = "1"
def opt1():
global health
print("Du förlorade striden")
health -= 50
print(health)
def opt2():
print("hej2")
def opt3():
print("hej3")
q = [opt1, opt2, opt3]
ind = random.randint(0,len(q)-1)
print("you have ", p, " potions")
print("Your health is ", health,)
while True:
print("Commands: Add, drink, sleep, fight, quest")
a = input("Enter a command: ")
if a == "add":
health = int(health)
p = int(p) + 1
print("you have ", p, " potions")
print("Your health is ", health,)
if a == "fight":
q[ind]()
In addition, you can read more on scoping in Python here.
Hope this helps you!

def opt1():
inside opt1 you should declare variable that you are giving into a function.
for example:
def opt1(health):

Related

Python local variable referenced before as assignment

So basically i defined the variable before (globally)
However, it still says variable referenced before assignment.
I am a beginner and i dont know how to use this so please forgive me if i am doing something wrong
import time
import multiprocessing
i = True
upgrade_level = 0
money = 10
def clear_chat():
num = 0
while num < 100:
print(" ")
num += 1
def loop1():
while i:
question = input("Would you like to upgrade? (y)\n")
if(question.lower() == "y"):
if(money >= 10):
clear_chat()
money = money-10
print("You upgraded once")
print("Your upgrade level is " + str(upgrade_level))
elif(money < 10):
clear_chat()
print("You do not have enough money ($10) to buy an upgrade")
else:
clear_chat()
print("You can only input (y)")
def loop2():
while i:
money += 10
time.wait(10)
p1 = multiprocessing.Process(target = loop1())
p2 = multiprocessing.Process(target = loop2())
import time
import multiprocessing
i = True
upgrade_level = 0
money = 10
def clear_chat():
num = 0
while num < 100:
print(" ")
num += 1
def loop1():
global money
while i:
question = input("Would you like to upgrade? (y)\n")
if(question.lower() == "y"):
if(money >= 10):
clear_chat()
money = money-10
print("You upgraded once")
print("Your upgrade level is " + str(upgrade_level))
elif(money < 10):
clear_chat()
print("You do not have enough money ($10) to buy an upgrade")
else:
clear_chat()
print("You can only input (y)")
def loop2():
global money
while i:
money += 10
time.wait(10)
p1 = multiprocessing.Process(target = loop1())
p2 = multiprocessing.Process(target = loop2())
I included global keyword below loop1 func declaration
First time.wait() is accully time.sleep().
The main problem in your code is, you haven't added the global keyword in function. you can read the global variable without global keyword, but in order to make changes in it you have to use global keyword, i.e use global money in both loops.
Instead of clear_chat() functions, you can use the following:
if os.name == 'posix':
os.system('clear') # for MAC os and linux
else:
os.system('cls') # for windows platform
To clear the python screen or Console.
You need to add the global keyword in each function where you want to use it to access it like this,
import time
import multiprocessing
i = True
upgrade_level = 0
money = 10
def clear_chat():
num = 0
while num < 100:
print(" ")
num += 1
def loop1():
global money
while i:
question = input("Would you like to upgrade? (y)\n")
if(question.lower() == "y"):
if(money >= 10):
clear_chat()
money = money-10
print("You upgraded once")
print("Your upgrade level is " + str(upgrade_level))
elif(money < 10):
clear_chat()
print("You do not have enough money ($10) to buy an upgrade")
else:
clear_chat()
print("You can only input (y)")
def loop2():
global money
while i:
money += 10
time.wait(10)
p1 = multiprocessing.Process(target = loop1())
p2 = multiprocessing.Process(target = loop2())
Can read this for examples https://www.w3schools.com/python/python_variables_global.asp
You need to specify that the variable 'money' in both functions is the global one you initialized beforehand using the keyword global. Like this:
import time
import multiprocessing
i = True
upgrade_level = 0
money = 10
def clear_chat():
num = 0
while num < 100:
print(" ")
num += 1
def loop1():
global money
while i:
question = input("Would you like to upgrade? (y)\n")
if(question.lower() == "y"):
if(money >= 10):
clear_chat()
money = money-10
print("You upgraded once")
print("Your upgrade level is " + str(upgrade_level))
elif(money < 10):
clear_chat()
print("You do not have enough money ($10) to buy an upgrade")
else:
clear_chat()
print("You can only input (y)")
def loop2():
global money
while i:
money += 10
time.wait(10)
p1 = multiprocessing.Process(target = loop1())
p2 = multiprocessing.Process(target = loop2())
However, note that the i variable is never changed to False and that creates an infinite loop.
Check this article for more info on the error: Article

User/Player Health is not saved during attack simulation using a coin and random

I am a novice to python. My longterm project is to design a choose your own adventure text-based game.
A major component of this game is attack scenarios. With that in mind, I have been constructing a python program for simulating an attack scenario. In this case, by flipping a coin to first determine whether the player or the enemy attacks first. Afterwards, a random integer between 1 and 10 is used as the attack damage. A function (HealthCheck), checks the health of the player/enemy to determine whether the player/enemy is dead.
My main problem is that the enemy's and player's health restarts after an attack. How can my program save the user's health after an attack, instead of resetting to 10 HP?
Below is my python code. Thank you for your help.
import random
import time
import sys
enemyHealth = 10
playerHealth = 10
def playerAttack(enemyHealth):
attack_damage = random.randint(1, 10)
print("The player does " + str(attack_damage) + " damage points to
the enemy.")
enemyHealth -= attack_damage
print("The enemy has " + str(enemyHealth) + " HP left!")
enemyHealthCheck(enemyHealth)
pass
def enemyAttack(playerHealth):
attack_damage = random.randint(1, 10)
print("The enemy does " + str(attack_damage) + " damage points to
the player.")
playerHealth -= attack_damage
print("The player has " + str(playerHealth) + " HP left!")
playerHealthCheck(playerHealth)
pass
def turnChoice():
h = 1
t = 2
coin = ""
while coin != "h" and coin != "t":
coin = input("Player, flip a coin to decide who attack first.\n"
"Heads or tails? H for heads. T for tails.\n")
if coin == "h":
print("You chose heads.\n"
"Flip the coin. \n"
". . .")
time.sleep(2)
else:
print("You chose tails.\n"
"Flip the coin. \n"
". . .")
time.sleep(2)
choice = random.randint(1, 2)
if choice == coin:
print("Great choice. You go first.")
playerAttack(enemyHealth)
else:
print("Enemy goes first.")
enemyAttack(playerHealth)
def replay():
playAgain = ""
while playAgain != "y" and playAgain != "n":
playAgain = input("Do you want to play again? yes or no")
if playAgain == "y":
print("You chose to play again.")
print(".")
print(".")
print(".")
time.sleep(2)
turnChoice()
else:
print("Game over. See you soon.")
sys.exit()
def playerHealthCheck(playerHealth):
if playerHealth <=0:
print("Player is dead. Game over.")
replay()
else:
print("The player has " + str(playerHealth) + " HP points!")
print("It is your turn to attack.")
playerAttack(enemyHealth)
def enemyHealthCheck(enemyHealth):
if enemyHealth <=0:
print("Enemy is dead. You win.")
replay()
else:
print("Enemy is not dead. The enemy has " + str(enemyHealth) + " HP points.")
print("It is their turn to attack.")
enemyAttack(playerHealth)
turnChoice()
To make the code edit the variables you need to use globals. When you call the variable with the parentheses in the function they are only edited in the scope of that variable, but when you use globals they get edited for the whole program. Here is an example. Below is the code that is using globals:
import random
import time
import sys
enemyHealth = 10
playerHealth = 10
def playerAttack():
global enemyHealth
attack_damage = random.randint(1, 10)
print("The player does " + str(attack_damage) + " damage points to the enemy.")
enemyHealth -= attack_damage
print("The enemy has " + str(enemyHealth) + " HP left!")
enemyHealthCheck()
pass
def enemyAttack():
global playerHealth
attack_damage = random.randint(1, 10)
print("The enemy does " + str(attack_damage) + " damage points to the player.")
playerHealth -= attack_damage
print("The player has " + str(playerHealth) + " HP left!")
playerHealthCheck()
pass
def turnChoice():
h = 1
t = 2
coin = ""
while coin != "h" and coin != "t":
coin = input("Player, flip a coin to decide who attack first.\n"
"Heads or tails? H for heads. T for tails.\n")
if coin == "h":
print("You chose heads.\n"
"Flip the coin. \n"
". . .")
time.sleep(2)
else:
print("You chose tails.\n"
"Flip the coin. \n"
". . .")
time.sleep(2)
choice = random.randint(1, 2)
if choice == coin:
print("Great choice. You go first.")
playerAttack()
else:
print("Enemy goes first.")
enemyAttack()
def replay():
playAgain = ""
while playAgain != "y" and playAgain != "n":
playAgain = input("Do you want to play again? yes or no")
if playAgain == "y":
print("You chose to play again.")
print(".")
print(".")
print(".")
time.sleep(2)
turnChoice()
else:
print("Game over. See you soon.")
sys.exit()
def playerHealthCheck():
global playerHealth
if playerHealth <= 0:
print("Player is dead. Game over.")
replay()
else:
print("The player has " + str(playerHealth) + " HP points!")
print("It is your turn to attack.")
playerAttack()
def enemyHealthCheck():
global enemyHealth
if enemyHealth <= 0:
print("Enemy is dead. You win.")
replay()
else:
print("Enemy is not dead. The enemy has " + str(enemyHealth) + " HP points.")
print("It is their turn to attack.")
enemyAttack()
turnChoice()

Run-time error when setting the value of a variable in Python

I want to make an RPG game, and I'm trying to make a system of buying items and potions. What I intended was for the player to get 3 potions of each in the beginning, but you need to buy more to continue with them. My problem is that they keep on resetting every time I call the fight function.
I've tried making them global in the beginning and defining them, but they keep on saying "Referenced before assignment"
def Fight(monster):
global HealPotionsLeft
global WeakPotionsLeft
HealPotionsLeft = 3
WeakPotionsLeft = 3
Potion = ['Yes', 'No']
currentFighter = ""
if myPlayer.dexterity >= monster.dexterity:
currentFighter = myPlayer.name
else:
currentFighter = monster.name
while myPlayer.isDead is not True and monster.isDead is not True:
print(currentFighter + "'s turn!")
print("===========================")
print("Name:", myPlayer.name)
print("Health:", myPlayer.health, "/", myPlayer.maxHealth)
print("===========================")
print("Name:", monster.name)
print("Health:", monster.health, "/", monster.maxHealth)
print("===========================")
if currentFighter == monster.name:
monster.Attack(myPlayer)
currentFighter = myPlayer.name
continue
userInput = ""
validInput = False
while validInput is not True:
print("-Attack")
print("-Spells")
print("-Items")
print("-Flee")
userInput = input()
if userInput == "Attack":
myPlayer.Attack(monster)
break
if userInput == "Spells":
print("TO DO - Spells")
if userInput == "Items":
secure_random = random.SystemRandom()
item = secure_random.choice(Potion)
if item == ('Yes'):
print("You have", HealPotionsLeft, "Potions of Healing Left and", WeakPotionsLeft, "Potions of Damage Left.")
PotionUsage = input("Would you like to use your *Potion of Healing*? y/n")
if PotionUsage == str("n"):
if HealPotionsLeft == 0:
print("You spent too much time trying to get the healing potion so you got attacked! *Out of Healing Potions*.")
break
elif HealPotionsLeft > 0:
if PotionUsage == ("y"):
myPlayer.health = 100
print(myPlayer.name, "Healed to 100 HP!")
HealPotionsLeft = HealPotionsLeft - 1
PotionsLeft()
break
if PotionUsage == str("y"):
if WeakPotionsLeft == 0:
print("You spent too much time trying to get the Potion of Damage so you got attacked! *Out of Potions of Damage*.")
break
elif WeakPotionsLeft > 0:
weakPotion = input("Would you like to use your Potion of Damage? y/n")
if weakPotion == str("y"):
monster.health = monster.health - 20
print(myPlayer.name, "Used their Potion of Damage on" , monster.name, "for 20 damage!")
WeakPotionsLeft = WeakPotionsLeft - 1
PotionsLeft()
break
if item == ('No'):
print("You didn't get to your potions in time!")
break
I expect the potions to go to three when the player goes into battle in the first time, but afterwards when going to battle the amount of potions resets the the amount remaining from last battle.
Outside this Fight() function initialize your potion counts to 3 each. Then pass the current amount of potions in to the Fight() function something like: Fight(monster,Hpots,Wpots) then return the remaining potions to the outer scope with a return(HealPotionsLeft,WeakPotionsLeft)
********* Example Requested: *********
I can not test this code and this is just an example
BattleResults = []
global CurrentHealPotions
global CurrentWeakPotions
CurrentHealPotions = 3
CurrentWeakPotions = 3
def Fight(monster,HealPotionsLeft,WeakPotionsLeft):
Potion = ['Yes', 'No']
currentFighter = ""
if myPlayer.dexterity >= monster.dexterity:
currentFighter = myPlayer.name
else:
currentFighter = monster.name
while myPlayer.isDead is not True and monster.isDead is not True:
print(currentFighter + "'s turn!")
print("===========================")
print("Name:", myPlayer.name)
print("Health:", myPlayer.health, "/", myPlayer.maxHealth)
print("===========================")
print("Name:", monster.name)
print("Health:", monster.health, "/", monster.maxHealth)
print("===========================")
if currentFighter == monster.name:
monster.Attack(myPlayer)
currentFighter = myPlayer.name
continue
userInput = ""
validInput = False
while validInput is not True:
print("-Attack")
print("-Spells")
print("-Items")
print("-Flee")
userInput = input()
if userInput == "Attack":
myPlayer.Attack(monster)
break
if userInput == "Spells":
print("TO DO - Spells")
if userInput == "Items":
secure_random = random.SystemRandom()
item = secure_random.choice(Potion)
if item == ('Yes'):
print("You have", HealPotionsLeft, "Potions of Healing Left and", WeakPotionsLeft, "Potions of Damage Left.")
PotionUsage = input("Would you like to use your *Potion of Healing*? y/n")
if PotionUsage == str("n"):
if HealPotionsLeft == 0:
print("You spent too much time trying to get the healing potion so you got attacked! *Out of Healing Potions*.")
break
elif HealPotionsLeft > 0:
if PotionUsage == ("y"):
myPlayer.health = 100
print(myPlayer.name, "Healed to 100 HP!")
HealPotionsLeft = HealPotionsLeft - 1
PotionsLeft()
break
if PotionUsage == str("y"):
if WeakPotionsLeft == 0:
print("You spent too much time trying to get the Potion of Damage so you got attacked! *Out of Potions of Damage*.")
break
elif WeakPotionsLeft > 0:
weakPotion = input("Would you like to use your Potion of Damage? y/n")
if weakPotion == str("y"):
monster.health = monster.health - 20
print(myPlayer.name, "Used their Potion of Damage on" , monster.name, "for 20 damage!")
WeakPotionsLeft = WeakPotionsLeft - 1
PotionsLeft()
break
if item == ('No'):
print("You didn't get to your potions in time!")
break
if myPlayer.isDead is True
result="You have been defeated!"
else
result="You have slain the Beast!"
BattleEnd=[result, HealPotionsLeft, WeakPotionsLeft]
return(BattleEnd)
A call to this function might look like:
BattleResults = Fight("Your Monster Reference Here",CurrentHealPotions,CurrentWeakPotions)
Then assign the new values to potions:
CurrentHealPotions = BattleResults[1]
CurrentWeakPotions = BattleResults[2]

How can I get new results from randint while in a loop?

My code thus far:
from random import randint
Dice1 = randint(1,6)
Dice2 = randint(1,6)
Dice3 = randint(1,6)
DiceRoll2 = Dice1 + Dice2
DiceRoll3 = Dice1 + Dice2 + Dice3
class Item(object):
def __init__(self, name, value, desc):
self.name = name
self.value = value
self.desc = desc
sword = Item("Sword", 2, "A regular sword.")
class Monster(object):
def __init__(self, name, health, attack):
self.name = name
self.health = health
self.attack = attack
monster = Monster("Monster", 50, DiceRoll2)
Damage = DiceRoll3 + sword.value
NewHealth = monster.health - Damage
print("You see a monster!")
while True:
action = input("? ").lower().split()
if action[0] == "attack":
print("You swing your", sword.name, "for", Damage, "damage!")
print("The", monster.name, "is now at", NewHealth, "HP!")
elif action[0] == "exit":
break
The intension is that with every time you enter "attack" you get a random result of DiceRoll3 (three random numbers from 1 to 6, that three times), add the value of the sword and substract that from the monster's starting health. This goes well until I enter "attack" a second time, which results in the same damage and the same reduced health being printed instead of using a new value. How can I properly do this?
You need to make the call to randint everytime. Below is one way to do it
def Dice1(): return randint(1,6)
def Dice2(): return randint(1,6)
def Dice3(): return randint(1,6)
This isn't great though because of all the repeated code. Here is a better way
class Dice(object):
def roll_dice(self):
return randint(1,6)
Dice1 = Dice()
Dice2 = Dice()
Dice3 = Dice()
Now in your code where ever you call Dice1, Dice2 or Dice3; instead call Dice1.roll_dice(), Dice2.roll_dice(), Dice3.roll_dice(). This abstract away the dice implementation and you are free to change it later without having to change your code.
If you need have dice with different number of faces, you only need to change your dice class
class Dice(object):
def __init__ (self, num_faces=6):
self.faces = num_faces
def roll_dice(self):
return randint(1,self.faces)
Dice1 = Dice() # 6 faced die
Dice2 = Dice(20) # 20 faced die
Put your dice-rolling into a separate function and calculate Damage and NewHealth inside your loop. (Also, update your Monster's health. :))
from random import randint
def dice_roll(times):
sum = 0
for i in range(times):
sum += randint(1, 6)
return sum
class Item(object):
def __init__(self, name, value, desc):
self.name = name
self.value = value
self.desc = desc
sword = Item("Sword", 2, "A regular sword.")
class Monster(object):
def __init__(self, name, health, attack):
self.name = name
self.health = health
self.attack = attack
monster = Monster("Monster", 50, dice_roll(2))
print("You see a monster!")
while True:
action = input("? ").lower().split()
if action[0] == "attack":
Damage = dice_roll(3) + sword.value
NewHealth = max(0, monster.health - Damage) #prevent a negative health value
monster.health = NewHealth #save the new health value
print("You swing your", sword.name, "for", Damage, "damage!")
print("The", monster.name, "is now at", NewHealth, "HP!")
elif action[0] == "exit":
break
if monster.health < 1:
print("You win!")
break

My game wont go to my function

Well here's the problem my game() function wont go to my firstlevel() function and just keeps says process exited with exit code 0 And I have no clue why I even tried changing the function name And still no luck I truly have no clue what to do I am just a beginner...
code:
import winsound
import random as ran
import pickle
profile = {}
def fightsound():
winsound.PlaySound('fight2.wav', winsound.SND_FILENAME | winsound.SND_ASYNC)
def ranking():
if profile['xp'] >= 20:
profile['level'] += 1
if profile['xp'] >= 50:
profile['level'] += 1
if profile['xp'] >= 100:
profile['level'] += 1
game()
else:
game()
else:
game()
else:
game()
def play_bgmusic():
winsound.PlaySound('mk.wav', winsound.SND_FILENAME | winsound.SND_ASYNC)
def load_game():
global profile
profile = pickle.load(open("save.txt", "rb"))
game()
def fatality():
winsound.PlaySound('fatal2.wav', winsound.SND_FILENAME | winsound.SND_ASYNC)
def game():
global profile
print("Player: " + profile['player'])
print("XP: ", profile['xp'])
print("Level: ", profile['level'])
print("win: ", profile['win'])
print("loss: ", profile['loss'])
if profile['level'] >= 1:
print("1.) The ogre king...")
if profile['level'] >= 2:
print("2.) The realm of the witch!")
y = input("Select an option -> ")
if y == 1:
firstlevel()
def firstlevel():
global profile
fightsound()
enemyhp = 50
hp = 100
while enemyhp > 0:
print("Your hp: ", hp, " Enemy hp: ", enemyhp)
input("Press enter to attack...")
damage = ran.randint(0, 25)
enemyhp -= damage
damage = ran.randint(0, 25)
hp -= damage
if hp <= 0:
profile['xp'] += 5
profile['loss'] += 1
pickle.dump(profile, open("save.txt", "wb"))
print("You died, press enter to continue...")
game()
fatality()
profile['xp'] += 10
profile['win'] += 1
pickle.dump(profile, open("save.txt", "wb"))
input("You win! Press enter to continue...")
ranking()
def new_game():
global profile
player = input("Enter a player name -> ")
profile['player'] = player
profile['xp'] = 0
profile['level'] = 1
profile['win'] = 0
profile['loss'] = 0
pickle.dump(profile, open("save.txt", "wb"))
game()
def main():
play_bgmusic()
print(20 * "-")
print("| |")
print("| 1.) New Game |")
print("| 2.) Load Game |")
print("| 3.) Credits |")
print("| |")
print(20 * "-")
x = int(input("Select an option -> "))
if x == 1:
new_game()
if x == 2:
load_game()
if x == 3:
pass
main()
The problem is these three lines:
y = input("Select an option -> ")
if y == 1:
firstlevel()
When you get input, it will come back as a string. You are comparing the string "1" to the integer 1. The two are not equal, so firstlevel() is never called.
You should convert the string to an integer, or change the integer to a string, so that you are comparing two objects of the same type.
Gonna bet it's cause y isn't what you think it is. Try printing it out or putting a breakpoint on it to make sure it is an integer with value 1.
The problem is here:
y = input("Select an option -> ")
if y == 1:
input() returns a string, so it will never be equal to the integer 1. Simply use int() on y before your comparison and you'll be good to go.

Categories

Resources