0

I've been at this for a few hours now. I am making a small game in C++ and I am trying to figure out how I can edit variables from inside of a function. I can place the variables in the main() and edit them them there no problem, but I can't figure out what I need to do to edit from a function. Below is the function.

void HeroSelect(string& hero)
{
    int gold = 20, health = 5, attack = 5, stats[2] = { health, attack };
    string weapon;
    cout << "Please choose your hero.\n";
    cin >> hero;
    if (hero == "Warrior" || hero == "warrior")
    {
        weapon = "Broad Sword";
        cout << "You are a Warrior wielding a " << weapon << endl;
        cout << "Good choice.\n"
            << "You start out with " << gold << " gold." << endl
            << "You have " << stats[0]<< " health and " << stats[1] << " attack.\n";
    }

Above is the function definition and I want to be able to edit the health when the player gets attacked or say gets a stronger weapon. Below is the main() of the script.

void main()
{
    double enter, room1, room2, room3, room4, BossRoom;
    int,   gold = 20; //This is used as part of check inventory and will be subtracted when necessary
    string hero, weapon;


    //Set decimal two places
    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.precision(2);

    Intro(enter);

    cout << "The first step in this adventure is to choose your hero. You can choose a warrior, a wizard, or an archer.\n";

    HeroSelect(hero);

So let's say he gets a new weapon and it gives +1 attack how do I reflect that in the function? Would I create a separate function for this?

As the player goes through the game, they can type in "stats" whenever, and when they do I want it to display their current health and attack and then essentially just loop back to the beginning of the room or fight they are in.

I know I can make the changes to the variables if I made all of my loops and all of my if-else statements in main(), but I wanted to try this and keep my main script clean. I did stats as an array, because I think it is good to print the array as a list. Any help would be great. Thanks!

Matt
  • 79
  • 1
  • 8
  • 3
    I think you need to start over with your design. Lets think about the design for a while, you have a "hero", that sounds like an object there. You have a "weapon", another object. How should the "hero" know what "weapon" he or she have? Maybe the "hero" could have some kind of collection containing "weapons"? What else does a "hero" have? Maybe attributes like "health" or "strength"? How could that be incorporated into the "hero" object? – Some programmer dude Oct 01 '15 at 05:35
  • To make the variables visible within your functions, the easiest way would be to move them out of `main` and make them [global variables](http://stackoverflow.com/questions/9702053/how-to-declare-a-global-variable-in-c). This would better match the programming style you're currently using, but both globals and your lack of structure in storing data are considered [anti-patterns](https://en.wikipedia.org/wiki/Anti-pattern) in [tag:c++]. Try learning about [class design](http://www.cprogramming.com/tutorial/class_design.html) for a bit then come back to the game. – MooseBoys Oct 01 '15 at 05:53
  • Thank you for the input, and as others mentioned, I will look up classes a bit more in depth and rewrite it. Still learning! – Matt Oct 01 '15 at 05:55

3 Answers3

4

You may need to do a refresher on C++ and OOP. Your concept is not bad, but you can possibly make it better. (Granted if you really want to do something in a particular fashion, and you are able to do it in such fashion, then by all means just do it :P).

As mentioned in your comments, a re-engineering of the game design may be in order. You will want to establish a Hero class, with multiple variables or sub-classes as the attributes (for example: strength, health points, weapons class, armor class, etc. (We could go into a lower-level description, but i don't think it's necessary yet). If you plan to have multiple weapons, a weapons class might be a good idea as well, for example you could define the weapon stats: attack damage, attack rate, weapon durability etc...

In these classes you can create "Helper Functions" which you can then use to change the stats of the associated objects. Helper function could be public functions which would allow you to increment/decrement hero health or perhaps a helper function that will increase attack damage?

It seems like you're doing a good job learning, so hopefully you can visualize the idea here. Either way, keep on grinding and feel free to ask for a more in depth answer whenever necessary! I'd love to see your game when your ready for some testing!

Eissa
  • 700
  • 5
  • 17
  • I have an idea of what you are talking about, and I kind of thought this was what I was doing. Apparently not! I appreciate the advice and will read up a bit more on what you listed. And I would be honored to show it to you when I finish! Thanks – Matt Oct 01 '15 at 05:57
2

There are several ways to handle this. The first being to create a class which is covered in the comments and the answer by ejsd1989.

The second option is to make these variables global variables by creating them in the main and just pass them through each function by reference. This keeps your main clean like you desired.

For example:

void HeroSelect(string& hero, int &gold, int &health)

The third option is very similar to the second, and it is to store these variables in an array and just modify the array with each function.

Essentially, it boils down to creating a class or passing the variables to the functions you wish to use.

Burgan
  • 880
  • 1
  • 7
  • 24
  • The modify an array is a good idea. Have the array display all stats, and then provide the array changes in the function is good. I may also try that. – Matt Oct 01 '15 at 06:00
0

Main is not a script and there are some conceptual problems with design in question. Word by word answer would be: pass function parameters by reference. But it would not be a good solution for the task. Please consider this example:

uint menu;
Hero * hero;
Room entrance, next[5];

entrance.Enter();

std::cout << "1st step in this adventure is to choose your hero." <<std::endl;
std::cout << "You can choose " <<std::endl;
std::cout << "(1)       a warrior " << std::endl;
std::cout << "(2) ,     a wizard" << std::endl;
std::cout << "(3) , or an archer." << std::endl;
std::cout << "Please choose your hero." << std::endl;
std::cin >> menu;
switch( menu )
{
    case  3 : { hero = new Archer;  break; }
    case  2 : { hero = new Wizard;  break; }
    default : { hero = new Warrior; break; }
}
hero->Weapon();
hero->Gold();
hero->Health();
hero->Attack();

std::cout << "Which room to enter? 1..5" << std::endl;
std::cin >> menu;

next[menu - 1].Enter();
if( 5 == menu )
{
    std::cout << "You are attacked by a troll!" << std::endl;
    hero->SetHealth( hero->GetHealth() >> 1 );
}
hero->Health();

You can handle hero types, room instances this way. Find properties of them that could be generalized and make differences via members or inheritance. Design it more carefully and you could minimize e. g. tons of couts and duplicated code branches.

class Room
{
    static uint cntr;
    std::string name;
public:
    Room() : name ( "Room#" ) { if( cntr < 5 ) { name[ name.size() - 1 ] = cntr + '0';  } else { name = "BossRoom"; }  ++cntr; }
    void Enter() { std::cout << "You have entered " << name << "!" << std::endl; }
};

uint Room::cntr;

struct Limint
{
    uint max;
    uint curr;
    Limint( uint init ) : max ( init ), curr( init ) {}
};

class Hero
{
protected:
    std::string     type;
    uint            gold;
    Limint          hp;
    Limint          attack;
    std::string     weapon;
public:
    Hero() : type( "Hero" ), gold( 20 ), hp( 50 ), attack(5), weapon( "Kitchen knife" ) {}
    uint GetHealth() { return hp.curr; }
    void SetHealth( uint health ) { health = std::min( health, hp.max ); hp.curr = health; }
    void Weapon() { std::cout << "You are a " << type << " wielding a " << weapon << ". Good choice!" << std::endl; }
    void Gold() { std::cout << "You start out with " << gold << " gold." << std::endl; }
    void Health() { std::cout << "You have " << hp.curr << " / " << hp.max << " health." << std::endl; }
    void Attack() { std::cout << "You have " << attack.curr << " / " << attack.max << " attack." << std::endl; }
};

class Warrior : public Hero
{
public:
    Warrior() { type = "Warrior"; weapon = "Broad sword"; }
};

class Wizard : public Hero
{
public:
    Wizard() { type = "Wizard"; weapon = "Magic stick"; }
};

class Archer : public Hero
{
public:
    Archer() { type = "Archer"; weapon = "Crossbow"; }
};

Have fun!

renonsz
  • 571
  • 1
  • 4
  • 17