How to call next line of code after function?

I'm practicing by making this text rpg and I am having a hard time with the attack function that I created. Right now it just breaks and ends the program, I just want it to go to the next available line of code if the player wins the battle. I'm guessing it could have something to do with getline but I'm not very familiar with it. I vaguely remember going over it, but I suppose there is google... Thanks everyone!

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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// TEXT RPG.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <stdlib.h>
#include <stdio.h> 

using namespace std;

int attack() {
	srand(time(0));
	return (rand() % 10);
}

int npcattack() {
	srand(time(0));
	return (rand() % 12);
}

void menu() {
	int k = 0;
	cout << "Bash<1> Cleave<2> Gash<3> Stomp<4>" << endl;
	cin >> k;

	if (k == 1) {
		cout << "The warrior bashes the enemy with his weapon!" << endl;
	}

	if (k == 2) {
		cout << "Cleave attack!" << endl;
	}

	if (k == 3) {
		cout << "Gash attack!" << endl;
	}

	if (k == 4) {
		cout << "Stomp attack!" << endl;
	}

	while (k > 4) {
		cout << "That is not an attack!" << endl;
		cin >> k;
	}
	cout << "The warrior attacks for " << attack() << " HP" << endl;
}

class character {
private: int hp = 30;
		 int npchp = 18;
		 int boss = 24;
		 int xp, total, totalLvl = 0;
		 int lvl = 1;

public:

	int hit() {
		cout << "The enemy strikes" << endl;
		cout << "You were hit for " << npcattack() << endl;
		hp -= npcattack();
		hp--;
		cout << "HP = " << hp << endl;
		if (hp < 1) {
			cout << "GAME OVER" << endl;
		}
		return hp;
	}

	int hitFor() {
		cout << "You hit the enemy for " << attack() << endl;
		npchp -= attack();
		npchp--;
		cout << "Enemy HP = " << npchp << endl;
		if (npchp < 1) {
			cout << "VICTORY" << endl;
		}
		return npchp;
	}

	void fight() {
		character action;

		while (action.npchp > 0 && action.hp > 0) {
			menu();
			action.hitFor();
			if (action.npchp <= 0) {
				system("pause");
			}
			cout << endl;
			action.hit();
		}

		if (action.hp <= 0) {
			cout << "GAME OVER" << endl;
			system("pause");

		}

		return;
	}

	int xpup() {
		xp += total;
		xp++;
		if (xp % 5) {
			cout << "Level Up!" << endl;
			lvl += totalLvl;
			lvl++;
		}
	}

	};


	int main()
	{

		character action1;

		cout << "TEXT RPG*****************by... JACOB STEWART" << endl;
		cout << endl;
		cout << endl;
		cout << "You awaken in a dim forest" << endl;
		cout << "You, the burly warrior picks up the axe\n"
			"laying on the ground in front of you" << endl;
		cout << "The axe is heavy, but you are strong." << endl;
		cout << "In the distance there is a group of bandits." << endl;
		cout << "They draw nearer and they want blood." << endl;

		action1.fight();

		cout << "The bandits lay bloody on the ground." << endl;








		return 0;
	}


Your code logic is all over the place - you're not doing yourself any favors by making a class and then making it really hard to use.

In my eyes, a Character should have some statistics (HP, etc), and an attack function.
A Character shouldn't have three different HP's, and then different functions that create new characters so that it can pretend to direct a scene.

Let's keep it very basic for now.

Like I said, a Character should have HP. Let's do that then:

1
2
3
4
5
6
7
8
class Character {
	int health = 100;

public :
	int getHealth() { return health; }
	void takeDamage(unsigned int damage) { health -= damage; }

};


First of all, I've elected to name the "HP" integer "health" instead.
I've also decided to name the class Character and not character. This is more of a stylistic thing - I prefer to capitalize class names.

The int health is private by default. I'm also taking advantage of a C++11 feature which allows me to initialize in-class types other than const static integral ones on the same line on which they are declared.

We have to public methods that deal with our health variable. getHealth simply returns the current health, and takeDamage subtracts the argument from the current health. The argument is an unsigned integer, because if it was signed, you could pass negative numbers to the function - effectively "healing" a character.

I also said that a character should be able to attack another character. Let's do that now:

1
2
3
4
5
6
7
8
9
class Character {
	int health = 100;

public :
	int getHealth() { return health; }
	void takeDamage(unsigned int damage) { health -= damage; }

	void attack(Character& enemy) { enemy.takeDamage(10); }
};


All I've done is added another function called attack. This function takes a Character by reference as an argument. When an object exists outside of a function, but you want to modify that object in that function, you can pass the object by reference (or pass a pointer). The name we've given our reference in this case ("enemy") is just an alias, a handle to the actual object that was passed into the function, which allows us to modify the original.
If we didn't pass by reference, and passed by value, we would be modifying a copy, and any changes made to the copy would not be reflected in the original object. Furthermore, the copy would cease to exist once the function terminates.

Right now, the attack method only subtracts ten from the enemy's health. It's just a placeholder value.

Finally, this is how you might use this class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Character {
	int health = 100;

public :
	int getHealth() { return health; }
	void takeDamage(unsigned int damage) { health -= damage; }

	void attack(Character& enemy) { enemy.takeDamage(10); }
};

int main() {

	Character hero;
	Character villain;

	while (hero.getHealth() > 0 && villain.getHealth() > 0) {

		hero.attack(villain);
		villain.attack(hero);

	}

	return 0;
}
Last edited on
Thanks for the concise answer, your experience shows. The two separate classes or objects does make sense and was something I was originally going to do but was getting an error when setting up the second class... probably something to do with } placement, which I can mess with and figure out. I'll go back and alter the code with this in mind for sure, since it is a lot simpler. My reasoning behind the many functions in the class was to write the actual game a little easier in the int main function. If I want a fight to occur I just type action.fight() and done. This is mainly out of laziness and not wanting to type a lot to create the game... there are a lot of different paths I would like the player to be able to take which all need to be coded into the game.



TL DR: Thanks so much for your long and well written response. It has allowed a fresh look at creating classes. Could I just do this out of laziness, keeping me from typing that while loop for every fight instance?
Sorry if I'm asking about things that you already covered.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Character hero;
Character villain;

int fight(){
while (hero.getHealth() > 0 && villain.getHealth() > 0) {

		hero.attack(villain);
		villain.attack(hero);

	}
return;
}

int main() {


fight();

return 0;


Keeping class stats separate from actual actions, while keeping actions in a function for ease of writing. Is that good coding practice or no?
Last edited on
It is good practice to separate things into functions and classes. This is perfectly fine. At some point you may want to avoid using variables- and objects in global scope, but that's a different topic. You'll also want to be careful using words like "class" and "object" interchangeably.
"Class" refers to the cookie cutter, "object" or "instance" refer to the cookie - if that makes sense.
The only other thing I would point out is that your fight function would be better suited having a void return type, as opposed to int.
In addition, here's a quick lesson on using rand and srand:

srand is the function that seeds the pseudo-random number generator, and rand is the function that returns a pseudo-random number between 0 and RAND_MAX (where RAND_MAX that's defined in <cstdlib>, and guaranteed to be at least 32767 on any implementation) based on that seed.
For your purposes, you only want to seed once during your entire program's duration - this is typically done at the start of the main function.
For further reading (which I recommend) : http://www.cplusplus.com/faq/beginners/random-numbers/
Last edited on
Topic archived. No new replies allowed.