2

Using what I am learning in my programming classes, I am making a small text-based turn based combat game in C++. Keep in mind that I may not know how to use or be aware of more complex concepts.

I have a lot of variables in the game, bools for checking whether the player has certain items, ints for health, armor, etc. I know I shouldn't use global variables, so I was going to use pointers to pass variables between functions.

Normally this wouldn't be a problem:

attack(int *health, int *armor);

but I have something resembling this:

attack(int *health, int *armor, int *enemyHealth, int *enemyArmor, ......etc);

It's becoming tedious to type and using global variables would be an instant solution. But I want to know of another way. Also, sometimes when calling a function I don't need to pass "*armor" for example if the player isn't wearing any. This also means I need to create a lot of these:

if (*armor != nullptr)
{
    do things
}

Solutions? Sorry in advance if this wasn't clear. I'm new to this site and it might take me awhile to understand your answers. Thanks all!! :)

Here is the full code (There aren't many instances of this problem yet as I have just ran into it, but looking at my function calls will make it somewhat clear)

2
  • 6
    I think it's time you learn about classes/structs. Pick up a C++ book. Commented Nov 2, 2014 at 5:14
  • 1
    You use a structure and pass it around by pointer. Or you use references instead of pointers, if you're in C++. Commented Nov 2, 2014 at 5:14

3 Answers 3

1

The way to avoid passing hundreds of variables is to organize your data using classes or structs. The idea is you collect all the relevant variables together in one "user defined type" that models some part of the game.

As an example I have written a very small adventure game for you to examine to see how this can work:

The adventures of Wendy & Bob

#include <string>
#include <iostream>

// this just declares the makeup
// of weapons, it doesn't create any
struct weapon
{
    std::string name;
    int damage;
};

// this just declares the makeup
// of players, it doesn't create any
// NOTE: it contains a weapon
struct player
{
    bool alive;
    std::string name;
    bool male;
    int health;
    int armor;
    weapon weap;
};

// This performs a single attack
void attack(player& a, player& b)
{
    std::cout << "\n";
    std::cout << a.name;
    std::cout << " strikes at ";
    std::cout << b.name;
    std::cout << " with " << (a.male?"his":"her") << " ";
    std::cout << a.weap.name;

    int damage = std::rand() % a.weap.damage;

    if(damage == 0)
    {
        std::cout << " and " << (a.male?"he":"she") << " misses.";
        return;
    }

    int wound = damage - b.armor;

    if(wound <= 0)
    {
        std::cout << " causing no harm.";
        return;
    }

    std::cout << " inflicting ";
    std::cout << wound;
    std::cout << " damage";

    b.health -= wound;

    if(b.health < 0)
    {
        b.alive = false;
        std::cout << " killing " << (b.male?"him":"her") << " dead!";
    }
    else if(b.health < 10)
    {
        std::cout << " causing " << (b.male?"him":"her") << " to stumble!";
    }
    else if(b.health < 20)
    {
        std::cout << " causing " << (b.male?"him":"her") << " to stagger!";
    }
    else if(b.health < 30)
    {
        std::cout << " irritating " << (b.male?"him":"her") << " somewhat.";
    }
}

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

    std::cout << "Welcome to the Adventures of Wendy & Bob\n";

    // We actually create a player here
    player bob;

    // Give it relevant data
    bob.alive = true;
    bob.name = "Bob";
    bob.male = true;
    bob.armor = 4;
    bob.health = 100;
    bob.weap.name = "knife";
    bob.weap.damage = 16;

    // same with another player
    player wendy;

    wendy.alive = true;
    wendy.name = "Wendy";
    wendy.male = false;
    wendy.armor = 3;
    wendy.health = 100;
    wendy.weap.name = "blade";
    wendy.weap.damage = 20;

    // Keep fighting till someone dies!
    while(bob.alive && wendy.alive)
    {
        attack(bob, wendy);

        if(wendy.alive && bob.alive)
            attack(wendy, bob);
    }

}
Sign up to request clarification or add additional context in comments.

Comments

0

You can put your variables in a struct and pass that.

In C++ you would preferentially pass it by reference, using &, but that's not available in plain C.

In C++ you would also, preferentially, use a class instead of a struct, and restrict access to the variables so that they can only be updated via member functions of the class. That gives you better control. But I digress – start with the struct! ;-)

1 Comment

Well that seems to be the general consensus :) Haha we're actually learning about those after our first exam. I'll crack open that book right now and get a head-start. Thank you humans!
0

I'm going to agree with the others and say: yes, you should be looking at classes. The reason they are suggesting that is because of something called encapsulation. The idea is that you group related things together in a single class and have everything else interact with that class using an interface.

ex. Let's say you design a game with a player character and every time the player gets hit she must always slow down. So, you would have health and speed as private variables. That way nothing outside the class can change them. Then you would have a function called "takeHit" (or something like that) and that function would deduct health and reduce player speed. That way, you can't accidentally reduce the health without reducing the speed too. This makes it easy for you to write code that adheres to your design. It also makes it easier to think about your code because, most of the time, you only care about what your interfaces allow you to do with your objects.

Update: Oh, I should also mention that when you create your player inside of a class, it makes it easy to have more than one player.

Comments

Your Answer

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