[SOLVED] Modifying class variables using functions during a combat do while loop C++

Issue

Feel free to let me have it for being a noob here as I have only been programming for about a month in my spare time haha… but I made the terrible decision to try making an RPG, which I have since redacted while I keep learning the basics, and am now trying the most condensed form of an RPG-style combat system I could conceptualize, hoping I can expand on it later once I have learned more.

THE PROBLEM: I have a very basic understanding of C++ functions and classes, and my goal for practice is to create a series of character classes with RPG-esk stats and pseudo-random modifiers which I can call and do calculations upon. To test the combat system functions, I wanted to write a simple loop with output statements. Two preexisting characters, the hero and the enemy, attack each other in turns until one’s health drops to zero and the loop ends. Each attack is a simple base stat with a rand modifier, then with the later intention of adding an armor stat to mitigate some of the damage. The issue is I don’t quite understand how to call and modify the values in the classes yet.

The code I have so far (shown below) is providing me this error:

"message": "initial value of reference to non-const must be an lvalue"

I know where the problem is for the most part, but unable to figure out what is surely a simple fix to resolve the problem and continue with building out this (should be) straight forward looping fight sequence.

I have tried looking up pointers, and pass by references and adding additional functions to calculate the modifiers, as well as moving the class information around, but frankly, I’m still too new to see what it is I need to do. Any and all help is appreciated, including just pointing me in the right direction with a hint so I can hunt down the solution on my own. I’m sure once I get a basic understanding of what’s holding me up here, the rest I can muddle through. Thanks!

CURRENT CODE

#include <iostream>
#include <ctime>
#include <cstdlib>

class hero {
    public:
    int playerAttackMod;
    int playerDefenceMod;
    int playerHealth;
    int playerDamage;
    int playerDefence;
};

class enemy {
    public:
    int enemyAttackMod {rand() % 25 + 1};
    int enemyDefenceMod {rand() % 5 + 1};
    int enemyHealth {300};
    int enemyDamage = 50 + enemyAttackMod;
    int enemyDefence = 8 + enemyDefenceMod;
};

int main() 
{   
    srand(time(0));


void damageCalc();


    std::cout << "A hero and enemy meet and prepare to fight to the death!\n"
        << "Let's watch to see how it plays out!\n\n"
        << "The enemy strikes first!\n" 
        << "***********************************************************************" << std::endl;

    while (hero().playerHealth >= 0 && enemy().enemyHealth >= 0) {
        std::cout << "Hero's Health: " << hero().playerHealth << std::endl;
        std::cout << "Enemy's Health: " << enemy().enemyHealth << std::endl;
        
        std::cout << "The enemy attacks and does " << enemy().enemyDamage << " damage!\n";

        hero &playerHealth = hero().playerHealth - enemy().enemyDamage; //THIS APPEARS TO BE THE TROUBLE MAKER...BUT ITS PROBABLY A DEEPER ISSUE THAN THIS...

    }
        std::cout << "\nThe hero has died!\n";
 
}

Solution

There are a few potential issues with your code.

First, in your while loop, every time you write hero() or enemy() you create a new instances of the classes hero and enemy, respectively. That is also leading to the compiler error you received. Apart from the error, there is an other issue with that. Every new instance is initialized with the default values that you provided. This means that neither hero nor enemy are loosing any health. In addition, since you dont have any variables for holding the new instances they are deleted once the command where you called hero()orenemy()` is finished. What you could do instead instead is to create variables for the hero and enemy before the loop:

hero h;
enemy e;
while (h.playerHealth >= 0 && e.enemyHealth >= 0) {
 ...

The next problem is the missing default arguments in the hero class. In C++ built in types like int have no default values (in most cases). Thus, the members of hero can have any arbitrary value. So you should either add some default values to the class definition, or you could initialize all members once you create an instance of the hero class.

The next issue does arise from the changes I suggested earlier. If you create an instance of class enenmy the enemyAttackMod and enemyDefenceMod members get a random value. However, this value is not changed anymore. So you might removing the mods from the classes and add recalculate them in every loop iteration before adding them to your damage calculation. Unless of course if random but fixed mods is what you want.

The last thing is more about names. If you have a class hero or enemy, you can simplify the member names from enemyHealth to just health. When accessing the member you would yous e.health which already indicates that you are dealing with the health of the enemy instance e. That makes your code shorter and potentially easier to read. But this last issue is more a matter of taste than anything else.

Answered By – AchimGuetlein

Answer Checked By – Cary Denson (BugsFixing Admin)

Leave a Reply

Your email address will not be published.