Hello, OnlineGDB Q&A section lets you put your programming query to fellow community users. Asking a solution for whole assignment is strictly not allowed. You may ask for help where you are stuck. Try to add as much information as possible so that fellow users can know about your problem statement easily.

loop doesnt alter variable second time around

+5 votes
asked Nov 24, 2021 by Ryder Johansen (310 points)
basically I have a while loop in it with the following 2 lines:

newhp = player.hp - damage
player.hp = newhp

and it changes it the first time through but on the second it doesnt, why is this?

heres my entire code:

import random
import time
newhp = 0

def GetChoice(message, choices):
    success = False
    while (not success):
        choice = input(message + " " + str(choices) + ": ").strip().upper()
        success = choice in choices
    return choice

    
class Player:
    name = "yourself"
    maxHp = 50
    hp = 50
    mana = 100
    gp = 0
    inventory = "empty"

class Weapon:
    def CanHit(self):
        return random.randint(0, 100) < self.hitChance

    def TryHit(self, enemy):
        if self.CanHit():
            self.HitEnemy(enemy)
            enemy.TakeDamage(self.damage)
        else:
            print("You missed!")

    
class Sword(Weapon):
    hitChance = 85
    damage = 10
    def HitEnemy(self, enemy):
        print("You slash through the", enemy.name, "dealing", self.damage, "damage!")
class Magic:
    def CanCast(self):
        return random.randint(0, 100) < self.castChance

    def TryCast(self, target):
        if self.CanCast():
            self.CastOnTarget(target)
        else:
            print("You missed!")
    

class Fireball(Magic):
    castChance = 65
    damage = 15
    def CastOnTarget(self, enemy):
        print("Forming a ball of fire in your hand you hurl it at the", enemy.name, "dealing", self.damage, "damage!")
        enemy.TakeDamage(self.damage)

class Healing(Magic):
    castChance = 100
    healMin = 5
    healMax = 15
    def CastOnTarget(self, target):
        if target.maxHp > target.hp:
            heal = random.randint(5, 15)
            if heal > target.maxHp - target.hp:
                heal = target.maxHp - target.hp
            print("You have healed", target.name, "for", heal, "HP.")
        else:
            print("Already at maximum health.")

class Enemy:
    def __init__(self, name):
        self.name = name

    def TakeDamage(self, damage):
        self.hp = self.hp - damage

class Beatle(Enemy):
    hp = 20
    def __init__(self):
        Enemy.__init__(self, "Beatle")

class Goblin(Enemy):
    hp = 50
    def __init__(self):
        Enemy.__init__(self, "Goblin")

class Kobold(Enemy):
    hp = 100
    def __init__(self):
        Enemy.__init__(self, "Kobold")

print ("welcome to Ryder's house of monstrositys!!!")
time.sleep (2)
print ("can you escape?")
time.sleep (1)

difficulty = GetChoice("What difficulty would you like?", ["EASY", "NORMAL", "HARD", "DEBUG"])
if difficulty != "DEBUG":
    print ("... preparing dungeon ...")
    time.sleep (2)
    counter = 3
    while counter > 0:
        print (".")
        time.sleep (0.5)
        counter = counter - 1

if difficulty == "EASY":
    enemy = Beatle()
elif difficulty == "NORMAL":
    enemy = Goblin()
elif difficulty == "HARD":
    enemy = Kobold()
elif difficulty == "DEBUG":
    enemy = Goblin()

print("First encounter: " + enemy.name + "!")
choice = GetChoice("What would you like to do?", ["RUN", "FIGHT"])
if choice == "RUN":
    print ("GAME OVER!")
    exit ()
elif choice == ("FIGHT"):
  print ("Battle Begin!")
while enemy.hp and Player.hp > 0:
    print ("Your Turn!")
    player = Player()
    choice = GetChoice("What would you like to do?", ["ATTACK", "MAGIC", "INVENTORY", "RETREAT"])
    if choice == "INVENTORY" and player.inventory == "empty":
        print ("your inventory is empty!")
        choice = GetChoice("What would you like to do?", ["ATTACK", "MAGIC", "INVENTORY", "RETREAT"])
    if choice == "ATTACK":
        choice = GetChoice("What weapon would you like to use?", ["SWORD", "BOW"])
        if choice == "SWORD":
            weapon = Sword()
        elif choice == "BOW":
            weapon = Bow()
        else:
            print("[Error] Unknown weapon: " + choice)
        weapon.TryHit(enemy)
    elif choice == "MAGIC":
        choice = GetChoice("Which spell would you like to cast?", ["FIRE", "HEAL"])
        if choice == "FIRE":
            player.mana = player.mana - 10
            fireball = Fireball()
            fireball.TryCast(enemy)
            time.sleep(0.5)
            print ("you have", player.mana, "mana left")
        elif choice == "HEAL":
            mana = mana - 15
            healing = Healing()
            healing.TryCast(player)
            print ("you have", mana, "mana left")
    if enemy.hp <= 0:
        break
    time.sleep(1)
    print ("enemy turn!")
    if enemy.name == "Beatle":
        print ("the beatle lunges forward biting you!")
        time.sleep(1)
        damage = 5
        print  ("you take", damage, "damage")
        newhp = player.hp - damage
        player.hp = newhp
        print ("you have", player.hp, "hp remaining")
    elif enemy.name == "Goblin":
        print ("the Goblin slashes at you with there claws")
        time.sleep(1)
        damage = 10
        print  ("you take", damage, "damage")
        newhp = player.hp - damage
        player.hp = newhp
        print ("you have", player.hp, "hp remaining")
    elif enemy.name == "Kobold":
        print ("the Kobold slashes at you with there rusty sword")
        time.sleep(1)
        damage = 15
        print  ("you take", damage, "damage")
        newhp = player.hp - damage
        player.hp = newhp
        print ("you have", player.hp, "hp remaining")
    time.sleep(0.75)
    
if enemy.hp <= 0:
    print ("you win!")
elif player.hp <= 0:
    print ("you lose!")
    exit ()
print ("when you defeat the", enemy.name, "a chest appears!")
choice = GetChoice("do you open it?", ["YES", "NO"])
if choice == "YES":    
    if difficulty == "easy":
        print ("you recieve 10gp!")
        player.gp = player.gp + 10
        time.sleep(0.25)
        print ("you now have", player.gp+ "gp!")
    if difficulty == "normal":
        print ("you recieve 20gp!")
        player.gp = player.gp + 20
        time.sleep(0.25)
        print ("you now have", player.gp+ "gp!")

1 Answer

0 votes
answered Nov 24, 2021 by Peter Minarik (84,720 points)

You have to consider the lifespan (scope) of your variables.

If you check your code around line 124, you can see that you instantiate the Player class every time when it is the player's turn to fight. No wonder the previously taken damage does not carry over.

In game's term, it's like every round is fought by a new player.

123    print ("Your Turn!")
124    player = Player()

You have to make sure the same instance of the Player class is used throughout the whole game. I'd simply move the instantiation before the player would enter the dungeon.

That is, move line 124 to e.g. before line 115.

Good luck in the dungeon. ;)

Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and and receive answers from other members of the community.
...