1

Recently I've been working on an inventory system for a text-based game that uses a global array for the inventory system and a corresponding function to read true or false in said array. The problem I've run into is this, the function I'm using to modify the array

void playerGet(bool items[], int itemNumber) //this function takes an assigned argument of the array indices variable, and changes that array indices from true, to false. 
{
    items[itemNumber] = true;
}

only modifies the array within the scope of the function its housed in. The array is defined in a .cpp file like this:

void inventoryArray(bool items[]) //This function establishes all the items in the game, the true false statement expresses whether or not the item is in the player's inventory. 
{
    items[WEAPON_RELIC_RIFLE] = false;
    items[WEAPON_SCALPEL] = false;
    items[MISC_ACTION_FIGURE] = false;
    items[MISC_FIRE_EXTINGUISHER] = false;
    items[MISC_LIFE_RAFT] = false;
}

and is then declared in a .h file like this:

void inventoryArray(bool items[]);

the enums used in the array are defined in a header file like this:

enum equipment //This declares a list of enums for each item in the game, consumables, not included. 
{
    WEAPON_RELIC_RIFLE, // = 0
    WEAPON_SCALPEL, // = 1
    MISC_ACTION_FIGURE, // = 2
    MISC_FIRE_EXTINGUISHER, // = 3
    MISC_LIFE_RAFT, // = 4
    MAX_EQUIPMENT
};

the function that reads the inventory array is this:

void twoScavengerCombat(bool items[])
{
    for (int item = 0; item < MAX_EQUIPMENT; ++item)
    {
        if (items[item] == true) //if true proceed
        {
            switch (item)
            {
            case 0: //if array indices identifier = 0, print relic rifle
                cout << "1: Use the Relic Rifle\n";
                break;
            case 1:
                cout << "2: Use the Scalpel\n";
                break;
            case 2:
                break;
            case 3:
                cout << "3: Use the Fire Extingusher\n";
                break;
            case 4:
                cout << "4: Use the Life Raft\n";
                break;
            default:
                cout << "Error";
                break;
            }
        }
        else
            cout << "Option Unavailible\n"; //if false print Option Unavailible
    }

compiled, with the array and enums headers declared the main file would look like this:

int toolSearch()
{
   bool items[MAX_EQUIPMENT];
    inventoryArray(items);
   playerGet(items, 0);
}

void twoScavengerCombat(bool items[])\\ declared in this file, but since its just above here i left it as a forward declaration to save space

int main()
{
   toolSearch();
   twoScavengerCombat(items);
   return 0;
}

Ideally this would produce the result: Use Relic Rifle Option Unavailable Option Unavailable Option Unavailable Option Unavailable

but instead it produces 5 Option Unavailable's. What am I missing?

  • 3
    The `items` declared in `toolSearch()` is local to that function and would be overriding any globally declared array. – Jonathan Potter Aug 23 '15 at 01:20
  • @JonathanPotter, do you mean the one declared in `inventoryArray(items)`? If so how do you propose i change it, because i just tried removing that line, and the result was unchanged. – Sawyer Adlai Vierra-Hatch Aug 23 '15 at 01:23
  • 1
    @SawyerAdlaiVierra-Hatch `inventoryArray` doesn't declare any arrays. As much as it looks like it does, it doesn't. As a matter of fact, none of your code snippets declares a global array. – PaulMcKenzie Aug 23 '15 at 01:28
  • @PaulMcKenzie Do you mean the `void inventoryArray(bool items[])`, because unless I'm mistaken that function defines the array and the items in it. If you mean teh `inventoryArray` in `toolsearch()` then that should be acting as a declaration of the function which defines the array. If I'm incorrect in either assumption, can you show me the correct way to do it. – Sawyer Adlai Vierra-Hatch Aug 23 '15 at 01:34
  • 1
    @SawyerAdlaiVierra-Hatch *because unless I'm mistaken that function defines the array and the items in it* You're mistaken. Where in that function is an array declared? All you're doing is passing a pointer to `bool`, and given that pointer, accessing offsets from that pointer. Again, no array declaration is being done. – PaulMcKenzie Aug 23 '15 at 01:37
  • 4
    I'm sorry to have to tell you this, but you appear to be attempting something well beyond your ability. I respect your desire to challenge yourself, but you won't learn anything by reaching too far. You must **try something simpler first.** I suggest you start by playing around with the *simplest code you can devise* that does anything with a global array. Once you have that working perfectly, you can add use what you've learned in your game. – Beta Aug 23 '15 at 01:37
  • 1
    @SawyerAdlaiVierra-Hatch The question is worded assuming that there is a global array. The problem is that there is no global array. You declared a local array in `toolSearch`, and passed a pointer to the first element of this local array to `inventoryArray`. Once `toolSearch` returns, that local array is gone. So once that array is gone, what's left? – PaulMcKenzie Aug 23 '15 at 01:43
  • @PaulMcKenzie, again, correct me if I'm wrong, but normally an array would be declared by `int items[5]` followed by a declaration of indices as such: `items[1]`, if that's the case, the definition in is done in the parameters of the function, replacing a formal number with `MAX_EQUIPMENT` so that the enumerated list can grow w/o having to manually change the size of the array then below in the body of the function the indices are declared like normal, just replacing the formal number with an enumerator for clarity of code, then a value is assigned to the indices. Is that not correct? – Sawyer Adlai Vierra-Hatch Aug 23 '15 at 01:47
  • @PaulMcKenzie, the array is declared in a header file, is i wrote and it takes the form of `void inventoryArray(bool items[]) //This function establishes all the items in the game, the true false statement expresses whether or not the item is in the player's inventory. { items[WEAPON_RELIC_RIFLE] = false; items[WEAPON_SCALPEL] = false; items[MISC_ACTION_FIGURE] = false; items[MISC_FIRE_EXTINGUISHER] = false; items[MISC_LIFE_RAFT] = false; }` the `inventoryArray(items)` in `toolsearch()` should just be declaring this functions existence. correct? – Sawyer Adlai Vierra-Hatch Aug 23 '15 at 01:50
  • @Beta, Im doing a few things to educate myself, and while I'm aware this may be a bit of an overreach, im working on this project with a few friends, and since i only need to have the inventory designed once fro this project, i figured I'd just crank it out, so that they aren't waiting for me to learn the fundamentals. Again if this were the only way i was educating myself, i'd agree with you 10/10. – Sawyer Adlai Vierra-Hatch Aug 23 '15 at 01:53
  • 1
    @SawyerAdlaiVierra-Hatch `void inventoryArray(bool items[]);` That does not declare an array. That is a function declaration, and it takes a `bool*` argument. It is no different than this: `void inventoryArray(bool* items);` So again, you have not posted any code that declares a global array. I've gone through all of your snippets of code, and nowhere is a global array actually declared. – PaulMcKenzie Aug 23 '15 at 01:55
  • @PaulMcKenzie, i see, perhaps you could create an answer suggesting a different course of action then? Unless its something easy, then of course I don't mind you leaving it in the comments. – Sawyer Adlai Vierra-Hatch Aug 23 '15 at 01:58
  • 2
    @SawyerAdlaiVierra-Hatch See here: http://ideone.com/1ilFKW That demonstrates a declaration of a global array and having a function that sets the first two entries. – PaulMcKenzie Aug 23 '15 at 02:01
  • @PaulMcKenzie, I see what you are saying, but when i declared the array as listed in a .cpp file and then declared it in the .h file, the other files seemed unable to recognize the array. Every instance of the word items caused was labelled as "undefined". How would i get around this? – Sawyer Adlai Vierra-Hatch Aug 23 '15 at 02:12

1 Answers1

1

You would want

//bunch of #include<> directives
bool items[MAX_EQUIPMENT];

int toolSearch()
{
    inventoryArray();
    playerGet( 0);
}

void twoScavengerCombat()
...
// other functions here

int main()
{
   toolSearch();
   twoScavengerCombat();
   return 0;
}

Note that bool items[MAX_EQUIPMENT]; is not defined in a function. It is off on it's own at the top of the file in plain view of anything defined below it. This is what it means to be global. Anyone and everyone can access it, if they know where it is or you tell them where it is with an extern statement. It is created when the program starts (even before main and that can cause some really fun debugging if the initialization logic of the variable is faulty) and dies only when the program does.

Lightness Races in Orbit delves a bit deeper here, but is more concerned with making a global variable extend past a single file

There is no need to pass items into any function because everyone can see items The downside is there is one and only one items so if you have multiple players each with different item lists, you're going to have problems.

You might want to look into std::vector (resizable array) and std::map (which will allow you to look items up by name items["sword"].attackFoe(foe);) and std::set (which makes it really easy to see what a player has (if (items.find("Vorpal Hand Grenade") != items.end()) BlowStuffUp();) rather than having to search through each item every time.

Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54