I am new to programming in python and, I started writing a simple text based adventure game. I came across a problem when passing an object from one function to another. Here is my code:
import random
import time
num = random.randint(0,2)
xp1 = random.randint(1,2)
class player:
def __init__ (self, name, health, strength, defense, potion, xp, level):
self.__health = health
self.__strength = strength
self.__defense = defense
self.__name = name
self.__potion = potion
self.__xp = xp
self.__level = level
def getName(self):
return self.__name
def getHealth(self):
return self.__health
def getStrength(self):
return self.__strength
def getDefense(self):
return self.__defense
def getPotion(self):
return self.__potion
def getXP(self):
return self.__xp
def getLevel(self):
return self.__level
def setHealth(self):
self.__health = 10
def setLevel(self):
self.__level = 1
def subHealth(self, num):
self.__health -= num
def subPotion(self):
self.__potion -= 1
return self.__health
def addPotion(self, num1):
self.__potion += num1
def addHealth(self):
self.__health +=2
def addStrength(self):
self.__strength += 1
def addDefense(self):
self.__defense += 1
def addXP(self):
self.__xp += xp1
def addLevel(self):
self.__level += 1
self.__addHealth += 1
self.__defense += 1
self.__strength += 1
def battle(enemy, player1, name1):
player1 = player(name1, player1.getHealth(), player1.getStrength(), player1.getDefense(), player1.getPotion(), player1.getXP(), player1.getLevel())
enemy = player('Dongus', enemy.getHealth(), enemy.getStrength(), enemy.getDefense(), enemy.getPotion(), enemy.getXP(), enemy.getLevel())
s = 0
while s == 0:
time.sleep(1)
attack =int(input("Type 1 to attack, type 2 to use a potion."))
if attack == 1:
time.sleep(1)
print("Dongus's health is", enemy.subHealth(num))
print("Dongus hit you and your health is now at", player1.subHealth(num-player1.getDefense()))
elif attack == 2:
time.sleep(1)
print("You used a potion.")
player1.addHealth(), player1.subPotion()
if player1.getHealth() > 10:
player1.setHealth()
print("Dongus hit you and your health is now at", player1.subHealth(num-player1.getDefense()))
if enemy.getHealth()<=0:
print("Congratulations, you won! You recieved", xp1, "xp!")
player.addXP()
s = 2
def main():
name1 = input("What would you like your name to be?")
time.sleep(1)
print("Hello,", name1, "you are on a quest to save otis from the evil Dongus. You must slay him, or Otis will poop.")
time.sleep(2)
player1 = player(name1, 10, 2, 1, 0, 0, 1)
enemy = player('Dongus', 8, 4, 0, 0, 0, 0)
print("Your stats are, health:", player1.getHealth(), "strength:", player1.getStrength(), "and defense:", player1.getDefense())
time.sleep(2)
print("Fight!")
pick = input("You found a health potion! Press 'p' to pick it up.")
p = 0
while p == 0:
if pick == "p":
print("You added a potion to your inventory.")
player1.addPotion(1)
p = 2
else:
print("You have no potions, you should probably pick this one up.")
player1.addPotion(1)
p = 2
battle(enemy, player1, name1)
if self.__getXP() == 1:
print("You leveled up. You are now level 2.")
player1.addLevel()
print("Your stats are, health:", player1.getHealth(), "strength:", player1.getStrength(), "and defense:", player.getDefense())
loot1 = int(input("Type ''1'' to loot the enemy chest."))
if loot1 == 1:
print("You recieved two potions!")
player1.__addPotion(2)
enemy.setHealth(10)
battle(enemy, player1, name1)
main()
Now the problem is when I run the game, I get to a point where I type "1" to attack the enemy, but it says, for some reason, that after attacking the enemy, the enemies health is at "None". This is the same case when the enemy attacks player1, it says player1's health is at "None". I assume that "None" is the default value in python 3.4.1, so my thinking is that the player1's object from def main() are not being transferred over to def battle() and I cannot see the reason why this is happening. I most likely am missing something here, or it is something I do not already know about Python that is causing the issue. Does anybody know what I can do to fix this, and why it is doing this?
BTW some of the terms I am using may be wrong, so please correct me if they are... I have only been coding for 2 weeks :p.
Thanks!!!
First, received not recieved
2nd yes, If you have a Python function that does not return a value, the result is None
# dummy will return "Positive" or None
def dummy(x):
if X > 0:
return "Positive"
So, you probably want to change
def subHealth(self, num):
self.__health -= num
to
def subHealth(self, num):
self.__health -= num
return self.__health
Your question re: the "player" classes from def main() are not being transferred over to def battle() does not really make sense to me.
But, I see that in the first 2 lines of battle, you are replacing the formal parameters player1 and enemy with local variables, this seems like odd usage in your program.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am making a text game for fun and can't find a pythonic way to update the player's stats.
I tried variables like h = 100 player = class(h,d,a,w) (health, defense, attack, weight) but then to have the players health change, I have to do this: h -= enemy attack (ea) player = class(h,d,a,w). Which is long and later on brakes when I add in defense and weapons. Variables work but are very long and unstable when I start to do a lot of math with them to make it more interesting. I also looked into class methods but couldn't find a way to pass player some stat as so that it would update.
import random as ran
class Client:
def __init__(self, health, defense, attack, weight):
self.health = health
self.defense = defense
self.attack = attack
self.weight = weight
class NPC:
def __init__(self, health, defense, attack):
self.health = health
self.defense = defense
self.attack = attack
#client inventory
inv = []
#a set of true or false statements to create a loop
alive = True
enemy_alive = False
while alive == True:
message = input()
player = Client(100, 0, 0, 0)
enemy = NPC(100, 0, 20)
# A way to brake the loop at any time
if message == "q":
alive = False
# Now we need a way to choice a wepon
if len(inv) == 0:
if message == "pick up bow":
print("The bow is now in your inventory.")
inv.append("Bow")
# This was my latest atempt to set player attack to the damage of the bow
player.attack += 25
combat = True
if len(inv) > 0 and combat == True:
if enemy_alive == False:
print("""A enemy is chargeing at you!
HP: 100""")
#We start the fight now that the player has a bow
enemy_alive = True
if "Bow" in inv:
#This is where I said to my self what if I could have attack directly effect health so that when the fight loop is broke the players stats stay with them and so that the math is more set and stone
if minotaur.defense == 0:
if message == "shoot":
hit = ran.randint(0,9)
if hit == 9:
print("Head Shot")
enemy.health = 0
if hit <= 4:
print("Miss")
player.health = player.health-enemy.attack
print("HP :"+str(player.health))
if hit >= 5:
print("HIT!")
enemy.health = enemy.health-player.attack
print("Enemy HP: "+str(enemy.health))
if enemy.defense > 0:
#I made this so I could see if it worked but like above nothing saves correctly
player.attack = player.attack/minotar.defense
if message == "shoot":
hit = ran.randint(0,9)
if hit == 9:
print("Head Shot")
enemy.health = 0
if hit <= 4:
print("Miss")
player.health = player.health-enemy.attack
print("HP :"+str(player.health))
if hit > 4:
print("HIT!")
enemy.health = enemy.health-player.attack
print("Enemy HP: "+str(enemy.health))
if enemy.health <= 0:
print("The Minotaur died a painful death.")
minotaur_alive = False
combat = False
if player.health <= 0:
print("You died!")
alive = False
When I execute the code the only thing that doesn't work is the stat updates. I have a debug layer on my real code that allows me to see if the current state of the game so I know for sure that it isn't updating.
You could maybe consider have every object in the game handle its own behavior: for instance, a Player object could have a Stats object that gets updated when some event happens.
When this works well with one type of Player, you can consider subclassing to modify the behavior; make it harder to kill, of with faster recovery, etc...
Maybe something like this:
class Player:
def __init__(self, name, stats):
self.name = name
self.stats = stats
def get_hit(self, hit_value):
self.stats.update_health(-hit_value)
def rest(self):
self.stats.update_health(10)
def __str__(self):
return f'Player {self.name}: {self.stats}'
class FastRecoveryPlayer(Player):
def rest(self):
self.stats.update_health(20)
class Stats:
"""maintains the Player's stats up to date
"""
def __init__(self, health=100, defense=100, attack=100):
self.health = health
self.defense = defense
self.attack = attack
def update_health(self, value):
self.health += value
self.health = max(0, self.health)
self.health = min(100, self.health)
def __str__(self):
return f'health: {self.health}, defense: {self.defense}, attack: {self.attack}'
hero = Player('Python King', Stats())
print(hero)
print('the Hero gets hit hard')
hero.get_hit(30)
print(hero)
print('the Hero rests a little bit')
hero.rest()
print(hero)
print()
hero2 = FastRecoveryPlayer('Python Emperor', Stats())
print(hero2)
print('the Hero2 gets hit hard')
hero2.get_hit(30)
print(hero2)
print('the Hero2 rests a little bit')
hero2.rest()
print(hero2)
output:
Player Python King: health: 100, defense: 100, attack: 100
the Hero gets hit hard
Player Python King: health: 70, defense: 100, attack: 100
the Hero rests a little bit
Player Python King: health: 80, defense: 100, attack: 100
Player Python Emperor: health: 100, defense: 100, attack: 100
the Hero2 gets hit hard
Player Python Emperor: health: 70, defense: 100, attack: 100
the Hero2 rests a little bit
Player Python Emperor: health: 90, defense: 100, attack: 100
This is generally related to OO design, I suggest that you have a base class of Character (although not essential) and have Client and NPC inheriting that base class, then have an attack and receive_attack method.
class Character():
def __init__(self, health, defense, damage, weight):
self.health = health
self.defense = defense
self.damage = damage
self.weight = weight
def attack(self,target):
target.receive_attack(self.damage)
def receive_attack(self,damage):
self.health -= damage
class Client(Character):
pass
class NPC(Character):
pass
class NPC_harder_to_take_down(Character):
def receive_attack(self,damage):
self.health -= (damage/2)
me = Client(100,100,100,100)
other = NPC(10,10,10,10)
print(me.health)
>>>100
other.attack(me)
print(me.health)
>>>90
I have the following code:
import options
import random
class Player():
def __init__(self):
self.name = None
self.gold = 100
self.maxhealth = 100
self.health = self.maxhealth
self.level = 1
self.exp = 0
self.levelUp = 50
self.gainedexp = self.levelUp - self.exp
def get_name(self):
self.name = input("Hey there, traveller! What's your name?\n~~>")
print("Since you are new around here, 100 gold doubloons have been given to you, {}!".format(self.name))
def gold_counter(self):
print("You currently have {} gold!".format(player.gold))
class Dragon():
def __init__(self):
self.name = "Dragon"
self.dropgold = random.randint(13,20)
self.minexp = int(15 * round(player.level * 1.5))
self.maxexp = int(30 * round(player.level * 1.5))
self.expgain = random.randint({}, {}.format(self.minexp, self.maxexp))
self.maxhealth = 80
self.health = self.maxhealth
def intro():
wrong_input = 0
nar_name = "Narrator"
print("{}: Uhhhm...".format(nar_name))
print("{}: Let me check my list...".format(nar_name))
print("{0}: Ah! Yes! {1}, that's right. I heard you were supposed to be arriving today.".format(nar_name, player.name))
I am also using two other modules, but I'm 99% sure they don't affect this. I get the following output:
Hey there, traveller! What's your name?
~~>Savage Potato
Since you are new around here, 100 gold doubloons have been given to you, Savage Potato!
Do you want to see your balance?
~~> Yes
You currently have 100 gold.
Narrator: Uhhhm...
Narrator: Let me check my list...
Narrator: Ah! Yes! None, that's right. I heard you were supposed to be arriving today.
In the last line, it is printing out the Narrator's name, but not the user's inputted name. I also looked at the python documents on their website, but I couldn't find a fix. Any ideas on how I could stop it from outputting None as the user's name?
EDIT #1: I have player = Player() written later in the module.
EDIT #2: This is all the code I used:
Module 1 (main.py)
import prints
import random
class Player():
def __init__(self):
self.name = None
self.gold = 100
self.maxhealth = 100
self.health = self.maxhealth
self.level = 1
self.exp = 0
self.levelUp = 50
self.gainedexp = self.levelUp - self.exp
def get_name(self):
self.name = input("Hey there, traveller! What's your name?\n~~>")
print("Since you are new around here, 100 gold doubloons have been given to you, {}!".format(self.name))
class Dragon():
def __init__(self):
self.name = "Dragon"
self.dropgold = random.randint(13,20)
self.minexp = int(15 * round(player.level * 1.5))
self.maxexp = int(30 * round(player.level * 1.5))
self.expgain = random.randint({}, {}.format(self.minexp, self.maxexp))
self.maxhealth = 80
self.health = self.maxhealth
#while player.exp >= player.levelUp:
#player.levelUp += 1
#player.exp = player.exp - player.levelUp
#player.levelUp = round(player.levelUp * 1.5)
#print("Congrats! You just levelled up to level {} by gaining {} experience!".format(player.level, player.gainedexp))
def start():
player.get_name()
prints.gold_counter()
prints.intro()
prints.encounter()
player = Player()
start()
Module 2 (prints.py)
import options
import random
class Player():
def __init__(self):
self.name = None
self.gold = 100
self.maxhealth = 100
self.health = self.maxhealth
self.level = 1
self.exp = 0
self.levelUp = 50
self.gainedexp = self.levelUp - self.exp
def get_name(self):
self.name = input("Hey there, traveller! What's your name?\n~~>")
print("Since you are new around here, 100 gold doubloons have been given to you, {}!".format(self.name))
def gold_counter(self):
print("You currently have {} gold!".format(player.gold))
class Dragon():
def __init__(self):
self.name = "Dragon"
self.dropgold = random.randint(13,20)
self.minexp = int(15 * round(player.level * 1.5))
self.maxexp = int(30 * round(player.level * 1.5))
self.expgain = random.randint({}, {}.format(self.minexp, self.maxexp))
self.maxhealth = 80
self.health = self.maxhealth
def intro():
wrong_input = 0
nar_name = "Narrator"
print("{}: Uhhhm...".format(nar_name))
print("{}: Let me check my list...".format(nar_name))
print("{0}: Ah! Yes! {1}, that's right. I heard you were supposed to be arriving today.".format(nar_name, player.name))
print("{}: Welcome to... THE DRAGON FIGHTER GAME!".format(nar_name))
print("{}: I know, it isn't the most imaginative name.".format(nar_name))
print("{}: Don't look at me like that, I tried my hardest!".format(nar_name))
print("{}: Anyhoo, let's carry on.".format(nar_name))
print("{}: For some stupid reason, the creator of this game didn't give me an actual name, so\nmy name is just \"Narrator\" or \"N\", but you can call me Larry.".format(nar_name))
while True:
option = input("Narrator: Actually, which name would you prefer to call me?\n").upper()
if option in options.nar_larry_opt:
nar_name = "Larry"
elif option in options.nar_narrator_opt:
nar_name = "Narrator"
while True:
ask = input("{}: Maybe \"N\" for short?".format(nar_name)).upper()
if ask in options.inp_yes_opt:
nar_name = "N"
elif ask in options.inp_no_opt:
break
else:
wrong_input += 1
if wrong_input == 1:
print("Please try again.")
elif wrong_input == 2:
print("Try to not put the same thing in next time.")
elif wrong_input == 3:
print("This isn't funny.")
elif wrong_input == 4:
print("Seriously.")
elif wrong_input == 5:
print("OKAY! THIS IS IT! GO BACK TO THE BEGINNING!")
intro()
continue
break
else:
print("Please try again.")
continue
break
print("{}: So, as I was saying, this game is basically just some dragon quest thingy.".format(nar_name))
print("{}: You'll probably get tips from me every now and again if I can be bothered.".format(nar_name))
print("{}: I'll get an test encounter ready.".format(nar_name))
def gold_counter():
while True:
option = input("Do you want to see your balance?\n~~> ").upper()
if option in options.inp_yes_opt:
print("You currently have {} gold.".format(player.gold))
elif option in options.inp_no_opt:
print("You can check your balance later in the game.")
else:
print("Please try again.")
continue
break
def encounter():
while True:
dragon_appear = random.randint(1,2)
if dragon_appear == 1:
print("What's that? Looks like a huge bir... \nA DRAGON! A MAJESTIC DRAGON JUST FLEW DOWN FROM THE SKY!")
else:
print("What's that? Looks like a huge bir... \n Yeah. Just a giganta-bird.")
while encounter().dragon_appear != 2:
print("So that's the message you'll get when a dragon appears.")
print("And you will be prompted whether you want to run or fight, like so:")
while True:
wrong_input = 0
ask = input("Run away like a coward, or fight the majestic beast?")
if ask in options.enc_run_opt:
escape = random.randint(1,2)
if escape == 1:
print("You managed to get away!")
else:
print("You didn't get away. Better luck next time!")
elif ask in options.enc_attack_opt:
pass
else:
wrong_input += 1
if wrong_input == 1:
print("Please try again.")
elif wrong_input == 2:
print("Try to not put the same thing in next time.")
elif wrong_input == 3:
print("This isn't funny.")
elif wrong_input == 4:
print("Seriously.")
continue
break
player = Player()
Module 3 (options.py)
inp_yes_opt = {"Y", "YE", "YES", "YEAH", "PLEASE", "YES PLEASE"}
inp_no_opt = {"N", "NO", "NOPE", "NAH"}
nar_larry_opt = {"LARRY", "LARR", "LAR", "LA", "L", "LARRY PLEASE"}
nar_narrator_opt = {"NARRATOR", "NARR", "N", "NAR", "NARRATE", "NOT LARRY"}
enc_run_opt = {"RUN", "RU", "R", "SCRAM", "RUN AWAY", "RUUUUN"}
enc_attack_opt = {"ATTACK", "ATTAK", "A", "FIGHT", "F", "ATTACK", ""}
If you want to print out the name of the player , you need to pass in the player object to the intro function as a parameter. That assumes intro is not capturing the player object and the player object is not global
At the moment , it seems there is no player object accessible to the scope of the function which is why it outputs None
I'm making a small text game for fun. I want to use a function which is located in a function file that I made called functionala.
The function in question, attack(), does not work and the program crashes with the error:
Traceback (most recent call last):
File "C:\Users\seanm\Desktop\Programming\The mists of Alandria\Mists_of_alandria.py", line 22, in <module>
functionala2.attack()
File "C:\Users\seanm\Desktop\Programming\The mists of Alandria\functionala2.py", line 27, in attack
variablestamina += 2
UnboundLocalError: local variable 'variablestamina' referenced before assignment
The new and improved version of the functionala file is what seems to be causing the problem:
variablestamina = 20
variablehealth = 40
variablemonsterhealth = 30
variableattacktype1 = ("Lightattack")
variableattacktype2 = ("Mediumattack")
variableattacktype3 = ("Heavyattack")
def attack():
variableattackquery = input("You can execute three types of attacks. Lightattack does 2 damage and takes no stamina. Mediumattack does 4 damage and takes 2 stamina. Heavyattack does 7 damage and takes 5 stamina. You can only do one per turn: ")
if variableattackquery == variableattacktype1:
variablemonsterhealth -= 2
variablestamina -= 2
if variableattackquery == variableattacktype2:
variablemonsterhealth -= 4
variablestamina -= 4
if variableattackquery == variableattacktype3:
variablemonsterhealth -= 7
variablestamina -= 7
variablestamina += 2
variablestamina = min(20, variablestamina)
print ("The "+monster+" has "+str(variablemonsterhealth)+" health left")
print ("You have "+str(variablestamina)+" stamina left")
monsterattack = random.randrange(4,6)
variablehealth -= monsterattack
print ("The "+monster+" attacks you for "+str(monsterattack))
print ("You have "+str(variablehealth)+" health left")
print()
This seems a cleaner way of doing it, all in a single file. you may want to look at using classes.
From console, call game() to start the game, that's it. The game will end when either monster or you have health <= 0.
Code:
from random import randrange
def game():
stamina = 20
health = 40
monsterhealth = 30
monster = 'orc'
attacks = {'light':(-2,0),'medium':(-4,-2),'heavy':(-7,-4)}
while True:
a = input('you can execute 3 types of attacks, light, medium or heavy... pick one.')
a = a.lower().strip()
if a in attacks:
stamina, health, monsterhealth = attack(stamina, health, monsterhealth, monster, attacks[a])
if stamina <= 0:
print 'you have died...'
break
elif monsterhealth <= 0:
print 'the {} has died...'.format(monster)
break
else:
break
def attack(stamina, health, monsterhealth, monster, att):
monsterhealth += att[0]
stamina += att[1]
stamina = min(20, stamina)
print('the {} has {} health remaining'.format(monster,monsterhealth))
print('you have {} stamina remaining'.format(stamina))
ma = randrange(4,6)
health -= ma
print('the {} attacks you for {}'.format(monster,ma))
print('you have {} health left'.format(health))
return stamina, health, monsterhealth
NB: Even doing this in a single file, you need to scope the variables to the "main" procedure (game), and pass them to the attack function. Otherwise, referring to these names will raise the same error, and you can reproduce this like so:
m = 1
def foo():
m += 1 '## m doesn't exist within scope of foo, so it will raise the same error
HOWEVER, and this may be confusing, the following will not raise an error:
m = 1
def foo():
print m
Nor will this:
m = 1
def foo():
a = m
print a
But both of those seem kind of hack-y and it's usually better to pass values from the main procedure to called functions/methods/etc and return appropriate values to the caller.
I set damage to 3 at the top but when I type damage += 3 at the bottom it says damage is not referenced, why does this happen?
import random, time
inventory = ['dagger','torch']
hp = 50
maxhp = 50
damage = 3
ac = 4
gold = 10
in_combat = False
def choice():
choose = input(">> ")
if choose == "stats":
print("Health:",hp,", Damage:",damage,", Armour: ",ac,", Gold:",gold)
elif choose == "backpack":
print(inventory)
elif choose == "help":
print("Keywords:\nstats | view your stats\nbackpack | view your inventory\nhelp | view keywords to input\nattack | attack an enemy when in combat")
else:
print("Invalid Input")
class Enemy:
def __init__(self, name, attack, armour, health):
self.name = name
self.attack = attack
self.armour = armour
self.health = health
def attack_enemy(self):
time.sleep(1)
print("What action do you want to make?\nType 'help' for a list of actions\n")
answer = input(">> ")
if answer == "attack":
self.health = self.health - damage
print(self.name,"health is: ",self.health)
def main():
while hp > 0:
if 'dagger' in inventory:
damage += 3
print(damage)
choice()
main()
also if I change the code to dagger = 6 at the bottom it will print 6 but when I type stats it will say damage = 3
You can read global variables, but if you wish to assign (rebind) to them, you'll need to tell Python you mean to using the global keyword.
In this case there's no need to make those variable global at all.
You should move those attributes into a class. In this example I called it Player
import random, time
class Player:
def __init__(self):
self.inventory = ['dagger','torch']
self.hp = 50
self.maxhp = 50
self.damage = 3
self.ac = 4
self.gold = 10
self.in_combat = False
def choice(self):
choose = input(">> ")
if choose == "stats":
print("Health:", self.hp, ", Damage:", self.damage,
", Armour:", self.ac, ", Gold:", self.gold)
elif choose == "backpack":
print(inventory)
elif choose == "help":
print("Keywords:\nstats | view your stats\nbackpack | view your inventory\nhelp | view keywords to input\nattack | attack an enemy when in combat")
else:
print("Invalid Input")
class Enemy:
def __init__(self, name, attack, armour, health):
self.name = name
self.attack = attack
self.armour = armour
self.health = health
def attack_enemy(self):
time.sleep(1)
print("What action do you want to make?\nType 'help' for a list of actions\n")
answer = input(">> ")
if answer == "attack":
self.health = self.health - damage
print(self.name,"health is: ",self.health)
def main():
pl = Player()
while pl.hp > 0:
if 'dagger' in pl.inventory:
pl.damage += 3
print(pl.damage)
pl.choice()
main()
Aside: Since you are probably going to be printing lots of multiline blocks, look up the dedent function in textwrap. You could use it something like this:
from textwrap import dedent
def deprint(s):
print(dedent(s))
...
elif choose == "help":
deprint("""
Keywords:
stats | view your stats
backpack | view your inventory
help | view keywords to input
attack | attack an enemy when in combat""")
I cannot figure it out how to end this loop :(
import random
class Enemy:
life = 300
print ('Player 1 your life is ' + str(life) + ' hp' )
def bonusdmg(self):
bondmg=random.randrange(40,51)
print('congratz u made ' + str(bondmg)+' bonus dmg')
self.life-=bondmg
def attack(self):
ad1=random.randrange(50,81)
print(str(ad1) + 'dmg')
print('ouch')
self.life -=ad1
def attack2(self):
ad2=random.randrange(60,90)
print(str(ad2) + 'dmg')
print('arghhh')
self.life -=ad2
def attack3(self):
ad3=random.randrange(100,111)
print(str(ad3) + 'dmg')
print('tsshaaah')
self.life -=ad3
def heal(self):
hp=random.randrange(40,51)
print ('No more potions')
self.life +=hp
print(str(hp) + ' hp have been restored')
def checkLife(self):
if self.life <=0:
print('Your enemy is dead')
else:
print(str(self.life) + "hp life left")
class Enemy2:
life = 300
print ('Player 2 your life is ' + str(life) + ' hp' )
def bonusdmg(self):
bondmg=random.randrange(40,51)
print('congratz u made ' + str(bondmg)+' bonus dmg')
self.life-=bondmg
def attack(self):
ad1=random.randrange(50,81)
print(str(ad1) + 'dmg')
print('ouch')
self.life -=ad1
def attack2(self):
ad2=random.randrange(60,90)
print(str(ad2) + 'dmg')
print('arghhh')
self.life -=ad2
def attack3(self):
ad3=random.randrange(100,111)
print(str(ad3) + 'dmg')
print('tsshaaah')
self.life -=ad3
def heal(self):
hp=random.randrange(40,51)
print ('No more potions')
self.life +=hp
print(str(hp) + ' hp have been restored')
def checkLife(self):
if self.life <=0:
print('Your enemy is dead')
else:
print(str(self.life) + "hp life left")
enemy2 = Enemy2()
enemy1 = Enemy()
while 1:
turn = 1
if turn ==1:
while 1:
print('Player 1 is your turn !')
bonus=str(random.randrange(1,6))
player_move=input('Player1 choose your attack !')
if player_move =='a':
enemy1.attack()
enemy1.checkLife()
turn +=1
break
if player_move =='s':
enemy1.attack2()
enemy1.checkLife()
turn +=1
break
if player_move == 'd':
enemy1.attack3()
enemy1.checkLife()
turn +=1
break
if enemy1.life <=0:
break
if bonus=='2':
enemy1.bonusdmg()
if turn ==2:
while 1:
print('Player 2 is your turn !')
bonus=str(random.randrange(1,6))
player_move=input('Player2 choose your attack !')
if player_move =='a':
enemy1.attack()
enemy1.checkLife()
turn -=1
break
if player_move =='s':
enemy1.attack2()
enemy1.checkLife()
turn -= 1
break
if player_move == 'd':
enemy1.attack3()
enemy1.checkLife()
turn -=1
break
if enemy1.life <=0:
break
if bonus=='2':
enemy1.bonusdmg()
You can try breaking the loop once a certain condition is satisfied. For example, try it like this:
# in while loop
if condition_is_true:
break
Otherwise, you'll need to specify a condition within the declaration of your while loop. I suggest this technique because it does not close your program. It can execute the code below your loop as well, if you have any.
while condition_is_true:
I cleaned up a lot of this, some notes at bottom.
import random
class Player:
def __init__(self, num):
self.num = num
self.life = 300
print('%s your life is %d hp' % (self, self.life))
self.enemy = None
def __str__(self):
return "Player %d" % self.num
def bonusdmg(self):
bondmg=random.randrange(40,51)
print('congratz u made %d bonus dmg' % bondmg)
self.deal_damage(bondmg)
def attack(self):
ad1=random.randrange(50,81)
print('You attack for %d dmg -- ouch' % ad1)
self.deal_damage(ad1)
def attack2(self):
ad2=random.randrange(60,90)
print('You attack for %d dmg -- arghhh' % ad2)
self.deal_damage(ad2)
def attack3(self):
ad3=random.randrange(100,111)
print('You attack for %d dmg -- tsshaaah' % ad3)
self.deal_damage(ad3)
def heal(self):
hp=random.randrange(40,51)
print ('No more potions')
self.life += hp
print('%d hp have been restored' % hp)
def checkEnemyLife(self):
if self.enemy.life <=0:
return "%s is dead" % self.enemy
else:
return "%s has %d hp left" % (self.enemy, self.enemy.life)
# New
def take_damage(self, amt):
print('%s takes %d dmg' % (self, amt))
self.life -= amt
# New
def deal_damage(self, amt):
self.enemy.take_damage(amt)
print(self.checkEnemyLife())
# New
def handle_action(self, player_move):
if player_move =='a': self.attack()
if player_move =='s': self.attack2()
if player_move == 'd': self.attack3()
bonus=str(random.randrange(1,6))
if bonus==2: # Fixed this
self.bonusdmg()
# New
def turn(self):
print("")
player_move = raw_input("%s it's your turn! Choose your attack! " % self)
self.handle_action(player_move)
# New
def won(self):
return (self.enemy.life <= 0)
player1 = Player(1)
player2 = Player(2)
player1.enemy = player2
player2.enemy = player1
# Enemy class
# life as attribute
# raw_input
# string formatting
turn = 1 # Moved this
run_game = True
while run_game:
if turn == 1:
player1.turn()
if player1.won():
print("Player 1 wins")
run_game = False
break
turn += 1
elif turn == 2:
player2.turn()
if player2.won():
print("Player 2 wins")
run_game = False
break
turn -= 1
Made both Enemy classes a single Player class, player1 and player2 are instances of the same class.
Gave each Player instance a reference to their enemy, so they don't deal damage to themselves anymore.
Created a bunch of methods that help stream line your main game loop
Improved printing using string formatting (%) operator.
Changed input to the safer raw_input
life is now an instance attribute instead of a class attribute
A of other, smaller changes
Although your code has many mistakes,I think the infinite loop you are referring is in the inner loop
turn = 1
if turn ==1:
while 1: #this cause a problem, how are you going to exit this loop?
#rest of the code
You never change turn = 2 therefore the if statement turn == 1 is always True. You need to find a place to make turn = 2 so the second player can move. This however will not solve all your issues.