i'm doing a rpg for fun but this one function is giving me problems. it compiles without problems, but when i test it, the hp stats done change. this is the code for the function.

void attack(dragon *d1, dragon *d2)
{
    if(d1->getdef() < d2->getatk())
    {
        d1->changehp(- ( d2->getatk() - d1->getdef() ) );
    }else if(d2->getdef() < d1->getatk())
    {
    	d2->changehp(- (d1->getatk() - d2->getdef() ) );
    }
    if(d1->gethp() == 0)
    	d1->setout(true); /* set to unconscious */
}

and this is the code for the dragon class

class dragon {
private:
    string name;
    int atk, def, acc;
    int type, lvl, hp, hpmax, exp, expmax;
    int out;
public:
    dragon(string str = "wild dragon", int level = 5);
    string getname(){return name;};
    int gethp(){ return hp;};
    int gethpmax(){ return hpmax;};
    int getexpmax(){ return expmax;};
    int getatk(){return atk;};
    int getdef(){return def;};
    int getexp(){return exp;};
    int getacc(){return acc;};
    int getout(){return out;};
    void changehp(int s);
    void setname(string str) { name = str; };
    void sethpmax(){hpmax = lvlhp[lvl - 1];};
    void setexpmax(){expmax = lvlexp[lvl - 1];};
    void setatk();
    void setdef();
    int getlvl(){return lvl;};
    void setout(int s){ out = s;};
    void setacc(){acc += 5;};
    void setlvl(int level){ lvl = level; };
};

i would appreciate any help you could give me.

Recommended Answers

All 15 Replies

To change something you need an equal sign.

The only function that matters here is the changehp() function, and you didn't post it. Please do.

Any reason for passing by pointer instead of by reference?

this is the code to alter the hp.

void dragon::changehp(int s)
{
	if((hp + s) != hpmax)
	{
		hp += s;
	}else if(hp < 0)
	{
		hp = 0;
		setout(true);
	}
}

do you think it would be better to use reference in the attack function?

Everything bigger than a wchar_t is usually passed by reference (Unless there is a good reason not to do so, but these are exceptions and as you didnt use it I presume you would not benefit from knowing any exceptions).

Also please post the constructor. And also whats this:

void sethpmax(){hpmax = lvlhp[lvl - 1];};
void setexpmax(){expmax = lvlexp[lvl - 1];};

Random arrays assigned to int? This should not even compile.

void sethpmax(){hpmax = lvlhp[lvl - 1];};
void setexpmax(){expmax = lvlexp[lvl - 1];};

Random arrays assigned to int? This should not even compile.

This looks fine to me. Hes assigning the units health to whatever is at lvlhp[lvl-1] is. So if the guy is level 5 it would be lvlhp[5-1] or lvlhp[4]. That makes perfect sense.

this is the constuctor for the dragon class.

dragon::dragon(string str,int level) {
    name = str;
    int tp = ((rand() % 6) + 1);
    type = tp;
    lvl = level;
    setatk();
    setdef();
    setexpmax();
    sethpmax();
    hp = hpmax;
    setacc();
    setout(false);/* set to conscious */
}

and this is the code for the arrays.

int lvlhp[19]  = {25, 52, 84, 107, 155, 205, 259, 304, 349, 403, 460, 510, 670, 790, 800, 940, 1080, 1200};
int lvlexp[19] = {40, 65, 90, 125, 140, 200, 280, 340, 400, 460, 590, 700, 850, 999, 1100, 1250, 1490, 1700};
int lvlatk[19] = {3, 5, 7, 9, 11, 14, 17, 20, 24, 28, 32, 36, 40, 45, 50, 55, 60, 65};
int lvldef[19] = {1, 3, 5, 7, 9, 12, 14, 18, 22, 26, 28, 33,  37, 42, 47, 51, 57, 63};

Please also post

void setatk();
void setdef();

This is a basic version of what I think you are trying to do.

#include <iostream>
using namespace std;

class DRAGON
{
	public:
	int hp;
	int def;
	int atk;

	bool alive;

	DRAGON();
	int getHealth();
	void setHealth(int);

};

DRAGON::DRAGON()
{
	hp = 50;
	def = 2;
	atk = 10;
	alive = true;
}

int DRAGON::getHealth()
{
	return hp;
}

void DRAGON::setHealth( int dmg )
{
	if( hp - dmg < 0 )
		hp = 0;
	else
		hp -= dmg;
}

void attackPTR( DRAGON *d1, DRAGON *d2 )
{
	d1->setHealth(d2->atk - d1->def);
	d2->setHealth(d1->atk - d2->def);
}

void attackREF( DRAGON &d1, DRAGON &d2 )
{
	d1.setHealth(d2.atk - d1.def);
	d2.setHealth(d1.atk - d2.def);
}

int main()
{
	DRAGON d1, d2;

	attackPTR( &d1, &d2 ); //using pointer attack function

	cout << "d1: " << d1.getHealth() << " d2: " << d2.getHealth() << endl;

	attackREF(d1, d2); //using reference attack function
	cout << "d1: " << d1.getHealth() << " d2: " << d2.getHealth() << endl;

	return 0;
}

I put in both pointer and ref attack functions to show that they do the exact same thing but by reference makes it so you dont have to keep putting in the arrows and you do not have to pass by reference in the function usage.

I would try to use your code to show you an example but you are showing code that doesnt have to be posted for your problem and now showing parts that are key to finding the error.

And by the looks of it your attack function will never set the health to 0 because unless you are at "hpmax" (I'm guessing 100% health) then it will always reduce your health by the damage coming in (see my changeHealth() function).

The only reason I could see your dragons not doing damage to each other would be that their attack damage and defense are equal making it so that that never attack.

this is where the dragons are initialized:

dragon *pets[3];
    dragon *wild;
    int i = 0;
    srand(time(NULL));
    wild = new dragon("wild dragon");
	for(i = 0; i < 3; i++)
	{
		cout << endl << "name your dragon: ";
		cin >> name;
		cout << endl << "set his level: ";
		cin >> level;
		pets[i] = new dragon(name,level);
	}

i thought that if i declared it as a pointer it would be easier to set the levels when i named them.
heres the code to set the atk and def.

void dragon::setatk()
{
    int dif;
    dif = lvldef[lvl - 1] -lvldef[lvl - 2];
    if(def > lvldef[lvl - 2]){
            def = lvldef[lvl - 1];
    }
    else{
        def += dif;
    }

}

void dragon::setdef()
{
int dif;
    dif = lvldef[lvl - 1] -lvldef[lvl - 2];
    if(def > lvldef[lvl - 2]){
            def = lvldef[lvl - 1];
    }
    else{
        def += dif;
    }
}

or would it be better to declare them as normal and make another function to change the lvl?

The problem is that you copy pasted too much...in the attack function void dragon::setatk()...take a look. Attack never gets initialized.

Also what if the att and def for two dragons are the same? Fix that as well.

i see what your saying. i went back and fixed that. but its still not altering the hp of the dragon.
also altered the attack function to show which dragon won, the calculations look right but there is still no change in the hp

#include <iostream>
#include <string>
using namespace std;

namespace config {
const int MAX_SIZE = 19;
int lvlhp[MAX_SIZE]  = {25, 52, 84, 107, 155, 205, 259, 304, 349, 403, 460, 510, 670, 790, 800, 940, 1080, 1200};
int lvlexp[MAX_SIZE] = {40, 65, 90, 125, 140, 200, 280, 340, 400, 460, 590, 700, 850, 999, 1100, 1250, 1490, 1700};
int lvlatk[MAX_SIZE] = {3, 5, 7, 9, 11, 14, 17, 20, 24, 28, 32, 36, 40, 45, 50, 55, 60, 65};
int lvldef[MAX_SIZE] = {1, 3, 5, 7, 9, 12, 14, 18, 22, 26, 28, 33,  37, 42, 47, 51, 57, 63};
}


class dragon {
private:

    string name;
    int atk, def, acc;
    int type, lvl, hp, hpmax, exp, expmax;
    int out;

public:

    dragon(string str = "wild dragon", int level = 5);

    string getname(){return name;};

    int gethp(){ return hp;};
    int gethpmax(){ return hpmax;};
    int getexpmax(){ return expmax;};
    int getatk(){return atk;};
    int getdef(){return def;};
    int getexp(){return exp;};
    int getacc(){return acc;};
    int getout(){return out;};
	int getlvl(){return lvl;};

    void changehp(int s);
    void setname(string str) { name = str; };
    void sethpmax(){hpmax = config::lvlhp[lvl - 1];};
    void setexpmax(){expmax = config::lvlexp[lvl - 1];};
    void setatk();
    void setdef();
    void setout(int s){ out = s;};
    void setacc(){acc += 5;};
    void setlvl(int level){ lvl = level; };
	void attack(dragon*, dragon*);
};


dragon::dragon(string str,int level) {
    name = str;
    int tp = ((rand() % 6) + 1);
    type = tp;
    lvl = level;

	atk = config::lvlatk[level-1];
	def = config::lvldef[level-1];

    setatk();
    setdef();
    setexpmax();
    sethpmax();
    hp = hpmax;
    setacc();
    setout(false);/* set to conscious */
}

void dragon::changehp(int s)
{
	if((hp + s) != hpmax)
	{
		hp += s;
	}else if(hp < 0)
	{
		hp = 0;
		setout(true);
	}
}

void dragon::attack(dragon *d1, dragon *d2)
{

    if(d1->getdef() < d2->getatk())
    {
        d1->changehp(- ( d2->getatk() - d1->getdef() ) );
    }else if(d2->getdef() < d1->getatk())
    {
    	d2->changehp(- (d1->getatk() - d2->getdef() ) );
    }
    if(d1->gethp() == 0)
    	d1->setout(true); /* set to unconscious */
}

void dragon::setatk()
{
    int dif;
	dif = config::lvlatk[lvl - 1] - config::lvlatk[lvl - 2];
    if(atk > config::lvlatk[lvl - 2]){
            atk = config::lvlatk[lvl - 1];
    }
    else{
        atk += dif;
    }
 
}
 
void dragon::setdef()
{
int dif;
    dif = config::lvldef[lvl - 1] - config::lvldef[lvl - 2];
    if(def > config::lvldef[lvl - 2]){
            def = config::lvldef[lvl - 1];
    }
    else{
        def += dif;
    }
}

int main()
{

	dragon d1, d2;

	dragon *pt = &d1;
	dragon *pd = &d2;

	pt->attack(pt, pd);
	cout << "onehp: " << pt->gethp()<< " twohp = " << pd->gethp()<< endl;

	pt->attack(pt, pd);
	cout << "onehp: " << pt->gethp()<< " twohp = " << pd->gethp()<< endl;

	pt->attack(pt, pd);
	cout << "onehp: " << pt->gethp()<< " twohp = " << pd->gethp()<< endl;

	cin.get();

return 0;
}

that's great. thanks so much. this has given me problems for days.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.