changing private data of a class object in a vector...using functions!

Hello everyone.

I'm a bit new here so sorry if I make a mistake somewhere. I was recently attempting to make a working RPG, but during my tests I hit a bit of a snag. All I wanted to test was when the player attacks a monster saved in my vector Mparty, it not only displays the remaining Hp of the monster, but if the monster's Hp is 0, it is removed from the party (i.e. it died). I compiled my test, tried debugging it, compiled, and I'm still frustrated. What can I do?

Here are the files:

Monster.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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include "Monster.h"
#include <iostream>
#include <string>

Monster::Monster()
{
}

Monster::Monster(string mName,int mLvl,int mHp,int mStr,int mDef)
{
	name = mName;
	lvl = mLvl;
	Hp = mHp;
	Str = mStr;
	Def = mDef;
	dead = false;
}

string Monster::getName()
{
	return name;
}

int Monster::getLvl()
{
	return lvl;
}

int Monster::getHp()
{
	return Hp;
}

void Monster::setHp(int newHp)
{
	Hp = newHp;
}

int Monster::getStr()
{
	return Str;
}

void Monster::setStr(int newStr)
{
	Str = newStr;
}

int Monster::getDef()
{
	return Def;
}

void Monster::setDef(int newDef)
{
	Def = newDef;
}

bool Monster::KO()
{
	return dead;
}

void Monster::setKO(bool value)
{
	dead = value;
}


Player.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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include "Player.h"
#include <iostream>
#include <string>
using namespace std;

Player::Player(string mName,int mLvl,int mHp,int mStr,int mDef)
{
	name = mName;
	lvl = mLvl;
	Hp = mHp;
	Str = mStr;
	Def = mDef;
	dead = false;
}

string Player::getName()
{
	return name;
}

int Player::getLvl()
{
	return lvl;
}

int Player::getHp()
{
	return Hp;
}

void Player::setHp(int newHp)
{
	Hp = newHp;
}

int Player::getStr()
{
	return Str;
}

void Player::setStr(int newStr)
{
	Str = newStr;
}

int Player::getDef()
{
	return Def;
}

void Player::setDef(int newDef)
{
	Def = newDef;
}

bool Player::KO()
{
	return dead;
}

void Player::setKO(bool value)
{
	dead = value;
}


Monster_Party.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
49
50
51
52
53
54
55
56
57
58
#include "Monster_Party.h"
#include <iostream>

using namespace std;

Mparty::Mparty()
{
	mParty.resize(0);
}

void Mparty::add(Monster& monster)
{
	mParty.push_back(monster);
}

void Mparty::print()
{
	for (unsigned int i = 0; i < mParty.size(); i++)
	{
		cout << "Monster " << i+1 << endl;
		cout << mParty[i].getName() << " Hp: " << mParty[i].getHp() << endl << endl;
	}
}

int Mparty::getsize()
{
	return mParty.size();
}

void Mparty::remove(Monster& monster)
{
	int position;
	for (unsigned int i = 0; i < mParty.size(); i++)
	{
		Monster M1 = mParty[i];

		if (M1.getName() == monster.getName())
		{
			position = i;
		}

		else
		{
			cout << endl;
			cout << "Not found.\n";
		}
	}

	mParty.erase(mParty.begin()+position);
	return;
}

Monster Mparty::getMon(int position)
{
	Monster aMonster;
	aMonster = mParty[position];
	return aMonster;
}


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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "Player.h"
#include "Monster.h"
#include "Monster_Party.h"
#include <iostream>
#include <string>
using namespace std;

void battle(Player& player,Mparty& p);
Monster Choice(Mparty& party);
void damage(Player& player,Monster& m);


int main()
{
	Player p1 = Player("Anthony",20,100,20,20);
	Monster m1 = Monster("Rat",1,10,5,4);
	Monster m2 = Monster("Goblin",3,30,10,8);
	Monster m3 = Monster("Sorceror",5,50,15,15);

	Mparty mp1;

	mp1.add(m1);
	mp1.add(m2);
	mp1.add(m3);

	cout <<"Time for the test...\n";

	battle(p1,mp1);

	cout << "Finished" << endl;
	system("pause>nul");
	return 0;
}

Monster Choice(Mparty& party)
{
	int xin;
	cin >> xin;
	return party.getMon(xin-1);
}

void damage(Player& player,Monster& m)
{
	int damage = player.getStr() - m.getDef();
	if (damage <= 0)
	{
		damage = 0;
	}

	m.setHp(m.getHp()-damage);
	if (m.getHp() <= 0)
	{
		m.setHp(0);
	}
}

void battle(Player& player,Mparty& p)
{
	while (p.getsize() != 0)
	{
		for (unsigned int i = 0; i < p.getsize(); i++)
		{
			if (p.getMon(i).getHp() == 0)
			{
				p.remove(p.getMon(i));
			}
		}
		p.print();
		damage(player,Choice(p));
		system("cls");
	}
}


Please don't make fun of my lack of skill here. I'm still a total noob in my opinion so just keep that in mind. Let me know if there is anything else I need to fix.
Last edited on
Antman777 wrote:
All I wanted to test was when the player attacks a monster saved in my vector Mparty, it not only displays the remaining Hp of the monster, but if the monster's Hp is 0, it is removed from the party (i.e. it died). I compiled my test, tried debugging it, compiled, and I'm still frustrated. What can I do?
Okay, you've told us the expected behavior, but you haven't told us what's happening instead. What's wrong?
Well, so far what is happeneing is that when I choose a monster to attack, the screen refreshes and the monsters have the same health as before, even though I had chosen a monster to attack and I'm pretty sure the player object I created has enough attack to at least hurt one of them. It's as if nothing happened.
Choice returns a monster object by value. Line 69 wouldn't compile in a conforming compiler, so I'm guessing you're using VC++ with the extension to allow temp objects to be bound to non-const references. Any changes to that object will be lost.
So how exactly would I fix this issue. My intention was not to have a monster object be passed by value.
Don't return by value. If you didn't intend to return by value, what did you intend to return by?
Alright, so I understand this, but based on my Choice function, I am passing the monster party object by reference. How do I also pass the monster objects in the party by reference as well?
Change getMon(int position):
1
2
3
4
Monster &Mparty::getMon(int position) // Note: &
{
	return mParty[position];
}


In Choice(Mparty& party) you have a problem: The user might enter something invalid, hence you need to do something to prevent this.

1
2
3
4
5
6
7
8
9
Monster &Choice(Mparty& party) // Note: &
{
	int xin;
	while(!(cin >> xin) || (xin < 1) || (xin > party.size()))
{
  // ... Error handling
}
	return party.getMon(xin-1);
}
Well, I tried what you suggested coder and my program still isn't taking the Monster object by reference. It continues to run after input with no changes to Hp or anything.

1
2
3
4
5
6
7
8
9
10
11
12
Monster &Choice(Mparty& party)
{
	int xin;
	cin >> xin;
	while ((xin < 1) || (xin > party.getsize()))
	{
		cout << "\nInvalid input.\n";
		cin >> xin;
	}

	return party.getMon(xin-1);
}


1
2
3
4
5
6
Monster &Mparty::getMon(int position)
{
	Monster aMonster;
	aMonster = mParty[position];
	return aMonster;
}


Monster party class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef MONSTER_PARTY_H
#define MONSTER_PARTY_H

#include <iostream>
#include <vector>
#include "Monster.h"
using namespace std;

class Mparty
{
public:
	Mparty();
	void add(Monster&);
	Monster &getMon(int);
	void print();
	int getsize();
	void remove(Monster&);

private:
	vector<Monster> mParty;
};

#endif 


EDIT:Ah I see the problem. I needed to change getMon member to "return mparty[position]". Thanks guys!!
Last edited on
Topic archived. No new replies allowed.