0

I'm trying to code a very very simple text-based game for my senior project (meaning I know that my code is very basic and absolutely butchers what you normally will want to do, but with my current knowledge I can't do much beyond that until college). I was having a lot of trouble with passing by reference, so I decided that it would be easier to make all of the variables global. However, I need to be able to change these variables from within functions. As you can see, the damage variable is equal to 4+level+strength, but when I try to output it after changing the strength through the getattributes function, it outputs as 5. It only adds the level and the 4. At first, I thought that the issue was that the code was interpreting the strength as 0 still, but whenever I tell it to output strength, it outputs the correct value that I changed it to. So why is it only adding the value for strength that was declared in the top instead of the new value? Even though it can recognize the new value. I've spent hours trying to get this to work, so I would really appreciate some help. Attached is the extern variables in the header file, and the functions file with the declared variables and the functions. The main issues are with the dhcheck(), getattributes(), and floor_menu() functions. Thank you!

Header extern variables:

extern int strength;
extern int dexterity;
extern int constitution;
extern int agility;
extern int luck;
extern int experience;
extern int level;
extern int damage;
extern int health;
extern int dodge;
extern int defense;

function file:

#include <iostream>
#include <iomanip>
#include <cstring>
#include <vector>
#include <cstdlib>
#include <fstream>
#include "Header.h"

using namespace std;

int strength = 0;
int dexterity = 0;
int constitution = 0;
int agility = 0;
int luck = 0;
int experience = 0;
int level = 1;
int damage = 4 + (::level + ::strength);
int health = 100 + (::level * 10 + ::constitution * 5);
int dodge = 5 + ::agility;
int defense = 1 + ::dexterity;

void start_menu(int& c) {
    c = 0;
    cout << "                     THE DUNGEON\n";
    cout << "---------------------------------------------------------\n";
    cout << "---------------------------------------------------------\n";
    cout << "1) Start a new game\n";
    cout << "2) Load an existing game\n";
    cout << "3) Exit the game\n";
    cin >> c;
    if (c >= 1 && c <= 3) {
        return;
    }
    else {
        cin.clear();
        cin.ignore(1000, '\n');
        cout << "\n";
        c = 0;
        return;
    }
}

void get_name(string& n) {
    cout << "Please enter your name\n";
    cin >> n;
    cout << "\n\nWell hello " << n << "!  It's nice to meet you! *Although I'll probably never see you again...*\n";
    return;
}
void get_attributes() {
    ::strength = 0;
    ::dexterity = 0;
    ::constitution = 0;
    ::agility = 0;
    ::luck = 0;
    bool finish = false;
    do {
        int x = 20 - ::strength - ::dexterity - ::constitution - ::agility - ::luck;
        int y = 0;
        cout << "What are you skills, brave warrior?\n\n";
        cout << "You have " << x << " skill points left to distribute. Choose which skill to add or remove points from.\n\n";
        cout << "1) Strength (Affects damage) " << ::strength << " points currently in Strength.\n";
        cout << "2) Dexterity (Affects defense, critical hit chance, and critical hit damage) " << ::dexterity << " points currently in Dexterity.\n";
        cout << "3) Constitution (Affects total health) " << ::constitution << " points currently in Constitution.\n";
        cout << "4) Agility (Affects who goes first and chance to dodge) " << ::agility << " points currently in Agility.\n";
        cout << "5) Luck (Affects loot from chests and enemy drops) " << ::luck << " points currently in Luck.\n";
        cout << "6) Finish distributing attributes\n";
        cin >> y;
        if (y == 1) {
            cout << "How many points would you like to put into Strength?\n\n";
            cin >> ::strength;
            cout << "\n\n";
            if (::strength < 0) {
                cout << "You cannot enter a negative value. Try again.\n\n\n";
                ::strength = 0;
            }
            else if (::strength + ::dexterity + ::constitution + ::agility + ::luck > 20) {
                cout << "Total sum of attributes cannot be greater than 20. Try again.\n\n\n";
                ::strength = 0;
            }
            else if (::strength >= 0 || ::strength <= 20) {
                cout << "Strength has been set to " << ::strength << ".\n\n\n";
            }
            else {
                cout << "You must enter a valid input. Restart.\n\n\n";
                cin.clear();
                cin.ignore(1000, '\n');
                cout << "\n";
                ::strength = 0;
                void get_attributes();
            }
        }
        else if (y == 2) {
            cout << "How many points would you like to put into Dexterity?\n\n";
            cin >> ::dexterity;
            cout << "\n\n";
            if (::dexterity < 0) {
                cout << "You cannot enter a negative value. Try again.\n\n\n";
                ::dexterity = 0;
            }
            else if (::strength + ::dexterity + ::constitution + ::agility + ::luck > 20) {
                cout << "Total sum of attributes cannot be greater than 20. Try again.\n\n\n";
                ::dexterity = 0;
            }
            else if (::dexterity >= 0 || ::dexterity <= 20) {
                cout << "Dexterity has been set to " << ::dexterity << ".\n\n\n";
            }
            else {
                cout << "You must enter a valid input. Restart.\n\n\n";
                cin.clear();
                cin.ignore(1000, '\n');
                cout << "\n";
                ::dexterity = 0;
                void get_attributes();
            }
        }
        else if (y == 3) {
            cout << "How many points would you like to put into Constitution?\n\n";
            cin >> ::constitution;
            cout << "\n\n";
            if (::constitution < 0) {
                cout << "You cannot enter a negative value. Try again.\n\n\n";
                ::constitution = 0;
            }
            else if (::strength + ::dexterity + ::constitution + ::agility + ::luck > 20) {
                cout << "Total sum of attributes cannot be greater than 20. Try again.\n\n\n";
                ::constitution = 0;
            }
            else if (::constitution >= 0 || ::constitution <= 20) {
                cout << "Constitution has been set to " << ::constitution << ".\n\n\n";
            }
            else {
                cout << "You must enter a valid input. Restart.\n\n\n";
                cin.clear();
                cin.ignore(1000, '\n');
                cout << "\n";
                ::constitution = 0;
                void get_attributes();
            }
        }
        else if (y == 4) {
            cout << "How many points would you like to put into Agility?\n\n";
            cin >> ::agility;
            cout << "\n\n";
            if (::agility < 0) {
                cout << "You cannot enter a negative value. Try again.\n\n\n";
                ::agility = 0;
            }
            else if (::strength + ::dexterity + ::constitution + ::agility + ::luck > 20) {
                cout << "Total sum of attributes cannot be greater than 20. Try again.\n\n\n";
                ::agility = 0;
            }
            else if (::agility >= 0 || ::agility <= 20) {
                cout << "Agility has been set to " << ::agility << ".\n\n\n";
            }
            else {
                cout << "You must enter a valid input. Restart.\n\n\n";
                cin.clear();
                cin.ignore(1000, '\n');
                cout << "\n";
                ::agility = 0;
                void get_attributes();
            }
        }
        else if (y == 5) {
            cout << "How many points would you like to put into Luck?\n\n";
            cin >> ::luck;
            cout << "\n\n";
            if (::luck < 0) {
                cout << "You cannot enter a negative value. Try again.\n\n\n";
                ::luck = 0;
            }
            else if (::strength + ::dexterity + ::constitution + ::agility + ::luck > 20) {
                cout << "Total sum of attributes cannot be greater than 20. Try again.\n\n\n";
                ::luck = 0;
            }
            else if (::luck >= 0 || ::luck <= 20) {
                cout << "Luck has been set to " << ::luck << ".\n\n\n";
            }
            else {
                cout << "You must enter a valid input. Restart.\n\n\n";
                cin.clear();
                cin.ignore(1000, '\n');
                cout << "\n";
                ::luck = 0;
                void get_attributes();
            }
        }
        else if (y == 6) {
            int z = 0;
            cout << "Are you sure that you are finished?  You have " << x << " points left to distribute\n\n";
            cout << "1) Yes, I am absolutely sure of how I distributed my attributes\n";
            cout << "2) No, I want to go back and change something\n";
            cin >> z;
            if (z == 1) {
                cout << "Wow, you truly are a mighty warrior.\n";
                void dhcheck();
                finish = true;
            }
            else if (z == 2) {
            }
            else {
                cout << "You must enter a valid input. Restart.\n\n\n";
                cin.clear();
                cin.ignore(1000, '\n');
                cout << "\n";
                void get_attributes();
            }
        }
        else {
            cout << "You must enter a valid input. Restart.\n\n\n";
            cin.clear();
            cin.ignore(1000, '\n');
            cout << "\n";
            y = 0;
            void get_attributes();
        }

    } while (finish == false);

}

void floor_menu() {
    int o = 0;
    void dhcheck();
    cout << ::damage << "\n\n\n\n";
    cout << "Level == " << ::level << "\n\n";
    cout << "Progress to next level == " << ::experience << "/" << (::level/0.07)*(::level/0.07) << "\n\n\n\n\n\n\n\n\n";
    cout << "Upon entering the dungeon, you find yourself in a small room with 3 passages.  Which do you choose to enter?\n\n\n";
    void encounter();
    cout << "1) Left passage\n";
    cout << "2) Forward passage\n";
    cout << "3) Right passage\n";
    cout << "4) Check inventory\n";
    cout << "5) Save and exit game\n";
    cin >> o;
    if (o == 1) {
        left_door();
    }
    else if (o == 2) {
        forward_door();
    }
    else if (o == 3) {
        right_door();
    }
    else if (o == 4) {
        inventory_menu();
    }
    else if (o == 5) {
        cout << "WIP\n\n";
    }
    else {
        cin.clear();
        cin.ignore(1000, '\n');
        cout << "\n";
        o = 0;
        cout << "Invalid input, please try again\n";
    }
}
void inventory_menu() {
    cout << "WIP\n\n";
}
void left_door() {
    cout << "You enter the door on your left, and encounter ";
}
void forward_door() {
    cout << "You enter the door ahead of you, and encounter ";
}
void right_door() {
    cout << "You enter the door to your right, and encounter ";
}
void small_slime() {

}

void encounter() {

}

void levelup() {
    if (::experience >= (::level / 0.07) * (::level / 0.07)) {
        ::level = ::level + 1;
        cout << "Congrats!  You have leveled up!  Your stats have increased, and you now have two more attribute points to distribute.\n\n\n";
        
        void dhcheck();
    }
}
void dhcheck() {
    ::damage = 4 + ::level + ::strength;
    ::health = 100 + (::level * 10) + (::constitution * 5);
    ::dodge = 5 + ::agility;
    ::defense = 1 + ::dexterity;
}
Dawson
  • 1
  • 1
    You have a lot of places in your code where you have something like `void dhcheck();` I assume you meant to call the function there, but that is a function declaration not a function call. You need to use `dhcheck();` to call the function. – Retired Ninja Mar 01 '22 at 20:47
  • 2
    Recommendation: the globals. Get them out of there. Make a nice class that aggregates all of the player's characteristics, allocate an instance in `main`, and pass a reference to the instance around. Global variables make the writing of code easy, but, because a global can be accessed at any time from any where every function in the program can have hidden side effects, the reasoning about the code's behaviour, and thus debugging and maintaining, becomes far more difficult than necessary. – user4581301 Mar 01 '22 at 20:58
  • As @RetiredNinja already mentioned you're not actually calling the function in that case. Usually you'd just forward-declare all the functions in a file, so you can call them from each other without the compiler complaining, e.g. [godbolt](https://godbolt.org/z/z4o1KcP1T). I'd recommend you to take a look into [classes](https://www.cplusplus.com/doc/tutorial/classes/) though, that would allow you to group all variables & data together, making the code easier to read – Turtlefight Mar 01 '22 at 20:59
  • 1
    _I was having a lot of trouble with passing by reference, so I decided that it would be easier to make all of the variables global._ No, don't do that, you're on the road to nowhere. [Learn how the language works](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) instead. – Paul Sanders Mar 01 '22 at 21:11
  • In most games similar to this, they place the attributes, such as strength and wisdom, into a class or structure called a Player. For example, this would allow them to handle a player and a bunch of Non-Player Characters (NPC), all by creating instances. Your code only supports one player, a global one. – Thomas Matthews Mar 02 '22 at 01:46
  • Also, by placing these into a `struct` or `class`, you can inherit from them and create monster classes. Monster's may have additional attributes to the player (like flying capability). – Thomas Matthews Mar 02 '22 at 01:48
  • You may be able to find public software for historical games like you are working on. Search the internet for "source code adventure game", "source code wumpus game". – Thomas Matthews Mar 02 '22 at 01:50

0 Answers0