santisegu26
santisegu26

Reputation: 1

Integer value keeps resetting in between function calls

I am trying to write what I expected to be a very simple program for a text-based game where a player unit and an enemy unit deal damage to each other until one unit hits 0 health. However, somehow both the player and the enemy are resetting to full health between each call of my attack function. This makes no sense to me because the unit health correctly updates in order to print within the attack function. Here is my code. I called the attack function multiple times in my code to demonstrate.

#include <iostream>

using namespace std;
 


class player; // this is to avoid a syntax error in the enemy attack function

class enemy
{
public:
    int health;
    int strength;
    int defense;
    enemy(int h, int s, int d);
    void attack(player u);
};

class player
{
public:
    int health;
    int strength;
    int defense;


    player(int h, int s, int d);
    void attack(enemy u);
};



player::player(int h, int s, int d)
{
    health = h;
    strength = s;
    defense = d;
    srand(time(NULL));
    cout << "You arrive to the battlefield..." << endl;
}

void player:: attack(enemy u)
{
    int damage = 0;
    damage = strength - u.defense + (rand() % 3);
    u.health -= damage;
    cout << "You strike the enemy and deal " << damage << " damage. The enemy now has " << u.health << " health.\n" << endl;
    
}

enemy::enemy(int h, int s, int d)
{
    health = h;
    strength = s;
    defense = d;
    cout << "An enemy has appeared!" << endl;

}
void enemy::attack(player u)
{
    int damage = 0;
    damage = strength - u.defense + (rand() % 6);
    u.health  -= damage;
    cout << "The enemy strikes you and deals " << damage << " damage. You now have " << u.health << " health.\n" << endl;
    
}

void battle()
{
    player p(50,35,20);// Both healths are set at 50
    enemy e(50,34,19);

    p.attack(e); // Target health resets after each attack function runs. Unsure why.
    //cout << e.health << endl;
    e.attack(p);    

    p.attack(e); 
    e.attack(p);

    p.attack(e); 
    e.attack(p);
    
}

int main()
{
    battle();
     
    return 0;

}

Upvotes: 0

Views: 170

Answers (2)

C0L.PAN1C
C0L.PAN1C

Reputation: 12243

Depending on if you only have one copy of the player object vs multiple you can just simply make void enemy::attack() without an argument.

If there's only one player ever, then you can just simply do e.attack() and not pass in the value and reference the player object.

Player could easily be a singleton class (since there's only one copy of it, ever). If there are multiple copies of Player or multiple players then this wouldn't work clearly.

Upvotes: 0

john
john

Reputation: 88092

It's simple enough. Your code is copying your objects and you are altering the hit points of the copied objects, not the original objects in battle. That's why it seems to reset when you go back to battle. You're making the common but incorrect assumption that C++ objects are references, but they are not, they are values and they do get copied.

Change this

void enemy::attack(player u)

to this

void enemy::attack(player& u)

The extra & makes u a reference, and not a copy, so the changes you make will affect the original object, not a copied object. Similar changes needed elsewhere.

Upvotes: 2

Related Questions