0

I was making a short game just to try out using classes and functions, but when I modify a attribute of a class using another class it only returns the original, unmodified attribute. How can I solve this issue? Below is my code. I have found that assigning the new hp to a variable works but I want to modify the attribute of the class with another class directly. Thank you

import random

class Player:
    """Describes the main player."""
    def __init__(self,level,health,will):
        """Initializes stats"""
        self.level = level
        self.health = health
        self.full_health = health
        self.will = will

    def default_attack(self, enemy_hp):
        """Normal attack that damages enemy target."""
        damage = 0
        if random.randint(1,100) <= 95:
            damage = (self.level * 2)
            critical_hit = random.randint(1,10)
            if critical_hit == 1:
                damage += int(self.level * 0.5)
                print("Critical hit!")
        enemy_hp -= damage
        print("The enemy took " + str(damage) + " damage.")

    def heal(self):
        """Heals self by 10%."""
        recovered = int(self.full_health * 0.10)
        self.health += recovered
        if self.health > self.full_health:
            self.health = self.full_health
        print("Recovered " + str(recovered) + " HP.")


class enemy:
    """Describes common easy enemy."""
    def __init__(self,level,health,magic):
        """Initializes stats"""
        self.level = level
        self.health = health
        self.magic = magic

    def default_attack(self, protag_hp):
        """Normal attack that damages protagonist target."""
        chance_to_hit = random.randint(1,100)
        damage = 0
        if chance_to_hit <= 90:
            damage = (self.level * 2)
            if chance_to_hit <= 10:
                damage += int(self.level * 0.5)
        protag_hp -= damage
        print("You took " + str(damage) + " damage.")

# Spawn enemies
def spawn_enemy(level):
    if level == "easy":
        level = random.randint(1,5)
        health = int(level * 5)
        magic = int(level * 2)
        enemy = {"level": level,"health": health,"magic": magic}
        return enemy
    elif level == "medium":
        level = random.randint(6, 10)
        health = int(level * 5)
        magic = int(level * 2)
        enemy = {"level": level, "health": health, "magic": magic}
        return enemy
    elif level == "hard":
        level = random.randint(11, 15)
        health = int(level * 5)
        magic = int(level * 2)
        enemy = {"level": level, "health": health, "magic": magic}
        return enemy

# Start
enemy_minion = enemy(**spawn_enemy("easy"))
print("The enemy's level is " + str(enemy_minion.level) + ".")
Rachel = Player(1,100,10)
Rachel.default_attack(enemy_minion.health)
enemy_minion.default_attack(Rachel.health)
print(Rachel.health)
Rachel.heal()
print(Rachel.health)

My output and I put a comment next to what part I am concerned about.

The enemy's level is 3.
The enemy took 2 damage.
You took 7 damage.
100                   # here I want it to say 93
Recovered 10 HP.
100
2
  • protag_hp -= damage overwrites the local name protag_hp, not changing the underlying value. You might have better luck putting return protag_hp at the end of the function, and then calling it as Rachel.health = enemy_minion.default_attack(Rachel.health), as then the returned value will be assigned to Rachel.health. Commented Jul 8, 2020 at 18:39
  • protag_hp isn't any sort of "attribute of a class". It's just a numeric value, that happened to come from an attribute - but has absolutely no ongoing connection with the class. One option is to pass Rachel to the method, rather than Rachel.health - assuming that this parameter is named protag, you could then do protag.health -= damage to get your desired result. Commented Jul 8, 2020 at 18:43

1 Answer 1

1

Here, when you pass the health attribute to the enemy's default attack function, you aren't passing that variable, you are just passing its value. So, when you edit it inside the function, it doesn't affect the variable.

To go around this, rather than passing in the health, pass in the character class:

enemy_minion.default_attack(Rachel)

and edit the character's health inside the attack functions:

def default_attack(self, player):
        """Normal attack that damages protagonist target."""
        ...
        player.health -= damage  # Here is the change
        ...

You should also do the same for the player's attack function:

def default_attack(self, enemy):
        """Normal attack that damages enemy target."""
        ...
        enemy.health -= damage
        print("The enemy took " + str(damage) + " damage.")
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.