damage algorithm for simple game

I'm having issues calculating damage from a small game I wrote. Every time the player or enemy attack, the damage gets reset so no one ever dies. The problem is in character::hp in characters.cpp.

characters.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef RESOURCES_H
#define RESOURCES_H

class Die{
public:
	static int roll();
};

class character{
public:
	static int hp();
	bool state();
};

class attack{
public:
	int number();
};

#endif 

characters.cpp
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
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "characters.h"

int damage;

int Die::roll()
{
	return rand()%4+1;
}

int character::hp()
{
	int initialhealth=500;
	int health = initialhealth-damage;
	int currenthealth = health-damage;
	return currenthealth;
}

int attack::number()
{
	damage=(rand()%4+1) * 25;
    return damage;
}

main.cpp
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
#include <iostream>
#include "characters.h"

int main()
{
	srand(time(0));
	char select;
	character player;
	character troll;
	std::cout << "Hello, welcome to wizardworld version 1" << std::endl;
	std::cout << "there is a troll in the room you are in, engage in combat?" << std::endl;
	
	std::cout << "Both your hp, and the troll's hp start at 500, you will take turns attacking each other until one of you runs out" << std::endl;
	std::cout << "the players hp is " << player.hp() << std::endl;
	std::cout << "the troll's hp is " << troll.hp() << std::endl;
	
	while(player.hp()>0 and troll.hp()>0)
	{
	std::cout << "enter a to begin combat" << std::endl;
	std::cin >> select;
	if(select=='a')
	std::cout << "You have entered combat" << std::endl;
	else return 0;
	
	
	player.hp(); 
	attack theplayer;
	attack thetroll;
	
	std::cout << "to attack enter a" << std::endl;
	std::cin >> select;
	if(select=='a'){
	thetroll.number();
	std::cout << troll.hp() << std::endl;
	}
	else return 0;
	
	std::cout << "it is the trolls turn to attack" << std::endl;
	theplayer.number();
	std::cout << "the troll attacked, your hp is now " << player.hp() << std::endl;
	}
	if(troll.hp()>0)
	std::cout << "The troll has won." << std::endl;
	else std::cout << "You have Won!!!" << std::endl;
	return 0;
}
Last edited on
This is because "initialhealth" is a variable that is local to that member function 'hp()' when it should be a private member of the class 'character' and set at the constructor.

EDIT: Also "damage" should be an argument passed to 'hp()', not a global variable.
Last edited on
alright, I moved initialhealth to characters.cpp as a private member
now i get terminal error
1
2
3
4
5
6
7
characters.cpp: In static member function ‘static int character::hp()’:
characters.cpp:15:15: error: invalid use of member ‘character::initialhealth’ in static member function
   15 |  int health = initialhealth-damage;
      |               ^~~~~~~~~~~~~
In file included from characters.cpp:4:
characters.h:13:6: note: declared here
   13 |  int initialhealth=500;

also, I don't know how to pass damage as an argument yet, so first I'm going to focus on resolving the error.
characters.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "characters.h"

int damage;

int Die::roll()
{
	return rand()%4+1;
}

int character::hp()
{
	int health = initialhealth-damage;
	int currenthealth = health-damage;
	return currenthealth;
}

int attack::number()
{
	damage=(rand()%4+1) * 25;
    return damage;
}

characters.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef RESOURCES_H
#define RESOURCES_H

class Die{
public:
	static int roll();
};

class character{
public:
	static int hp();
	private:
	int initialhealth=500;
};

class attack{
public:
	int number();
};

#endif 
How are learning C++? What book etc are you using? For an on-line resource I suggest https://www.learncpp.com/
I've been following tutorials and assigning myself projects like this game. I've learned at least as much coding this game as from the tutorials. I currently have no books. I followed the tutorials from thecpluplus guy on YouTube, which I find easy to follow. But yeah, it's going to take a while to develop a breadth of knowledge. I started learning about a week ago.

Every so often I run into a problem I can't easily solve in an hour or two, so I make a post. I try not to over rely on it. I've learned a lot about classes and member functions compared to when I started this project and I have a plan to make a larger terminal based game by expanding this one in multiple iterations.
Last edited on
The 'hp()' member function doesn't NEED to be static here. You're also missing the time.h header.

EDIT:

character.cpp should read more like this:
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
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "character.hpp"

//int damage;

int Die::roll()
{
	return rand()%4+1;
}

int character::hp(int damage)
{
	//int health = initialhealth-damage;
	health = health-damage;
	return health;
}

int attack::number()
{
	//damage=(rand()%4+1) * 25;
    int dmg = (rand()%4+1) * 25;
    return dmg;
}


I've renamed the member variable "initialhealth" to just "health" since that appears to have been tripping you up.

EDIT 2: There's actually a lot to change now that I've tried to compile it. But it's small stuff. Let me see if I can help out.
Last edited on
So, basically I couldn't get this to compile without the global variable damage. here's my current errors after changing to the above
1
2
3
4
5
6
7
8
9
10
11
12
13
characters.cpp:13:5: error: no declaration matches ‘int character::hp(int)’
   13 | int character::hp(int damage)
      |     ^~~~~~~~~
In file included from characters.cpp:4:
characters.h:11:13: note: candidate is: ‘static int character::hp()’
   11 |  static int hp();
      |             ^~
characters.h:9:7: note: ‘class character’ defined here
    9 | class character{
      |       ^~~~~~~~~
characters.cpp: In member function ‘int attack::number()’:
characters.cpp:21:2: error: ‘damage’ was not declared in this scope
   21 |  damage=(rand()%4+1) * 25;

characters.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "characters.h"

//int damage;

int Die::roll()
{
	return rand()%4+1;
}

int character::hp(int damage)
{
	health = health-damage;
	return health;
}

int attack::number()
{
	damage=(rand()%4+1) * 25;
    return damage;
}

edit: changes to characters.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef RESOURCES_H
#define RESOURCES_H

class Die{
public:
	static int roll();
};

class character{
public:
	static int hp();
	private:
	int health=500;
};

class attack{
public:
	int number();
};

#endif 
Last edited on
Like I said, there was a bunch of small things. Take what you have and save it to another folder. Start a new project and try this, I've kept the changes to a minimum:

character.hpp:
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
#ifndef CHARACTER_HPP_INCLUDED
#define CHARACTER_HPP_INCLUDED
class Die{
public:
	static int roll();
}; //NOT USED

class character{
public:
    character(): health(500) {};

	int hp(int);
	int hp();
	int attack();
	private:
	int health;
};

/*class attack{
public:
	int number();
};*/


#endif // CHARACTER_HPP_INCLUDED 


character.cpp:
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
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "character.hpp"

//int damage;

int Die::roll() //NOT USED
{
	return rand()%4+1;
}

int character::hp()
{
    return health;
}

int character::hp(int damage)
{
	//int health = initialhealth-damage;
	health = health-damage;
	return health;
}


int character::attack()
{
	int dmg=(rand()%4+1) * 25;
    return dmg;
}

/*int attack::number()
{
	damage=(rand()%4+1) * 25;
    return damage;
}*/


main.cpp
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
#include <iostream>
#include "character.hpp"

int main()
{
	//srand(time(0));
	char select;
	character player;
	character troll;
	std::cout << "Hello, welcome to wizardworld version 1" << std::endl;
	std::cout << "there is a troll in the room you are in, engage in combat?" << std::endl;

	std::cout << "Both your hp, and the troll's hp start at 500, you will take turns attacking each other until one of you runs out" << std::endl;
	std::cout << "the players hp is " << player.hp(troll.attack()) << std::endl;
	std::cout << "the troll's hp is " << troll.hp(player.attack()) << std::endl;

	while(player.hp()>0 and troll.hp()>0)
	{
	std::cout << "enter a to begin combat" << std::endl;
	std::cin >> select;
	if(tolower(select)=='a')
	std::cout << "You have entered combat" << std::endl;
	else return 0;


	player.hp();
//	attack theplayer;
//	attack thetroll;

	std::cout << "to attack enter a" << std::endl;
	std::cin >> select;
	if(tolower(select)=='a'){
//	thetroll.number();
    player.hp(troll.attack());
	std::cout << troll.hp() << std::endl;
	}
	else return 0;

	std::cout << "it is the trolls turn to attack" << std::endl;
//	theplayer.number();
    troll.hp(player.attack());
	std::cout << "the troll attacked, your hp is now " << player.hp() << std::endl;
	}
	if(troll.hp()>0)
	std::cout << "The troll has won." << std::endl;
	else std::cout << "You have Won!!!" << std::endl;
	return 0;
}


Your damage isn't random though

Also, feel free to ask any questions.
Last edited on
That worked, thanks. Now I'm going to go through and figure out why these practices were better. Also, while playing the game, the damage appeared to be semirandom, as I would receive between 25 and 100 points in damage each turn, can you clarify what you meant. Is it just not truly random, or will I get the same results every time?

edit: Die::roll is a legacy. I started by modifying a dice rolling program. That's the only reason it was there.
Last edited on
It's because I commented out "srand()" because time.h wasn't included but when I went through to compile and make my fixes I glazed over it. For something like this srand\rand is good enough. But something to keep in the back of your mind is that there are way better methods these days.
is the return value of dmg going to int hp(int damage); ?
Yes, that is occurring on Lines 34 and 41 in Main.cpp.
Oh, that makes sense. I can fix it too then. But yes, I've been hearing that. I'll get up to date on random number generation eventually, for now my needs are very simple. I want to focus on mastering classes, member functions and constructors really.
That's clever. I find that while tutorials are nice, they don't seem to beat experience like this. Projects teach how to actually use whats in the tutorials. Thanks for the help!
Topic archived. No new replies allowed.