Unintentionally changing the value of the object

Asked

Viewed 44 times

0

Project link: https://github.com/ThomasCaio/RPG2

self.enemy.Damage returns : {'Physical': 45, 'fire': 25}

self.Defense returns : {'Physical': 50}

def receive_damage(self):
    damage = self.enemy.damage
    defense = self.defense
    full_damage = 0
    for dmg in damage:
        full_damage += damage[dmg]
    for dmg in damage:
        if defense.get(dmg):
            damage[dmg] -= defense[dmg]
            if damage[dmg] < 0:
                damage[dmg] = 0
    final_damage = 0
    for dmg in damage:
        final_damage += damage[dmg]
    print(f'{self.enemy} atacou {self} em {full_damage} de dano.')
    print(f'{self} bloqueou {full_damage-final_damage} de dano e recebeu {final_damage}.')
    self.health -= round(final_damage)

The player’s first damage is working perfectly. This function (receive_damage) has both player and monster, but when an attack occurs:

damage[dmg] -= defense[dmg]

this line of code reduces the damage of the monster. I am unable to solve this!

1 answer

1


Probably ( I say probably because I don’t understand very well how your game works ) the problem is that you have used -= instead of a subtraction operator -. The result of this is that you will have your own damage reduced by the defense. Example:

def ataca():
    global dano,defesa
    dano -=  defesa
    print("O monstro te deu %.2f de dano."%dano)

dano = 30
defesa = 1.5

for i in range(30):
    ataca()

The right thing should be:

def ataca():
    global dano_total,defesa
    dano_causado = dano_total
    dano_causado -=  defesa
    print("O monstro te deu %.2f de dano."%dano_causado)

dano_total = 30
defesa = 1.5

for i in range(30):
    ataca()

As you saw in the example above, to fix the problem just create an auxiliary variable to undergo changes from the current round, without changing the original variable. If by chance you did damage = self.enemy.damage wanting to create a helper variable, unfortunately this code is also wrong. From what I see, the self.enemy.damage is an object. If you pass a variable containing the reference of an object to another variable, all the changes of one variable will be reflected in the other. This is because you are not passing the object itself, but rather the memory address. If the self.enemy.damage be a dictionary, use the method copy to receive the reference of a new object with the same elements. Example:

damage = self.enemy.damage.copy()
  • Because then, you shouldn’t just reduce the value of the damage variable instead of reducing the damage of self.enemy.Damage?

  • Not if you’re gonna use a fixed damage. Example: Let’s say the enemy has a damage of 90, what you can do is create an auxiliary variable to undergo all the changes like reducing it by the player’s defense. This way, in a given round, the damage suffered can be 75 as it was calculated plus the player’s defense, but the monster’s damage remains 90. If you change the damage directly from the monster in the next rounds, the monster’s damage will be less as in the example I gave in the answer.

  • And isn’t this auxiliary variable what I did on Damage? I put her to take the monster’s damage and suffer the reduction but still alters the monster’s damage.

  • If your "auxiliary variable" is on line 3 of your function, then you are wrong. From what I see, the variable "Damage" is a dictionary or some kind of object. You should remember that when you pass an object to a variable, you are not passing the object but a memory address. That is, the changes of the variable "Damage" are also happening in "self.enemy.Damage". For this not to happen just use the "copy" method of the dictionary ( if it is a dictionary ) to return an object with the identical elements but different from the original in memory.

  • Perfect! It worked right.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.