954,480 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

attack function not altering stats

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.

writerervin
Newbie Poster
13 posts since Nov 2010
Reputation Points: 10
Solved Threads: 0
 

To change something you need an equal sign.

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

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

mike_2000_17
Posting Virtuoso
Moderator
2,134 posts since Jul 2010
Reputation Points: 1,634
Solved Threads: 457
 

Any reason for passing by pointer instead of by reference?

pseudorandom21
Practically a Posting Shark
890 posts since Jan 2011
Reputation Points: 216
Solved Threads: 111
 

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?

writerervin
Newbie Poster
13 posts since Nov 2010
Reputation Points: 10
Solved Threads: 0
 

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.

PhysicsExpert
Newbie Poster
16 posts since Jan 2011
Reputation Points: 10
Solved Threads: 2
 

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.

sfuo
Practically a Master Poster
656 posts since Jul 2009
Reputation Points: 164
Solved Threads: 99
 

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};
writerervin
Newbie Poster
13 posts since Nov 2010
Reputation Points: 10
Solved Threads: 0
 

Please also post

void setatk();
void setdef();

PhysicsExpert
Newbie Poster
16 posts since Jan 2011
Reputation Points: 10
Solved Threads: 2
 

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.

sfuo
Practically a Master Poster
656 posts since Jul 2009
Reputation Points: 164
Solved Threads: 99
 

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;
    }
}
writerervin
Newbie Poster
13 posts since Nov 2010
Reputation Points: 10
Solved Threads: 0
 

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

writerervin
Newbie Poster
13 posts since Nov 2010
Reputation Points: 10
Solved Threads: 0
 

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.

PhysicsExpert
Newbie Poster
16 posts since Jan 2011
Reputation Points: 10
Solved Threads: 2
 

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

writerervin
Newbie Poster
13 posts since Nov 2010
Reputation Points: 10
Solved Threads: 0
 
#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;
}
PhysicsExpert
Newbie Poster
16 posts since Jan 2011
Reputation Points: 10
Solved Threads: 2
 

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

writerervin
Newbie Poster
13 posts since Nov 2010
Reputation Points: 10
Solved Threads: 0
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: