I'm back and only with 52 errors this time :D

I've spent a couple hours revamping, simplifying and correcting some mistakes. currently, im confused with errors talking about "'_name': is not a member of 'Monster'" or "'Player::makeAttack': function does not take 3 arguments" because to my knowledge, i have declared them correctly but the compiler is telling me something else.

these are all the errors with the Combat files.

Error C2039 '_name': is not a member of 'Monster' C++ Course Work c:\users\kyle\documents\visual studio 2015\projects\c++ course work\c++ course work\combat.cpp 30 & 31 & 32

Error C2660 'Player::makeAttack': function does not take 3 arguments C++ Course Work c:\users\kyle\documents\visual studio 2015\projects\c++ course work\c++ course work\combat.cpp 39

Error C3867 'Monster::monAttack': non-standard syntax; use '&' to create a pointer to member C++ Course Work c:\users\kyle\documents\visual studio 2015\projects\c++ course work\c++ course work\combat.cpp 43 & 46 & 49


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include "Combat.h"


using namespace std;


int main()
{
	bool runCombat();

	system("PAUSE");
	return 0;
}


Combat.h
1
2
3
4
5
6
7
8
9
10
11
#pragma once
class Combat
{
public:
	Combat();
	
	bool runCombat();

private:
	int checkSpeed(int crea1, int crea2, int crea3, int crea4);
};


Combat.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 <iostream>
#include <string>
#include "Combat.h"
#include "Player.h"
#include "Monster.h"
#include "Scenario.h"

using namespace std;

Combat::Combat()
{
}

bool Combat::runCombat()
{
	Player kyle;

	Monster one;
	Monster two;
	Monster three;
	
	kyle.init(1, 10, 10, 3, 5, 6, 15, 12, 500, 1000);
	one.init(1, 10, 10, 2, 5, 6, 15, 12, 500, 1000);
	two.init(1, 10, 10, 1, 5, 6, 15, 12, 500, 1000);
	three.init(1, 10, 10, 4, 5, 6, 15, 12, 500, 1000);

	one._name = "Orrin";
	two._name = "Braedon";
	three._name = "Brent";

	int turn = checkSpeed(kyle._speed, one._speed, two._speed, three._speed);

	if (turn == 1) {
		int choice = kyle.pickAction();
		if (choice == 1) {
			kyle.makeAttack(one, two, three);
		}
	}
	else if (turn == 2) {
		one.monAttack;
	}
	else if (turn == 3) {
		two.monAttack;
	}
	else {
		three.monAttack;
	}
}

int Combat::checkSpeed(int crea1, int crea2, int crea3, int crea4)
{
	if (crea1 > crea2 && crea3 && crea4) {
		return 1;
	}
	else if (crea2 > crea1 && crea3 && crea4) {
		return 2;
	}
	else if (crea3 > crea1 && crea2 && crea4) {
		return 3;
	}
	else {
		return 4;
	}
}


Player.h
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
#pragma once
class Player
{
public:
	Player();
	void init(int level, int health, int defense, int speed, int damage, int attack, int stamina, int mana, int gold, int experience);

	int pickAction();

	void makeAttack(Monster target1, Monster target2, Monster target3);

	int _level;
	int _health;
	int _defense;
	int _speed;
	int _damage;
	int _attack;
	int _stamina;
	int _mana;
	int _gold;
	int _experience;

	int _wAttDice;
	int _wDamDice;

private:
	
};


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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "Player.h"
#include <iostream>
#include "Monster.h"
#include "Time.h"
#include <ctime>
#include <string>
#include "Dice.h"
#include "Weapon.h"

using namespace std;


Player::Player()
{
}

void Player::init(int level, int health, int defense, int speed, int damage, int attack, int stamina, int mana, int gold, int experience)
{
	_level = level;
	_health = health;
	_defense = defense;
	_speed = speed;
	_damage = damage;
	_attack = attack;
	_stamina = stamina;
	_mana = mana;
	_gold = gold;
	_experience = experience;
}


int Player::pickAction()
{
	whoops:
	int actionChoice;

	cout << "please pick an action!" << endl;
	cout << "1). Attack!" << endl;
	cout << "2). Cast Spell!" << endl;

	cin >> actionChoice;


	if (actionChoice == 1) {
		return 1;
	}
	else if (actionChoice == 2) {
		//Spell function
	}
	else {
		cout << "You cannot do that now!" << endl;
		goto whoops;
	}

}

void Player::makeAttack(Monster target1, Monster target2, Monster target3)
{
	//Initialize Weapon
	Weapon katana;
	katana.init("Katana", 6, 8);

	int aTotal;
	int dTotal;
	int iTotal;

	//Roll dice for Attack and Damage "ranges"
	Dice ATTACK;
	Dice DAMAGE;
	int attackDiceResults = ATTACK.diceRoller(katana._attackDice);
	int damageDiceResults = DAMAGE.diceRoller(katana._damageDice);

	//Add dice results with player stats.
	aTotal = _attack + attackDiceResults;
	dTotal = _damage + damageDiceResults;

	//Pick target
	cout << "Please pick a target" << endl;
	cout << "1)." << target1._name << endl;
	cout << "2)." << target2._name << endl;
	cout << "3)." << target3._name << endl;
	int choice;
	cin >> choice;

	//Check is attack beats target defense, then subtract armor from damage total and inflict to health.
	switch (choice)
	{
	case 1:
		if (aTotal >= target1._defense) {
			iTotal = dTotal - target1._armor;
			target1._health = iTotal;
			cout << "You have dealt " << iTotal << "damage to " << target1._name << "!" << endl;
			target1._health -= iTotal;
		}
		else {
			cout << "You're attack has missed!" << endl;
		}
		break;
	case 2:
		if (aTotal >= target2._defense) {
			iTotal = dTotal - target2._armor;
			target2._health = iTotal;
			cout << "You have dealt " << iTotal << "damage to " << target2._name << "!" << endl;
			target2._health -= iTotal;
		}
		else {
			cout << "You're attack has missed!" << endl;
		}
		break;
	case 3:
		if (aTotal >= target3._defense) {
			iTotal = dTotal - target3._armor;
			target3._health = iTotal;
			cout << "You have dealt " << iTotal << "damage to " << target3._name << "!" << endl;
			target3._health -= iTotal;
		}
		else {
			cout << "You're attack has missed!" << endl;
		}
		break;
	}
}




Monster.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#pragma once
class Monster
{
public:
	Monster();
	void init(int level, int health, int defense, int speed, int damage, int attack, int stamina, int mana, int armor, int magicResist);

	string _name;

	int _level;
	int _health;
	int _defense;
	int _speed;
	int _damage;
	int _attack;
	int _stamina;
	int _mana;
	int _armor;
	int _magicResist;

	void monAttack(Player player);

private:
};


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
#include "Monster.h"
#include <string>
#include <iostream>
#include "Weapon.h"
#include "Dice.h"
#include "Player.h"

using namespace std;

Monster::Monster()
{
}

void Monster::init(int level, int health, int defense, int speed, int damage, int attack, int stamina, int mana, int armor, int magicResist)
{
	_level = level;
	_health = health;
	_defense = defense;
	_speed = speed;
	_damage = damage;
	_attack = attack;
	_stamina = stamina;
	_mana = mana;
	_armor = armor;
	_magicResist = magicResist;
}

void Monster::monAttack(Player player)
{
	//Initialize Weapon
	Weapon club;
	club.init("Club", 4, 10);

	int aTotal;
	int dTotal;
	int iTotal;

	//Roll dice for Attack and Damage "ranges"
	Dice ATTACK;
	Dice DAMAGE;
	int attackDiceResults = ATTACK.diceRoller(club._attackDice);
	int damageDiceResults = DAMAGE.diceRoller(club._damageDice);

	//Add dice results with player stats.
	aTotal = _attack + attackDiceResults;
	dTotal = _damage + damageDiceResults;

	if (aTotal >= player._defense) {
		iTotal = dTotal - 5;
		player._health = iTotal;
		cout << "You have been dealt " << iTotal << "damage to!" << endl;
		player._health -= iTotal;
	}
	else {
		cout << _name << "has missed!" << endl;
	}
	

	
}




I've dont a little reasearch and am wondering if some of my classes should be structs. would that change anything? I've also heard of "deconstructors." are those needed in this program?
Last edited on
Try cleaning your project if you're using an IDE, or copying the code into a new project if that doesn't help.
Also a tip, you should be #including dependencies wherever needed, not just in main (In your case, you should put #include <string> in Monster.h - it won't make a difference for this project, but it could make errors confusing in future, bigger things).

Classes and structs are essentially the same thing in C++, unlike languages such as C#. A struct just has public access by default. Things are usually marked as private to let functions do implementation-side side effects without having the user of the class have to be worried about such details. For a simple class like yours, it doesn't really matter. But look up "encapsulation" as a general OOP term, and apply it where you think it makes sense.

A deconstructor will be made by the compiler if your class doesn't define one. For your classes in your post, no you do not need to define a deconstructor.

However, if, for example, you dynamically allocate memory or require a custom copy constructor or assignment operator, you probably will need to implement a custom destructor as well.
http://en.cppreference.com/w/cpp/language/rule_of_three

___________________
One thing I see you aren't doing is using constructors effectively in your code. Constructors let you immediately have your object in a usable state at the same time you declare the object itself. Basically, they do what your init() functions are doing, but all in one step and in a clearer way.
Last edited on
I'm reading you loud and clear with everything but the last part :) can you explain it again? Maybe with sme examples :)
Sure I'll try. Look at your combat.cpp's runCombat function. What if you just had:
1
2
3
4
5
Player kyle;
Monster one;
Monster two;
Monster three;
int turn = checkSpeed(kyle._speed, one._speed, two._speed, three._speed);

You construct the player and the monsters, but they still have uninitialized values after creation, so all the values are garbage and won't work correctly. In general, the class should be made so that this wouldn't occur, or had safeguards against it. You do this with your init() function, but you could do it all in one line if you made a custom constructor for your classes instead.

In other words, instead of
1
2
3
4
5
6
Monster();
void init(int level, int health, int defense, int speed, int damage, int attack, int stamina, int mana, int armor, int magicResist);

// called by
Monster one; // Still at potentially dangerous, unusable state!
one.init(1, 10, 10, 2, 5, 6, 15, 12, 500, 1000);

You could make the constructor do the work instead:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Monster::Monster(int level, int health, int defense, int speed, int damage, int attack, int stamina, int mana, int armor, int magicResist)
{
	_level = level;
	_health = health;
	_defense = defense;
	_speed = speed;
	_damage = damage;
	_attack = attack;
	_stamina = stamina;
	_mana = mana;
	_gold = gold;
	_experience = experience;
}
// called by:
Monster one(1, 10, 10, 2, 5, 6, 15, 12, 500, 1000);

That way, the object has valid values as soon as it's created.

_________________
Also, realize that you aren't actually calling any functions in main()
 
bool runCombat();

is just declaring a non-member function called runCombat that returns a bool.
You probably want to do
1
2
Combat combat;
combat.runCombat(); // lotta combat! 
Last edited on
Okay! That made much more sense. I'll try that when I get home. What about name? I seem to get errors with that no matter what.
In general, just look at the first error generated by the compiler. Following errors are likely to be caused by the first.

I would guess your _name woes come from not doing #include <string> where necessary.
so i need to add "#include <string>" to my .h files? I have string in all my .cpp files i believe.

and my first error was:

Error C2338 invalid template argument for uniform_real_distribution C++ Course Work c:\program files (x86)\microsoft visual studio 14.0\vc\include\random 3602

Dice.h
1
2
3
4
5
6
7
8
9
10
11
#pragma once
class Dice
{
public:
	Dice();
	int Dice::diceRoller(int x);
	
private:
	
};


Dice.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "Dice.h"
#include <ctime>
#include <random>
#include <iostream>

using namespace std;

Dice::Dice()
{
	
}

int Dice::diceRoller(int x)
{
	default_random_engine randomGenerator(time(NULL));
	uniform_real_distribution<int> roll(1, x);	
}


it doesn't point to these files but i believe the error is inside here.
Last edited on
Bumpity bump (i actually have no idea what this does but i assume it puts my post higher in the forum listing or something XD
so i need to add "#include <string>" to my .h files? I have string in all my .cpp files i believe.

You need to add #include <string> to the files that require it. For instance, Monster.h requires it. You #include it in Monster.cpp before you #include the <string> header, so the compiler doesn't know what a string is when it parses Monster.h.

Or, I suppose, you could just hope <string> gets somehow magically included before Monster.h. I'd prefer to avoid that situation myself.


Bumpity bump (i actually have no idea what this does but i assume it puts my post higher in the forum listing or something XD

Yes. We don't encourage bumps. If you want to bump a topic, add more information to it or clarify what you're asking about.

As for the error message: invalid template argument for uniform_real_distribution

You're using a uniform_real_distribution. If you want your random numbers to be ints, use a uniform_int_distribution. You should probably also return a value from a function that you promise to return a value from.

I would expect a Die class to look something like the following:

Die.h:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once

#include <random>

class Die
{
    std::uniform_int_distribution<unsigned> _dist;
    std::mt19937 _gen;

public:
    Die(unsigned sides);
    unsigned roll();

    unsigned getSides() const;
};


Die.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "Die.h"
#include <ctime>
#include <random>

Die::Die(unsigned sides)
    : _dist(1, sides), _gen(std::time(nullptr))
{
}

unsigned Die::roll()
{
    return _dist(_gen);
}

unsigned Die::getSides() const
{
    return _dist.b;
}
Topic archived. No new replies allowed.