Text based rpg examples


Hi, I would like to show you guys a text based rpg that my friend and I made, it involves 2 guys dueling till submission with the values being random. Please give your thoughts on how we did.

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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#include<iostream>
#include<fstream>
#include<cmath>
#include<cstdlib>
#include<conio.h>
#include<iomanip>
#include<Windows.h>
using namespace std;

int Start(int&, int&, int&, int&);
int battleGear(int&, int&, int&, int&);
int duel(int&, int&, int&, int&);
int showYourHealth(int&);
int showEnemyHealth(int&, int&);

int main()
{
	int begins;
	int weapon;
	int enemyHealth;
	int Health;

	Start(begins, weapon, enemyHealth, Health);
	battleGear(weapon, enemyHealth, Health, begins);
	duel(weapon, enemyHealth, Health, begins);
	showEnemyHealth(enemyHealth, weapon);
	showYourHealth(Health);

	ofstream GroupAssignment;
	GroupAssignment.open(" GroupAssignment.txt");
	GroupAssignment << "This is a game group assignment for programming.";
	GroupAssignment.close();
}

int Start(int& begins, int& weapon, int& enemyHealth, int& Health)
{

	cout << "A man insults you in a bar and challenges you to a duel, do you accept?" << endl;
	cout << "\n" << endl;
	cout << "Accept = 1" << endl;
	cout << "Decline = 2" << endl;
	cout << "\n" << endl;
	cout << "Please enter your choice: ";
	cin >> begins;
	cout << "\n" << endl;

	if (begins == 1)
	{
		cout << "\nThe man nods, as you both step outside to battle each other.\n" << endl;
		Sleep(2000);
		system("CLS");
		battleGear(weapon, enemyHealth, Health, begins);
	}
	else if (begins == 2)
	{
		cout << "The whole bar laughs at you as you decline the duel and leave the bar.\n" << endl;
		Sleep(3000);
		system("CLS");
		return main();
	}
	else
	{
		cout << "This choice is invalid, you can't do that, lets start all over\n" << endl;
		Sleep(3000);
		system("CLS");
		return main();
	}
	return 0;
}

int battleGear(int& weapon, int& enemyHealth, int& Health, int& begins)
{

	cout << "Choose your weapon, and I will follow suit:" << "\n\n" << endl;
	cout << " 1. Longsword" << "\n" << endl;
	cout << " 2. Musket" << "\n" << endl;
	cout << " 3. Spear" << "\n" << endl;
	cout << " 4. Bow" << "\n" << endl;
	cout << " 5. Brass Knuckles" << "\n" << endl;
	cout << " 6. Magic" << "\n" << endl;
	cout << "\n" << endl;
	cout << "Please enter your choice: ";
	cin >> weapon;
	cout << "\n" << endl;

	switch (weapon)
	{
	case 1: //You will use a longsword. 
	{
		srand((unsigned int)time(NULL));
		cout << "The longsword eh, a standard choice.\n\n" << endl;
		weapon = rand() % 20 + 5;
		Sleep(2000);
		system("CLS");
		duel(weapon, enemyHealth, Health, begins);
		break;
	}

	case 2: //You will use a musket. (though like a gun, you can either hit hard or miss it all.)
	{
		srand((unsigned int)time(NULL));
		cout << "Muskets, sure, but do you have a good trigger finger?\n\n" << endl;
		weapon = rand() % 30 + 1;
		Sleep(2000);
		system("CLS");
		duel(weapon, enemyHealth, Health, begins);
		break;
	}

	case 3: //You will use the spear. (A long range weapon with mediocre damage but consistent when compared to the other weapons.)
	{
		srand((unsigned int)time(NULL));
		cout << "How primitive, but interesting....\n\n" << endl;
		weapon = rand() % 15 + 10;
		Sleep(2000);
		system("CLS");
		duel(weapon, enemyHealth, Health, begins);
		break;
	}

	case 4: //You will use the bow. (Similar to the musket, but a bit more consistent, but less damaging)
	{
		srand((unsigned int)time(NULL));
		cout << "My skills with the arrow are impeccable, shoot if you must.\n\n" << endl;
		weapon = rand() % 20 + 10;
		Sleep(2000);
		system("CLS");
		duel(weapon, enemyHealth, Health, begins);
		break;
	}

	case 5: //You will use the brass knuckles. (You're using your fists with metal wrapped around it, good luck Mike Tyson.)
	{
		srand((unsigned int)time(NULL));
		cout << "A pugilist, barbaric. Though I wouldn't mind a bit of rough-housing, bring it.\n\n" << endl;
		weapon = rand() % 30 + 10;
		Sleep(2000);
		system("CLS");
		duel(weapon, enemyHealth, Health, begins);
		break;
	}

	case 6: //You will use magic. (No need for explanations, go for broke with EXPLOSIONS!!!)
	{
		srand((unsigned int)time(NULL));
		cout << "Ah, I see that you're a person of culture as well.\n\n" << endl;
		weapon = rand() % 200 + 199;
		Sleep(2000);
		system("CLS");
		duel(weapon, enemyHealth, Health, begins);
		break;
	}

	default: //If you choose anything but the options given.
	{
		cout << "Last time I checked, a duel requires some sort of weapon, choose again....\n\n" << endl;
		Sleep(1000);
		battleGear(weapon, enemyHealth, Health, begins);
		break;
	}
	}
	return 0;
}

int duel(int& weapon, int& enemyHealth, int& Health, int& begins)
{
	Health = 200, enemyHealth = 200;
	int fight;

	do
	{
		cout << "Hit him?" << endl;
		cout << "\n" << endl;
		cout << "Yes = 1" << endl;
		cout << "No = 2" << endl;
		cout << "\n" << endl;
		cout << "Please enter your choice: ";
		cin >> fight;
		cout << "\n" << endl;

		switch (fight)
		{
		case 1: // You chose to hit him
		{
			enemyHealth = showEnemyHealth(enemyHealth, weapon);
			Health = showYourHealth(Health);
			cout << "You hit him!" << endl;
			cout << "Your opponent has \t" << enemyHealth << "\t health left.\n" << endl;

			if (Health <= 0)
			{
				cout << "Aha, It was clear that I would win the duel, do better next time you peasant!!" << endl;
				Sleep(3000);
				system("CLS");
				Start(begins, weapon, enemyHealth, Health);
				return 0;
			}

			else if (enemyHealth <= 0)
			{
				cout << "STOP, I GIVE UP, YOU WON, YOU'RE BETTER THAN ME.\n" << endl;
				Sleep(2000);
				cout << "Till we meet again for another duel.\n\n" << endl;
				Sleep(2000);
				cout << "2 weeks later........." << endl;
				Sleep(3000);
				system("CLS");
				Start(begins, weapon, enemyHealth, Health);
				return 0;
			}

			else if (enemyHealth > 0)
			{
				cout << "Your opponent has hit you back!" << endl;
				cout << "You now have \t" << Health << "\t health left.\n\n" << endl;
			}

			break;
		}

		case 2://You decided to not hit him.
		{
			Health = showYourHealth(Health);
			cout << "You think this is ridiculous and refuse to hit him, but he hits you anyway.\n" << endl;

			if (Health <= 0)
			{
				cout << "Aha, It was clear that I would win the duel, do better next time you peasant!!" << endl;
				Sleep(3000);
				system("CLS");
				Start(begins, weapon, enemyHealth, Health);
				return 0;
			}


			else if (enemyHealth > 0)
			{
				cout << "Your opponent has hit you back!" << endl;
				cout << "You now have \t" << Health << "\t health left.\n\n" << endl;
			}

			break;
		}

		default:// You pressed anything but 1 or 2.
		{
			cout << "You can't do that, it's not possible!\n" << endl;
		}
		}

	} while (Health > 0 && enemyHealth > 0);
	return 0;
}

int showEnemyHealth(int& enemyHealth, int& weapon)
{
	enemyHealth = enemyHealth - weapon;
	return enemyHealth;
}

int showYourHealth(int& Health)
{
	Health = Health - rand() % 20;
	return Health;
}
Last edited on
Lines 90,101,112,123,134,145: time() requires the <ctime> header which you have not included.

Lines 90,101,112,123,134,145: Do not call srand() multiple times. srand() sets the RNG to a particular starting point. Calling srand() repeatedly can cause the RNG to return the same random numbers. srand() should be called ONCE at the beginning of main().
http://www.cplusplus.com/reference/cstdlib/srand/

Lines 59,66: It is illegal to call main() recursively.

@AbstractionAnon why is it illegal if I call main recursively, the program works though.
why is it illegal if I call main recursively

Most directly, because the standard mandates that a correct program shall not use the main function.

8.2.2.10 [expr.call]
Recursive calls are permitted, except to the main function.
http://eel.is/c++draft/expr.call#10
6.6.1.3 [basic.start.main]
The function main shall not be used within a program. ...
http://eel.is/c++draft/basic.start.main#3

I'm not certain of the committee's rationale for that restriction. I speculate that it has something to do with the code generation technique of placing code that completes dynamic initialization in the main function, especially in freestanding environments where main is not called by a runtime library. Just a guess.
Last edited on
@mbozzi though illegal, it's still viable in this case right, or is there a better option
Change your main() to
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int game_main()
{
	int begins;
	int weapon;
	int enemyHealth;
	int Health;

	Start(begins, weapon, enemyHealth, Health);
	battleGear(weapon, enemyHealth, Health, begins);
	duel(weapon, enemyHealth, Health, begins);
	showEnemyHealth(enemyHealth, weapon);
	showYourHealth(Health);

	return 0 ; // with an added return 0 ;
}


Write a new main() int main() { return game_main() ; }

And everywhere else, replace the call main() with a call to game_main()
1
2
// return main() ;
return game_main() ;
though illegal, it's still viable

Just because an incorrect program works for you right now doesn't mean it will work always for everyone later. The law of parsimony suggests that if there wasn't a need for that restriction it wouldn't be there. So it's probably not viable.
I think there is just too much recursion in your program, even without your calls to main. You
should use more looping.

Look at Start():

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
int Start(int& begins, int& weapon, int& enemyHealth, int& Health)
{

	cout << "A man insults you in a bar and challenges you to a duel, do you accept?" << endl;
	cout << "\n" << endl;
	cout << "Accept = 1" << endl;
	cout << "Decline = 2" << endl;
	cout << "\n" << endl;
	cout << "Please enter your choice: ";
	cin >> begins;
	cout << "\n" << endl;

	if (begins == 1)
	{
		cout << "\nThe man nods, as you both step outside to battle each other.\n" << endl;
		Sleep(2000);
		system("CLS");
		battleGear(weapon, enemyHealth, Health, begins);
	}
	else if (begins == 2)
	{
		cout << "The whole bar laughs at you as you decline the duel and leave the bar.\n" << endl;
		Sleep(3000);
		system("CLS");
		return main();
	}
	else
	{
		cout << "This choice is invalid, you can't do that, lets start all over\n" << endl;
		Sleep(3000);
		system("CLS");
		return main();
	}
	return 0;
}


If you fail to get a reasonable response, why go back to main (or game_main as JLBorges suggested)? You should just loop until you get the answer that you want.

Then, don't call battleGear from within Start(). You call it from main() already. I don't think you want to call it from Start() and then call it again when Start() returns.

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
int Start(int& begins, int& weapon, int& enemyHealth, int& Health)
{
	bool needResponse = true;

	while (needResponse)
	{
		cout << "A man insults you in a bar and challenges you to a duel, do you accept?" << endl;
		cout << "\n" << endl;
		cout << "Accept = 1" << endl;
		cout << "Decline = 2" << endl;
		cout << "\n" << endl;
		cout << "Please enter your choice: ";
		cin >> begins;
		cout << "\n" << endl;

		if (begins == 1)
		{
			cout << "\nThe man nods, as you both step outside to battle each other.\n" << endl;
			Sleep(2000);
			system("CLS");
			needsResponse = false; // <------------ got response we want
			//  battleGear(weapon, enemyHealth, Health, begins); <-- called from main
		}
		else if (begins == 2)
		{
			cout << "The whole bar laughs at you as you decline the duel and leave the bar.\n" << endl;
			Sleep(3000);
			system("CLS");
			// return main(); <--- just keep looping
		}
		else
		{
			cout << "This choice is invalid, you can't do that, lets start all over\n" << endl;
			Sleep(3000);
			system("CLS");
			// return main(); <-- just keep looping
		}
	}
	return 0;
}

Topic archived. No new replies allowed.