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.
#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;
elsereturn 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;
}
elsereturn 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;
}
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.
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 ‘staticint 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
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.
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: ‘staticint character::hp()’
11 | staticint 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;
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:
#ifndef CHARACTER_HPP_INCLUDED
#define CHARACTER_HPP_INCLUDED
class Die{
public:
staticint 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
#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;
elsereturn 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;
}
elsereturn 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;
}
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.
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.
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!