Potential reference vs value problem with objects

I have been working on a game and trying to use it as a means for bettering my C/C++/general programming skills. I'm reasonably familiar with the concept of pointers (I'd say I'm a 4/10, where 10 is 'leet hacker' and 0 is absolute novice) and scope, so that's the first thing I thought about while making my program.

Unfortunately, it's very modular (I'm working with friends and we're eventually going to take up different aspects of the code; but as of now, all the coding has been done by me, so I know all the ins/outs of the program as it currently is).

Essentially, I've gotten my program to successfully spawn a single player character with preset stats and an unlimited number of enemies (one at a time, though) on command.

My current test is to have my overpowered character attack a never-ending stream of bad guys until the player either dies or gets bored of spawning enemies. Unfortunately, for some inexplicable reason, though, my hero seems to restore his health every turn.

I tried following a debug, but it froze my game somehow after I began battling an enemy (it runs just fine when I run it normally, with no warnings or segfaults). Watching the variable led to some interesting results - my currenthealth variable randomly goes to "undefined" when I'm tracing outside of the class that created it... I always assumed that a variable should stay constant until I free the ram used by it (I have no destructors in my program, so I thought they'd remain permanent). Then again, maybe I was staring at a "class's" variable instead of an object's. Either way, though, the currenthealth restores itself, making me think the program is doing a change of value instead of a change by reference.

But I am definitely using the address operator (&) and using it in dereference form in functions (*) and saving using the arrow (->). I could understand this behavior if I was, for example doing this:

CLASSTYPE OBJECTNAME;
FUNCTION(OBJECTNAME);


INT FUNCTION(CLASSTYPE COPYOFOBJECT)
{
COPYOFOBJECT.SETVAR1(10);
}



But that's why I'm doing:

CLASSTYPE OBJECTNAME;
FUNCTION(&OBJECTNAME)

INT FUNCTION(CLASSTYPE* ORIGINALOBJECT)
{
ORIGINALOBJECT->SETVAR1(10);
}



I'm hoping that my logic is correct and that maybe I just passed a variable incorrectly at some point (as in by value) or that I'm overlooking some part of my program that accidentally heals my character in between fights. But... As far as I can tell, only choosing option 2 ("create a hero") should reset his stats. Thanks in advance.

Please note the game was made in codeblocks and uses a TON of headers. You'll have to either open it as a codeblocks project or manually add each header and file to a project in your compiler/IDE.

http://www.mediafire.com/download/f1rk1h5dxx9k5me/RPG+GAME.zip
Unfortunately, it's very modular
This is a good thing.

There's something basically wrong with your game loop. It should look something like this:
1
2
3
init
while (!end)
    action

But yours is:
1
2
create main player
introFunction(main player)

Where introFunction is:
1
2
3
4
get option
fixup player
action
introFunction(player)

That's pretty much infinite recursion. But you haven't hit those problems yet.

I've created a Unix makefile for you (for me really, because I needed to run your code). Filenames in Unix are case sensitive, so fix that where necessary:
1
2
3
4
5
6
7
PROG = game
SRCS = attack.cpp battle.cpp enemyAttack.cpp enemyStats.cpp intro.cpp main.cpp playerStats.cpp spawnEnemy.cpp

all:	$(PROG)

$(PROG): $(SRCS:.cpp=.o)
	$(LINK.cc) $^ -o $@

Some hints:
1. srand with a fixed seed so you get reproducible results in development
2. make ALL data private, data in player is public
3. player is so much like enemy, that perhaps they should have a common base class
4. eventually remove that recursion with a loop

I ran the game and got this output, but I can't see what's wrong with it.
Welcome to RPG Game.
What would you like to do?





1. Register name (don't do this)
2. Choose hero type(currently spawns a regular warrior)
3. Spawn an enemy
4. Check your stats (requires you to make hero first)




>> 2
********************************
Your character has been created!
********************************
Welcome to RPG Game.
What would you like to do?





1. Register name (don't do this)
2. Choose hero type(currently spawns a regular warrior)
3. Spawn an enemy
4. Check your stats (requires you to make hero first)




>> 3
Your warrior attacks the optimistic pikachu and inflicts 10 damage.
The enemy pikachu is left with 40 HP!
The optimistic pikachu attacks you and inflicts 3 damage, leaving you with 97 HP!
Your warrior attacks the optimistic pikachu and inflicts 10 damage.
The enemy pikachu is left with 30 HP!
The optimistic pikachu attacks you and inflicts 1 damage, leaving you with 96 HP!
Your warrior attacks the optimistic pikachu and inflicts 10 damage.
The enemy pikachu is left with 20 HP!
The optimistic pikachu attacks you and inflicts 2 damage, leaving you with 94 HP!
Your warrior attacks the optimistic pikachu and inflicts 10 damage.
The enemy pikachu is left with 10 HP!
The optimistic pikachu attacks you and inflicts 2 damage, leaving you with 92 HP!
Your warrior attacks the optimistic pikachu and inflicts 10 damage.
The enemy pikachu is left with 0 HP!
Welcome to RPG Game.
What would you like to do?





1. Register name (don't do this)
2. Choose hero type(currently spawns a regular warrior)
3. Spawn an enemy
4. Check your stats (requires you to make hero first)




>> 3
Your warrior attacks the fuzzy pikachu and inflicts 10 damage.
The enemy pikachu is left with 40 HP!
The fuzzy pikachu attacks you and inflicts 3 damage, leaving you with 97 HP!
Your warrior attacks the fuzzy pikachu and inflicts 10 damage.
The enemy pikachu is left with 30 HP!
The fuzzy pikachu attacks you and inflicts 2 damage, leaving you with 95 HP!
Your warrior attacks the fuzzy pikachu and inflicts 10 damage.
The enemy pikachu is left with 20 HP!
The fuzzy pikachu attacks you and inflicts 2 damage, leaving you with 93 HP!
Your warrior attacks the fuzzy pikachu and inflicts 10 damage.
The enemy pikachu is left with 10 HP!
The fuzzy pikachu attacks you and inflicts 2 damage, leaving you with 91 HP!
Your warrior attacks the fuzzy pikachu and inflicts 10 damage.
The enemy pikachu is left with 0 HP!
Welcome to RPG Game.
What would you like to do?
Last edited on
I meant to fix issues with case sensitivity; that's a huge no-no that I started with but tried to fix. I'll look more carefully into case sensitivity. Likewise, I keep meaning to make my classes capitalized, but objects lowercase.

I'll definitely make my data private. It was mostly public because this is my first time actually working with objects and I didn't want to deal with potential errors with scope/permissions (I'll admit I took an OOP class in java that taught us about keeping stuff private, but I was a lazy student then and didn't pay attention... I vaguely know about destructors and overloading, and whatnot. Don't worry, I do regret being lazy back then). I'm definitely going to try to privitize as much as I can after I feel comfortable with my objects working properly.

As for the "unfortunately modular", I meant it in terms of a bigger hassle for readers on this website in that they have to create a project, etc. just to compile it. I did intentionally modularize it for the "good reasons" that you're thinking of, though.

I'll recode the sRand; thanks!

I'm not 100% sure if my recursion issue is what I think it is, but if you mean how the program runs infinitely with no exit, I have temporarily done that intentionally as I'm working in steps. My current idea is to playtest the basics - creating a single character with set stats, and letting him battle an infinite number of enemies, one at a time, until he dies or gets bored. I had initially playtested my battle system by letting him fight just one premade enemy and then killing the game as soon as he won. The current step is to run an infinite loop that tests stability of my objects and whether my values stay after a battle... unfortunately, that's where my problem is - the values reset. I want the warrior to remain hurt after his initial battle.

I created a test program (I do a lot of these, haha) to see if my logic with passing objects is correct, and the results suggest I'm thinking this properly:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>

class Variables{
    private:
        int variable1;
    public:
        void setVariable(int myNum)
        {
            variable1 = myNum;
        }
        int getVariable()
        {
            return variable1;
        }
};

int myFunction(Variables* myVariable1);
int myFunction(Variables myVariable1); //overloaded function

int main()
{
    Variables myVariable;
    myVariable.setVariable(10);
    printf("%d\n",myVariable.getVariable()); //should say 10 hopefully

    myVariable.setVariable(myVariable.getVariable()-4);
    printf("%d\n",myVariable.getVariable()); //should say 6 hopefully

    myFunction(myVariable);
    printf("%d\n",myVariable.getVariable()); //should still say 6 hopefully

    myFunction(&myVariable);

    printf("%d\n",myVariable.getVariable()); //should say 50 hopefully



}

int myFunction(Variables myVariable1)
{
    myVariable1.setVariable(20);
    return 0;
}

int myFunction(Variables* myVariable1)
{
    myVariable1->setVariable(50);
    return 0;
}



The data does not "reset" when I pass by reference in this mini program, but it does in my actual game. Perchance do you know why he's healing in between fights? I noticed that in your statement about recursion (speaking of which, am I understanding correctly that you're referring to my intentional loop as the infinite recursion, or am I misunderstanding?) that you said my player goes through a "fixup"; does that mean my player is healing himself at that step? I am trying to find out where he might heal, but aside from intentionally choosing option 2 (create hero), he shouldn't get a chance to heal up.

Once I verify he keeps damage between fights, I'm going to make the fight non-recursive and give an option to exit.

Also, to anyone reading this: don't worry about the printf's. I know they must be really annoying to see in C++ code, but I'm going to get around to replacing all of them with couts. It's just that I've been doing C (regular) for years, so I am very used to printf. Heh heh.

By the way, thanks for looking into this and the advice, kbw!
Ooops... Realized my error after posting all that stuff. I passed my objects in a silly way when it came to spawnEnemy().

Here's my updated code. Looks like everything's ok (got a little snagged when I was figuring out whether to use asterisks or ampersands, but realized the logic behind it after staring more intently at it); here's the fixed code. The warrior continues to stay injured between fights now. I'll work on a better fighting structure (i.e. no infinite fights) now that this issue is solved.

http://www.mediafire.com/download/pd82gkoeqgmm1xk/RPG+GAME+Saved+at+450am+on+111513.zip


Thanks again, kbw! Also, if you can think of any other problems (or if I misunderstood any of your suggestions), feel free to let me know!


EDIT: Oh, and regarding the similarity between the enemy and hero - I was considering that at first while making the classes, but then I decided that by the time the game got more serious that the hero(es) would get a lot more complex than the grunt enemies, thereby potentially causing issues much later in the game. Likewise, bosses are probably going to get their own individual classes as well. However, I'll definitely keep that suggestion in mind, especially since I guess I could just "ignore" the aspects that don't apply to enemies (such as "inventory" or "mana" that will be implemented later).

I'm going to go and fix my private/public members now (and then retest my program afterwards to make sure I didn't break it with those changes).
Last edited on
Topic archived. No new replies allowed.