Like Tree3Likes
  • 1 Post By Elysia
  • 2 Post By laserlight

How to Make a Function Modify a Variable Globally Instead of Locally

This is a discussion on How to Make a Function Modify a Variable Globally Instead of Locally within the C++ Programming forums, part of the General Programming Boards category; Okay, so I've run into another weird problem that I'm not sure how to solve. So as part of the ...

  1. #1
    Registered User
    Join Date
    Jul 2012
    Posts
    36

    How to Make a Function Modify a Variable Globally Instead of Locally

    Okay, so I've run into another weird problem that I'm not sure how to solve. So as part of the text adventure I've been writing to help me learn C++, I built a function that displays the player's inventory and lets them select things from it and embedded it in a larger function that shows their stats, location, and character portrait. Those functions are as follows:

    Inventory function:
    Code:
    void  inventory (int healingpotion, int lightningbottle, int lockpick, int  halfhealingpotion, int inventorychoice, int healthstat, int  spikedhorseshoes)
    {
        cout << "You are carrying: (Select an item to use it, or type  \"9\" or an integer not tied to an inventory object to exit.) \n \n";
        if (healingpotion == 1)
        {
            cout << "1. Healing Potion (Sets health to 8!) \n";
        }
        if (halfhealingpotion == 1)
        {
            cout << "2. Half Healing Potion (Sets health to 5!) \n";
        }
        if (lightningbottle ==1)
        {
            cout << "3. Lightning Bottle \n";
        }
        if (lockpick == 1)
        {
            cout << "4. Lock Pick \n";
        }
        if (spikedhorseshoes == 1)
        {
            cout << "5. Spiked Horse Shoes\n";
        }
        cout << "Selection?  ";
        cin >> inventorychoice;
        if (inventorychoice == 1 && healingpotion ==1)
        {
            healthstat = 8;
            cout << "You feel a strong surge of energy and a  distinctly itchy feeling as your wounds knit themselves together. You  feel energized, you feel great! You look at your biggest wound, the one  you're REALLY worried about... You sigh. Well, at least you're a healthy  cripple.\n\n";
            healingpotion = 0;
            cout << healthstat;
            cout << healingpotion;
            cout <<halfhealingpotion;
        }
        if (inventorychoice == 2 && halfhealingpotion ==1)
        {
            healthstat = 5;
            cout << "You feel a weak surge run through you and a  distincly itchy feeling as your wounds start to knit themselves  together. Start being the operative word. You still feel like garbage,  but you think you can move now.\n\n";
            halfhealingpotion = 0;
            cout << healthstat;
            cout << healingpotion;
            cout <<halfhealingpotion;
        }
    }
    The function it's embedded in:
    Code:
    void  breathedeep (int weapon, int healthstat, int spiritstat, int  strengthstat, int dexteritystat, int playerrace,int healingpotion, int  lightningbottle, int lockpick, int inventorychoice, int  halfhealingpotion, int north, int east, int up, int room, int  spikedhorseshoes)
    {
                cout << "You take a deep breath, close your eyes and  look inward. You have a brief moment of deep awareness. \n\n Health:  "<< healthstat << "\n Spirit:" << spiritstat <<  "\n Strength: " << strengthstat << "\n Dexterity: " <<  dexteritystat << "\n\n";
                if (playerrace == 1)
                {
                    cout <<  "UNICORN\n.................~()~().../\.....\n..................(~0000/  /............\n..............(~0/    _     \............\n.............(~0/     Q      \__.....\n............(~0/              _D\........\n...........(~0/              ___/.........\n..........(~0/           \__/...................\n____________/            /.........................\n                        |..........................\n                        |...........................\n                        |..........................\n                        |..........................\n                        |.........................\n                         \.......................\n                          \.......................\n________|     |_____       \.......................\n........|     |......\      \......................\n........|     |.......\     \  .........................\n\n";
                }
                else if (playerrace == 2)
                {
                    cout <<  "PEGASUS\n..................~()~()......\n..................(~000000............\n..............(~0/     _    \............\n.............(~0/     Q      \__.....\n............(~0/              _D\........\n...........(~0/              ___/.........\n..........(~0/           \__/...................\n____________/            /.........................\n|||||||||>>              |..........................\n|||||||||>>              |...........................\n|||||||||>               |..........................\n|||||||||                |..........................\n|||||||||                |.........................\n|||||||||                \.......................\n|||||||||                 \.......................\n|||||||||     |_____       \.......................\n--------|     |......\      \......................\n........|     |.......\     \  .........................\n\n";
                }
                    else if (playerrace == 3)
                    {
                        cout << "EARTH  PONY\n..................~()~()......\n..................(~000000............\n..............(~0/     _    \............\n.............(~0/     Q      \__.....\n............(~0/              _D\........\n...........(~0/              ___/.........\n..........(~0/           \__/...................\n____________/            /.........................\n                        |..........................\n                        |...........................\n                        |..........................\n                        |..........................\n                        |.........................\n                         \.......................\n                          \.......................\n        |     |_____       \.......................\n--------|     |......\      \......................\n........|     |.......\     \  .........................\n\n";
                    }
                //I'll need to fix the ascii art above, it's a great idea,  but I have to figure out how to get the spacing right and make the \  character show up.
                if (weapon == 0)
                {
                    cout << "You're completely unshod, and unarmed.\n\n";
                }
                if (location( north, east, up, room) == 5)
                {
                    cout << "You are in some sort of clinic. It is  tidy and neat, but doesn't appear to have much in the way of medical  supplies. Everything is worn down, but obvious efforts have been made to  maintain what little is there. A mare in an orange vest resides here,  looking watchful. There is also a heavy metal cabinet tucked away in a  corner. It has a very sturdy chain lock.\n\n";
    
                }
                inventory (healingpotion, lightningbottle, lockpick,  halfhealingpotion, inventorychoice, healthstat, spikedhorseshoes);
            }
    (Yes, I know the ascii art is silly.)

    I found out that in a certain part of my text adventure it was possible for a player to progress and be pronounced healed even when they hadn't drunk a healing potion from their inventory and just opened their inventory and exited instead. To fix this, I built a loop:

    Code:
     while (healingpotion ==1 || halfhealingpotion ==1)
        {
        cout<< "\n 1. Breathe Deep. \n 2. Do the exercise, but keep an eye open to make sure she doesn't pull anything.\n";
        cin >> tutorialchoicefive;
        while (tutorialchoicefive > 2 || tutorialchoicefive < 1)
         {
             cout << "Choose an option: ";
             cin >> tutorialchoicefive;
         }
        switch (tutorialchoicefive)
        {
            case 1:
             breathedeep (weapon, healthstat, spiritstat, strengthstat,  dexteritystat, playerrace, healingpotion, lightningbottle, lockpick,  inventorychoice, halfhealingpotion, north, east, up, room,  spikedhorseshoes);
            break;
            case 2:
             breathedeep (weapon, healthstat, spiritstat, strengthstat,  dexteritystat, playerrace, healingpotion, lightningbottle, lockpick,  inventorychoice, halfhealingpotion, north, east, up, room,  spikedhorseshoes);
             cout << "Your cracked eyelid lets you catch a glimpse of  the mare sitting next to you... who does absolutely nothing. She sticks  her tounge out when she sees you peeking.\n\n";
            break;
        }
        cout << healthstat;
            cout << healingpotion;
            cout <<halfhealingpotion;
        }

    You may notice the cout statements at the end of the inventory function and the loop. I put them there to test a theory I had and sure enough, they print out a sequence of 800210. Basically if the player drinks the potion I want the sequence to be 800, and the function modifies the variables to those values at least within itself.

    However, outside of the function the variables remain unmodified, causing my loop to keep repeating itself and a whole host of problems down the road in my program as the player sits on a healing potion and is horribly wounded as opposed to patching themselves up.

    If I could make it so that the variable defining statements in the function affected the variables more globally (most importantly, in main()) then things would be awesome, but I'm just not sure how to do that.

    So, once again, I seek advice from more experienced programmers, is there anything I can do to make this work? I would be sorely grateful for any help I could get.

  2. #2
    Registered User
    Join Date
    May 2006
    Posts
    100
    Hi, I haven't read your code yet, but I have read the rest of the question. Basically you just want to research pointers. Then references, but mostly pointers. In newer languages, such as Java, pointers/references tend to be used fairly implicitly, but C++ is pretty much completely direct in distinguishing between whether you're using that stuff or not.

    Basically when you pass a variable as an argument to a function in C++, the value of that variable gets copied over to the function. That means that you're working with two different copies that start off with the same value. Variables, by default, just have "ordinary" values in them, like numbers or alphanumerical sequences or something. However if you declare a variable to be a pointer, then the value of that variable is really just an address to a different location on the computer. So if you pass a pointer to a function, instead of an "ordinary" variable, the function receives the memory address, NOT the actual data. But doing that lets both the function and whatever is calling the function mess with the same piece of data (the contents of the same memory address), and this is basically how you do what you're describing.

    Again newer languages tend to handle this somewhat internally, such as in Java. C++ and VB.Net are fairly explicit about it though, with good reason for the contexts in which they're used. It might take you a little while to learn to work with pointers, but that's something you'll need to research.

    And if I misunderstood your question and actually just repeated a bunch of stuff you already know, sorry.

  3. #3
    Registered User
    Join Date
    Jul 2012
    Posts
    36
    Quote Originally Posted by jsrig88 View Post
    Hi, I haven't read your code yet, but I have read the rest of the question. Basically you just want to research pointers. Then references, but mostly pointers. In newer languages, such as Java, pointers/references tend to be used fairly implicitly, but C++ is pretty much completely direct in distinguishing between whether you're using that stuff or not.

    Basically when you pass a variable as an argument to a function in C++, the value of that variable gets copied over to the function. That means that you're working with two different copies that start off with the same value. Variables, by default, just have "ordinary" values in them, like numbers or alphanumerical sequences or something. However if you declare a variable to be a pointer, then the value of that variable is really just an address to a different location on the computer. So if you pass a pointer to a function, instead of an "ordinary" variable, the function receives the memory address, NOT the actual data. But doing that lets both the function and whatever is calling the function mess with the same piece of data (the contents of the same memory address), and this is basically how you do what you're describing.

    Again newer languages tend to handle this somewhat internally, such as in Java. C++ and VB.Net are fairly explicit about it though, with good reason for the contexts in which they're used. It might take you a little while to learn to work with pointers, but that's something you'll need to research.

    And if I misunderstood your question and actually just repeated a bunch of stuff you already know, sorry.
    No, actually I'd read the tutorial for pointers on this site and had had problems figuring out what they were for until just now. I get it now, if I want to section my code into functions to keep things organized, then I'll have to designate pointers so that I'm working with the same piece of data! Thank you so much! I will give it a try and see if it works.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,897
    Look into references rather than pointers for this.
    King Mir likes this.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Jul 2012
    Posts
    36
    Quote Originally Posted by Elysia View Post
    Look into references rather than pointers for this.
    Hmm... I guess you're right, I tried using pointers to provide the location of the variables of interest in my if statements/case switches, defining the pointers like this:

    Code:
      int *healingpotionptr, *lightningbottleptr, *lockpickptr, *halfhealingpotionptr, *inventorychoiceptr, *healthstatptr, *spikedhorseshoesptr;
        healingpotionptr = &healingpotion;
        lightningbottleptr = &lightningbottle;
        lockpickptr = &lockpick;
        halfhealingpotionptr = &halfhealingpotion;
        inventorychoiceptr = &inventorychoice;
        healthstatptr = &healthstat;
        spikedhorseshoesptr = &spikedhorseshoes;
    in main() and then changing the inventory function like this:
    Code:
    void inventory (int healingpotion, int lightningbottle, int lockpick, int halfhealingpotion, int inventorychoice, int healthstat, int spikedhorseshoes,
        int healingpotionptr, int lightningbottleptr, int lockpickptr, int halfhealingpotionptr, int inventorychoiceptr, int healthstatptr, int spikedhorseshoesptr)
    {
        cout << "You are carrying: (Select an item to use it, or type \"9\" or an integer not tied to an inventory object to exit.) \n \n";
        if (*healingpotionptr == 1)
        {
            cout << "1. Healing Potion (Sets health to 8!) \n";
        }
        if (*halfhealingpotionptr == 1)
        {
            cout << "2. Half Healing Potion (Sets health to 5!) \n";
        }
        if (*lightningbottleptr ==1)
        {
            cout << "3. Lightning Bottle \n";
        }
        if (*lockpickptr == 1)
        {
            cout << "4. Lock Pick \n";
        }
        if (*spikedhorseshoesptr == 1)
        {
            cout << "5. Spiked Horse Shoes\n";
        }
        cout << "Selection?  ";
        cin >> *inventorychoiceptr;
        if (*inventorychoiceptr == 1 && *healingpotionptr ==1)
        {
            *healthstatptr = 8;
            cout << "You feel a strong surge of energy and a distinctly itchy feeling as your wounds knit themselves together. You feel energized, you feel great! You look at your biggest wound, the one you're REALLY worried about... You sigh. Well, at least you're a healthy cripple.\n\n";
            *healingpotionptr = 0;
            cout << healthstat;
            cout << healingpotion;
            cout <<halfhealingpotion;
        }
        if (*inventorychoiceptr == 2 && *halfhealingpotionptr ==1)
        {
            *healthstatptr = 5;
            cout << "You feel a weak surge run through you and a distincly itchy feeling as your wounds start to knit themselves together. Start being the operative word. You still feel like garbage, but you think you can move now.\n\n";
            *halfhealingpotionptr = 0;
            cout << healthstat;
            cout << healingpotion;
            cout <<halfhealingpotion;
        }
    }
    But now the code won't even compile and every line that has a pointer comes back with a compiler error saying:

    C:\Documents and Settings\Administrator\Desktop\program\First Prince Text Adventure\main.cpp|153|error: invalid type argument of 'unary *'|

    So I guess I just don't understand pointers and am horribly misusing them.

    I thought that writing in *lockpickptr would cause the program to search out what was stored at the memory address of lockpick and evaluate for the variable I defined as int lockpick and thus everything in the code would work out. I guess not. Is there something I'm missing here?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,114
    Quote Originally Posted by chaucer345
    But now the code won't even compile and every line that has a pointer comes back with a compiler error saying:

    C:\Documents and Settings\Administrator\Desktop\program\First Prince Text Adventure\main.cpp|153|error: invalid type argument of 'unary *'|
    That is because you did not change the type of your parameters, i.e., those parameters are not pointers.

    Reference parameters would indeed be a better approach here: you get the call by reference mechanism that you need, and you don't need to change the calling syntax or your function implementation.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Jul 2012
    Posts
    36
    Quote Originally Posted by laserlight View Post
    That is because you did not change the type of your parameters, i.e., those parameters are not pointers.

    Reference parameters would indeed be a better approach here: you get the call by reference mechanism that you need, and you don't need to change the calling syntax or your function implementation.
    What do you mean by the type of parameters? You mean like ints or floats? I'm very sorry, but I'm just not sure what you're talking about with this one. Would it be possible for you to give me a short example?

    I also tried redoing this using references instead of pointers but I had the same problem and the cout statements started giving me very strange values.

    Here's how I defined my references:
    Code:
       int& healingpotionr =healingpotion;
        int& lightningbottler =lightningbottle;
        int& lockpickr = lockpick;
        int& halfhealingpotionr = halfhealingpotion;
        int& inventorychoicer = inventorychoice;
        int& healthstatr = healthstat;
        int& spikedhorseshoesr = spikedhorseshoes;

    And here's how I changed the function:
    Code:
    void inventory (int& healingpotionr, int& lightningbottler, int& lockpickr, int& halfhealingpotionr, int& inventorychoicer, int& healthstatr, int& spikedhorseshoesr)
    {
        cout << "You are carrying: (Select an item to use it, or type \"9\" or an integer not tied to an inventory object to exit.) \n \n";
        if (healingpotionr == 1)
        {
            cout << "1. Healing Potion (Sets health to 8!) \n";
        }
        if (halfhealingpotionr == 1)
        {
            cout << "2. Half Healing Potion (Sets health to 5!) \n";
        }
        if (lightningbottler ==1)
        {
            cout << "3. Lightning Bottle \n";
        }
        if (lockpickr == 1)
        {
            cout << "4. Lock Pick \n";
        }
        if (spikedhorseshoesr == 1)
        {
            cout << "5. Spiked Horse Shoes\n";
        }
        cout << "Selection?  ";
        cin >> inventorychoicer;
        if (inventorychoicer == 1 && healingpotionr ==1)
        {
            healthstatr = 8;
            cout << "You feel a strong surge of energy and a distinctly itchy feeling as your wounds knit themselves together. You feel energized, you feel great! You look at your biggest wound, the one you're REALLY worried about... You sigh. Well, at least you're a healthy cripple.\n\n";
            healingpotionr = 0;
            cout << healthstat;
            cout << healingpotion;
            cout <<halfhealingpotion;
        }
        if (inventorychoicer == 2 && halfhealingpotionr ==1)
        {
            healthstatr = 5;
            cout << "You feel a weak surge run through you and a distincly itchy feeling as your wounds start to knit themselves together. Start being the operative word. You still feel like garbage, but you think you can move now.\n\n";
            halfhealingpotionr = 0;
            cout << healthstat;
            cout << healingpotion;
            cout <<halfhealingpotion;
        }
    }
    Clearly I'm missing something very important here, as the loop still keeps going and my cout statements are giving me a sequence of 804277200214277200
    which makes no sense at all. I'm really getting very confused here. Is there some key concept I'm missing? I thought from my research that references just served as aliases for variables defined in other functions and if I just defined some references for the variables I wanted to modify I would be able to use them and modify them as if they were those variables in a function aside from the function in which they were defined. Is that wrong?

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,897
    What you did is correct. More context is needed to figure out what's wrong.
    Regarding pointers, here is how to use them correctly:

    Pointers:
    Code:
    void foo(int* bar)
    {
    	std::cout << "Address: " << bar << "\nValue: " << *bar << std::endl;
    	*bar = 10;
    	std::cout << "Address: " << bar << "\nValue: " << *bar << std::endl;
    }
    
    int main()
    {
    	int bar = 5;
    	std::cout << "Address: " << &bar << "\nValue: " << bar << std::endl;
    	foo(&bar);
    	std::cout << "Address: " << &bar << "\nValue: " << bar << std::endl;
    }
    References:
    Code:
    void foo(int& bar)
    {
    	std::cout << "Address: " << &bar << "\nValue: " << bar << std::endl;
    	bar = 10;
    	std::cout << "Address: " << &bar << "\nValue: " << bar << std::endl;
    }
    
    int main()
    {
    	int bar = 5;
    	std::cout << "Address: " << &bar << "\nValue: " << bar << std::endl;
    	foo(bar);
    	std::cout << "Address: " << &bar << "\nValue: " << bar << std::endl;
    }
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,114
    Quote Originally Posted by chaucer345
    What do you mean by the type of parameters? You mean like ints or floats? I'm very sorry, but I'm just not sure what you're talking about with this one. Would it be possible for you to give me a short example?
    Look closely at your function in post #5:
    Code:
    void inventory (int healingpotion, int lightningbottle, int lockpick, int halfhealingpotion, int inventorychoice, int healthstat, int spikedhorseshoes,
        int healingpotionptr, int lightningbottleptr, int lockpickptr, int halfhealingpotionptr, int inventorychoiceptr, int healthstatptr, int spikedhorseshoesptr)
    The type of healingpotionptr is int, not pointer to int, hence the expression *healingpotionptr is invalid.

    Quote Originally Posted by chaucer345
    Here's how I defined my references:
    That was completely unnecessary. All you needed to do was to call the function by passing the arguments.

    Quote Originally Posted by chaucer345
    I'm really getting very confused here. Is there some key concept I'm missing?
    Yes. You're missing the key concept of starting small, then building up on what works. Look at your inventory function: holy 14 parameters, Batman! Spiderman recommends that you don't have functions that require more than 8 legs to count the parameters; 5 or 6 is usually a more palatable maximum for non-superhero programmers.

    If I were you, I would start with an inventory of just say, healing potions. Get your inventory system to work such that the player can use healing potions, thus reducing the inventory count, and find/buy healing potions, thus increasing the inventory count.

    Once you have this working, think of how you can write a class (or at least an aggregate struct) to model an inventory so that you can pass around an inventory object (by reference) rather than having to pass around an argument for each item type in the inventory.
    stahta01 and xstux like this.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Jul 2012
    Posts
    36
    Okay, so in an attempt to give the requested context I threw together a full program that was just the essential functions and portions of main() with easy to visualize cout statements that would display what was going on. The program compiles fine, if nothing else, and illustrates the problem (Also I know there's probably a bunch of junk variables floating around in there that aren't used for anything, I apologize for the lack of clarity):

    Code:
    #include <iostream>
     
     using namespace std;
     
     
      void inventory (int& healingpotionr, int& lightningbottler,  int& lockpickr, int& halfhealingpotionr, int&  inventorychoicer, int& healthstatr, int& spikedhorseshoesr)
     {
         cout << "You are carrying: (Select an item to use it, or type  \"9\" or an integer not tied to an inventory object to exit.) \n \n";
         if (healingpotionr == 1)
         {
             cout << "1. Healing Potion (Sets health to 8!) \n";
         }
         if (halfhealingpotionr == 1)
         {
             cout << "2. Half Healing Potion (Sets health to 5!) \n";
         }
         if (lightningbottler ==1)
         {
             cout << "3. Lightning Bottle \n";
         }
         if (lockpickr == 1)
         {
             cout << "4. Lock Pick \n";
         }
         if (spikedhorseshoesr == 1)
         {
             cout << "5. Spiked Horse Shoes\n";
         }
         cout << "Selection?  ";
         cin >> inventorychoicer;
         if (inventorychoicer == 1 && healingpotionr ==1)
         {
             healthstatr = 8;
             cout << "You feel a strong surge of energy and a  distinctly itchy feeling as your wounds knit themselves together. You  feel energized, you feel great! You look at your biggest wound, the one  you're REALLY worried about... You sigh. Well, at least you're a healthy  cripple.\n\n";
             healingpotionr = 0;
             cout<< "Within the inventory function: \n";
             cout << "healthstatr: " << healthstatr<<"\n";
             cout << "healingpotionr: " << healingpotionr<<"\n";
             cout << "halfhealingpotionr: "<< halfhealingpotionr<<"\n";
         }
         if (inventorychoicer == 2 && halfhealingpotionr ==1)
         {
             healthstatr = 5;
             cout << "You feel a weak surge run through you and a  distincly itchy feeling as your wounds start to knit themselves  together. Start being the operative word. You still feel like garbage,  but you think you can move now.\n\n";
             halfhealingpotionr = 0;
             cout<< "Within the inventory function: \n";
             cout << "healthstatr: " << healthstatr<<"\n";
             cout << "healingpotionr: " << healingpotionr<<"\n";
             cout << "halfhealingpotionr: "<< halfhealingpotionr<<"\n";
         }
     }
     int location(int north, int east, int up, int room)
     {
         //okay, so the idea here is that the movement in each direction  needs to modify the return value of the function such that each of the  12 rooms has a different value.
        if (north==0 && east==0 && up==0)
        {
            room = 1; //this will be tunnels room 1
        }
        else if (north==1 && east==0 && up==0)
        {
            room = 2; //this will be tunnels room 2
        }
        else if (north==1 && east==1 && up==0)
        {
            room = 3; // this will be tunnels room 3
        }
        else if (north==0 && east==1 && up==0)
        {
            room = 4; // this will be tunnels room 4
        }
        else if (north==0 && east==0 && up==1)
        {
            room = 5; //this will be the clinic
        }
        else if (north==1 && east==0 && up==1)
        {
            room = 6; //this will be the meeting room/hard knock's training room
        }
        else if (north==1 && east==1 && up==1)
        {
            room = 7; //this will be Tiller's lab
        }
        else if (north==0 && east==1 && up==1)
        {
            room = 8; // this will be the bedrooms/Blueblood's office
        }
        else if (north==0 && east==0 && up==2)
        {
            room = 9; // this will be the mountain pass
        }
        else if (north==0 && east==0 && up==2)
        {
            room = 10; // this will be the bridge
        }
        else if (north==1 && east==1 && up==2)
        {
            room = 11; // this will be the Creek
        }
        else if (north==0 && east==1 && up==2)
        {
            room = 12; // this will be the hill side
        }
         return room;
     }
     
     
     void breathedeep (int weapon, int healthstat, int spiritstat, int  strengthstat, int dexteritystat, int playerrace,int healingpotion, int  lightningbottle, int lockpick, int inventorychoice, int  halfhealingpotion, int north, int east, int up, int room, int  spikedhorseshoes)
     {
                 cout << "You take a deep breath, close your eyes and  look inward. You have a brief moment of deep awareness. \n\n Health:  "<< healthstat << "\n Spirit:" << spiritstat <<  "\n Strength: " << strengthstat << "\n Dexterity: " <<  dexteritystat << "\n\n";
                 if (playerrace == 1)
                 {
                     cout <<  "UNICORN\n.................~()~().../\.....\n..................(~0000/  /............\n..............(~0/    _     \............\n.............(~0/     Q      \__.....\n............(~0/              _D\........\n...........(~0/              ___/.........\n..........(~0/           \__/...................\n____________/            /.........................\n                        |..........................\n                        |...........................\n                        |..........................\n                        |..........................\n                        |.........................\n                         \.......................\n                          \.......................\n________|     |_____       \.......................\n........|     |......\      \......................\n........|     |.......\     \  .........................\n\n";
                 }
                 else if (playerrace == 2)
                 {
                     cout <<  "PEGASUS\n..................~()~()......\n..................(~000000............\n..............(~0/     _    \............\n.............(~0/     Q      \__.....\n............(~0/              _D\........\n...........(~0/              ___/.........\n..........(~0/           \__/...................\n____________/            /.........................\n|||||||||>>              |..........................\n|||||||||>>              |...........................\n|||||||||>               |..........................\n|||||||||                |..........................\n|||||||||                |.........................\n|||||||||                \.......................\n|||||||||                 \.......................\n|||||||||     |_____       \.......................\n--------|     |......\      \......................\n........|     |.......\     \  .........................\n\n";
                 }
                     else if (playerrace == 3)
                     {
                         cout << "EARTH  PONY\n..................~()~()......\n..................(~000000............\n..............(~0/     _    \............\n.............(~0/     Q      \__.....\n............(~0/              _D\........\n...........(~0/              ___/.........\n..........(~0/           \__/...................\n____________/            /.........................\n                        |..........................\n                        |...........................\n                        |..........................\n                        |..........................\n                        |.........................\n                         \.......................\n                          \.......................\n        |     |_____       \.......................\n--------|     |......\      \......................\n........|     |.......\     \  .........................\n\n";
                     }
                 //I'll need to fix the ascii art above, it's a great idea,  but I have to figure out how to get the spacing right and make the \  character show up.
                 if (weapon == 0)
                 {
                     cout << "You're completely unshod, and unarmed.\n\n";
                 }
                 if (location( north, east, up, room) == 5)
                 {
                     cout << "You are in some sort of clinic. It is  tidy and neat, but doesn't appear to have much in the way of medical  supplies. Everything is worn down, but obvious efforts have been made to  maintain what little is there. A mare in an orange vest resides here,  looking watchful. There is also a heavy metal cabinet tucked away in a  corner. It has a very sturdy chain lock.\n\n";
     
                 }
                 inventory (healingpotion, lightningbottle, lockpick,  halfhealingpotion, inventorychoice, healthstat, spikedhorseshoes);
             }
     
     int main()
     {
         int healthstat;
         int north, east, up;
         north = 0;
         east = 0;
         up = 1;
         int firstvisit;
         int everyoneconversationchoiceone;
         int hardknockconversationchoice;
         int bluebloodconversationonechoice;
         int spikedhorseshoes;
         spikedhorseshoes = 0;
         int windconversationonechoice;
         int inventorychoice;
         int halfhealingpotion;
         int healingpotion;
         int lightningbottle;
         int lockpick;
         //int *healingpotionptr, *lightningbottleptr, *lockpickptr,  *halfhealingpotionptr, *inventorychoiceptr, *healthstatptr,  *spikedhorseshoesptr;
         //healingpotionptr = &healingpotion;
         //lightningbottleptr = &lightningbottle;
         //lockpickptr = &lockpick;
         //halfhealingpotionptr = &halfhealingpotion;
         //inventorychoiceptr = &inventorychoice;
         //healthstatptr = &healthstat;
         //spikedhorseshoesptr = &spikedhorseshoes;
         int& healingpotionr =healingpotion;
         int& lightningbottler =lightningbottle;
         int& lockpickr = lockpick;
         int& halfhealingpotionr = halfhealingpotion;
         int& inventorychoicer = inventorychoice;
         int& healthstatr = healthstat;
         int& spikedhorseshoesr = spikedhorseshoes;
         int enemyweapon;
         int enemystrength;
         int targethealth;
         int weapon;
         int battle;
         int playername;
         //char enteredfirstname[1000];
         //char enteredlastname[1000];
         char enteredplayername[256];
         int spiritstat;
         int strengthstat;
         int dexteritystat;
         int tutorialchoiceone;
         int tutorialchoicetwo;
         int tutorialchoicethree;
         int tutorialchoicefour;
         int tutorialchoicefive;
         int tutorialchoicesix;
         tutorialchoicethree = 2;
         int playerrace;
         int people; // Plan: 1 will be Wind, 2 will be Blueblood, 3 will be Tiller, and 4 will be Hard knock.
         int room;
         int chapterover;
         chapterover = 1;
     
     healthstat =2;
     spiritstat=2;
     strengthstat=2;
     dexteritystat=2;
      healingpotion=1;
      halfhealingpotion=1;
       while (healingpotion ==1 || halfhealingpotion ==1)
         {
         cout<< "\n 1. Breathe Deep. \n 2. Do the exercise, but keep an eye open to make sure she doesn't pull anything.\n";
         cin >> tutorialchoicefive;
         while (tutorialchoicefive > 2 || tutorialchoicefive < 1)
          {
              cout << "Choose an option: ";
              cin >> tutorialchoicefive;
          }
         switch (tutorialchoicefive)
         {
             case 1:
              breathedeep (weapon, healthstat, spiritstat, strengthstat,  dexteritystat, playerrace, healingpotion, lightningbottle, lockpick,  inventorychoice, halfhealingpotion, north, east, up, room,  spikedhorseshoes);
             break;
             case 2:
              breathedeep (weapon, healthstat, spiritstat, strengthstat,  dexteritystat, playerrace, healingpotion, lightningbottle, lockpick,  inventorychoice, halfhealingpotion, north, east, up, room,  spikedhorseshoes);
              cout << "Your cracked eyelid lets you catch a glimpse of  the mare sitting next to you... who does absolutely nothing. She sticks  her tounge out when she sees you peeking.\n\n";
             break;
         }
             cout<< "Outside the inventory function: \n";
             cout << "healthstatr: " << healthstatr<<"\n";
             cout << "healingpotionr: " << healingpotionr<<"\n";
             cout << "halfhealingpotionr: "<< halfhealingpotionr<<"\n";
             cout << "healthstat: " << healthstat<<"\n";
             cout << "healingpotion: " << healingpotion<<"\n";
             cout << "halfhealingpotion: "<< halfhealingpotion<<"\n";
         }
     cout << "The mare looks you over. \"Okay, it looks like you've  healed up enough to walk. C'mon, there's some ponies that want to meet  you. \n\n";
     }

    Interested parties can throw it in a compiler and see for themselves, but the problem is clear. The references are modified fine in the function, but for some reason all the variables in the main function stay the same. That implies that the references I wrote in still aren't doing what I want them too, though the modification statements within the function are. Now that the full source code for the problem area is available, does anyone have ideas as to why?

    Quote Originally Posted by laserlight View Post
    Yes. You're missing the key concept of starting small, then building up on what works. Look at your inventory function: holy 14 parameters, Batman! Spiderman recommends that you don't have functions that require more than 8 legs to count the parameters; 5 or 6 is usually a more palatable maximum for non-superhero programmers.

    If I were you, I would start with an inventory of just say, healing potions. Get your inventory system to work such that the player can use healing potions, thus reducing the inventory count, and find/buy healing potions, thus increasing the inventory count.

    Once you have this working, think of how you can write a class (or at least an aggregate struct) to model an inventory so that you can pass around an inventory object (by reference) rather than having to pass around an argument for each item type in the inventory.
    Okay... this is where I shamefully admit my ignorance. The honest answer for why I didn't do all that stuff is that I don't know what any of it is. Very sorry, I'll get to researching.
    Last edited by chaucer345; 07-20-2012 at 02:09 PM. Reason: fix

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,897
    breathedeep doesn't take its arguments by reference.
    But you need to clean this up. Start putting stuff into structs, at the very least, as recommended.
    And work on your indentation.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Jul 2012
    Posts
    36
    It worked! Thank you so much.

    You know, as I'm using it as a learning exercise anyway, I think I'm actually going to rewrite this program from scratch (minus the string literals). I've learned so much in the process of writing it that I keep running into problems where my old code just isn't built the same way the new code is and it's left me with a bunch of dead leftover junk that really needs cleaning. Thank you all for your help, and your patience. Hopefully next time I post about this project, things will be a little easier to read and I'll have a more complex grade of problem.

  13. #13
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,438
    That big stack of variable declarations can be organised as laserlight says you can use structs - a certain type of player might have several attributes - you can group these attributes into your own datatype - a struct goblin, having goblin hits, goblin resistance etc. Further to that is the idea of Classes - Class player has hitpoints, resistance, status etc as well as working functions to do stuff- things common to all your character types - and then you subclass into your other types like wraith - which has a scare factor also, but still has all the things player has - as they are of type player too. Barring all that stuff, you dont need to declare all of your variables all at once, maybe look and see if any can be declared just when they are needed. Also north, east, south, west - things like that are constant - they can be declared as so and use CAPS to outline them in the code.
    Last edited by rogster001; 07-20-2012 at 03:00 PM.
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 03-08-2011, 02:16 AM
  2. Modify to make Doubly Linked List
    By Dampecram in forum C Programming
    Replies: 10
    Last Post: 11-03-2008, 07:25 PM
  3. Replies: 15
    Last Post: 12-07-2006, 09:27 PM
  4. Replies: 5
    Last Post: 01-13-2006, 12:00 AM
  5. Pointers to modify a variable's value?
    By Munkey01 in forum C++ Programming
    Replies: 3
    Last Post: 01-19-2003, 03:52 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21