Man vs Zombies and Holes

Hi,

I'm in the middle of writing a basic assignment to move a man (M) around a given island.

I have defined the island or a set size but cannot get him to move in any direction.

What seems to happen is that multiple "M"'s are appearing on the island as as such this should not be the case as I am lifting and replacing the "M" to a new grid reference dependant on where the "M" is on the island.

I have also created a set of randomly placed holes along with randomly placed zombies. I am still working on the logic for killing off zombies should they land in a hole but thought it best to get the logic of moving my man character around the screen more successfully.

I have used a switch and case check to try to get the man to move in a certain direction but am now thinking I need to change tac and work out a different way of applying a search in the island for the "M".

I would welcome your thoughts on this as I cannot seem to get the M to move correctly.

Here is my code:

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
// ConsoleApplication5.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "console.h"			
#include <iostream>
#include <windows.h>
#include <ctime>
#include <stdlib.h>
#include <time.h>
#include <iomanip>

using namespace std;

const int R = 12;
const int C = 22;
int randNum = 0;
int inputmove = 0;
int endgame = 0;

using namespace std;

void Console::clear()
{
	// Description: Clears the screen
	COORD coordScreen = { 0, 0 };
	DWORD cCharsWritten;
	CONSOLE_SCREEN_BUFFER_INFO csbi;
	DWORD dwConSize;

	GetConsoleScreenBufferInfo(hConsole, &csbi);
	dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
	FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);
	GetConsoleScreenBufferInfo(hConsole, &csbi);
	FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
	SetConsoleCursorPosition(hConsole, coordScreen);

};

void Console::setColour(COLOUR foreground, COLOUR background)
{
	int colour = background * 16 + foreground;
	SetConsoleTextAttribute(hConsole, colour);
};

HANDLE Console::hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

void Island(char island[R][C]) // Make Island
{
	for (int row = 0; row < 12; row++)
	{
		for (int column = 0; column < 22; column++)
		{
			island[row][column] = ' ';
		}
	}
}

void outline(char island[R][C]) {
	// Boundary definition around the island
	// The starting point is 0 through to 21 characters across on the x axis by 12 characters high
	for (int c = 0; c < 12; c++) {
		island[c][0] = '#';
	}
	for (int c = 0; c < 12; c++) {
		island[c][21] = '#';
	}
	for (int c = 1; c < 21; c++) {
		island[0][c] = '#';
	}
	for (int c = 1; c < 21; c++) {
		island[11][c] = '#';
	}
}

void display(char island[R][C]) {
	// Display a basic internal to th island 
	// These are spaces but could be any character if desired - just looks less noisy if it is space.
	Console::setColour(Console::BLUE, Console::GREEN); 
	for (int row = 0; row < 12; row++)
	{
		for (int column = 0; column < 22; column++)
		{
			cout << island[row][column] << " ";
		}
		cout << endl;
	}
	cout << endl;
	Console::setColour(Console::WHITE, Console::BLACK);
	
}

void zombies(char island[R][C]) {
	// Place Zombies randomly
	// This has 5 Zombies defined initially
	int numberzombies = 5;
	srand(time(0));
	for (int c = 0; c < numberzombies; c++)
	{
		island[rand() % 8 + 2][rand() % 18 + 2] = 'Z';
	}
}

void holes(char island[R][C]) {
	// This function places 4 Holes randomly
	// This can be edited to allow for a level game to be played so that the 4 can be a determined
	// by a range value which can be altered over time to increase the number of holes
	int numberholes = 8;
	srand(time(0));
	for (int c = 0; c < numberholes; c++)
	{
		//detemine(yard);
		island[rand() % 10 + 1][rand() % 20 + 1] = 'H';
	}
}

void makeman(char island[R][C]) {
	// This function puts you on the island
	// It is the last one to be done and as such this ensures that your character is not over written.
	int man = 1;
	srand(time(0));
	for (int c = 0; c < man; c++)
	{
		//detemine(yard);
		island[rand() % 10 + 1][rand() % 20 + 1] = 'M';
	}
}

void endofgame(){
	cout << "Sorry chum you died!!" << endl;
}

void detemine(char island[R][C]) // Determine if Zombie or Hole is found
{
	if (island[R][C] == 'Z')
	{
		endofgame();
			//yard[R][C] = '+';
		
	}
	else
	{
		island[R][C] = 'H';
	}
}

void Input(char island[R][C]){
	int moveman;
	cout << "In this game you die easy -  hit a Zombie or land in a Hole its GAMEOVER!!!!" << endl << endl;
	cout << "It's your turn to move buddy: 2=Down, 4=Left, 6=Right, 8=Up or 0=End: ";
	cin >> moveman;
	for (int y = 0; y < R; y++){
		for (int x = 0; x < C; x++){
			switch (island[x][y]){
			case 'M':
				switch (moveman){
				case 8: if ((island[y - 1][x] == ' ') && (island[y - 1][x] != 'Z' || island[y - 1][x] != 'H')) {
							island[y][x] = ' ';
							island[y - 1][x] = 'M'; 
						}
						else if (island[y - 1][x] == 'Z' || island[y - 1][x] == 'H') {
							endofgame();
						}
						break;
				case 6: if ((island[y][x + 1] == ' ') && (island[y][x + 1] != 'Z' || island[y][x + 1] != 'H')) {
							island[y][x] = ' ';
							island[y][x + 1] = 'M';
						}
						else if (island[y][x + 1] == 'Z' || island[y][x + 1] == 'H') {
							endofgame();
						}
						break;
				case 4: if ((island[y + 1][x] == ' ') && (island[y + 1][x] != 'Z' || island[y + 1][x] != 'H')) {
							island[y][x] = ' ';
							island[y + 1][x] = 'M';
						}
						else if (island[y + 1][x] == 'Z' || island[y + 1][x] == 'H') {
							endofgame();
						}
						break;
				case 2: if ((island[y][x - 1] == ' ') && (island[y][x - 1] != 'Z' || island[y][x - 1] != 'H')) {
							island[y][x] = ' ';
							island[y][x - 1] = 'M';
						}
						else if (island[y][x - 1] == 'Z' || island[y][x - 1] == 'H') {
							endofgame();
						}
						break;
				}
			}
		}
	}
}

void Movezombies(char island[R][C]){
	//Now move all of the available Zombies in a Random pattern based on a Case statement
	for (int y = 0; y < R; y++){
		cout << island[y] << endl;
	}
	for (int y = 0; y < R; y++){
		for (int x = 0; x < C; x++){
			switch (island[y][x]){
			case 'Z':
				randNum = rand() % 4 + 1;
				switch (randNum){
				case 1: if (island[y - 1][x] != '#' && island[y - 1][x] != 'Z') {
					island[y][x] = ' ';
					island[y - 1][x] = 'Z';
				}
						break;
				case 2: if (island[y][x + 1] != '#' && island[y][x + 1] != 'Z') {
					island[y][x] = ' ';
					island[y][x + 1] = 'Z';
				}
						break;
				case 3: if (island[y + 1][x] != '#' && island[y + 1][x] != 'Z') {
					island[y][x] = ' ';
					island[y + 1][x] = 'Z';
				}
						break;
				case 4: if (island[y][x - 1] != '#' && island[y][x - 1] != 'Z') {
					island[y][x] = ' ';
					island[y][x - 1] = 'Z';
				}
						break;
				}
			}
		}
		randNum = 0;

	}
}

int main(){
	
	char island[R][C];
	int n = 0;
	//Initialise the co-ordinate array
	Island(island);
	//Draw the outline of the island
	outline(island);
	// Make the holes to be used on the island
	holes(island);
	//Make the zombies to be used on the island
	zombies(island);
	//Make the man on the island
	makeman(island);
	//Make sure the screen is cleared
	Console::clear();
	
	while (endgame = 1){
		Console::setColour(Console::WHITE, Console::BLACK);
		cout << "\tMan vs Zombies and Holes Assignment" << endl << endl;
		//detemine(island);
		display(island);
		//system("pause");
		Input(island);
		//MoveMan(island);
		Movezombies(island);
		Console::clear();
	}
		system("pause");
}


I am using Visual Studio 2013 Express to run this in.

Cheers
Steve
Be careful. Set your compiler to maximum complaints. Line 251 should be while (endgame != 1).

I would also add endgame = 1; between lines 130 and 131.

The main problem you have is in your Input() function. You are searching the entire array just to find your man, then adjust him. Don't do that.

Keep track in some extra variables exactly where the man is. Then your function can look much simpler:

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
void Input(char island[R][C])
{
	int prevx = manx;
	int prevy = many;
	int moveman;
	cout << "In this game you die easy -  hit a Zombie or land in a Hole its GAMEOVER!!!!" << endl << endl;
	cout << "It's your turn to move buddy: 2=Down, 4=Left, 6=Right, 8=Up or 0=End: ";
	cin >> moveman;

	// Remove the man from where he was
	island[many][manx] = GRASS;

        switch (moveman)
        {
                case 0: endgame = 1; break;  // Don't forget this!
		case 8: if (many > 1) many -= 1; break;  // Move the man up one row
		case 4: if (manx > 1) manx -= 1; break;  // Move the man left one column
		case 6: if (manx < C-2) manx += 1; break; 
		...  // (Notice how we don't care about anything except not falling off the edge of 
		     //  the board. Everything else we'll deal with in a minute.)
	}

	switch (island[many][manx])
	{
		// Check to see if the man is dead.
		case ZOMBIE:
		case HOLE:
			return endofgame();

		// Stop the man from walking through barriers
		case WATER:
		case TREE:
			manx = prevx;
			many = prevy;

		// Any other options? Powerups? Etc?
		// ...
	}

	// Place the man where he now is
	island[many][manx] = MAN;
}

Notice also how I used things like WATER and ZOMBIE. You can declare them at the top of your program to make life so much easier.

1
2
3
4
const char MAN    = '\1';    // Draws as a smiley face
const char ZOMBIE = '\2';    // Draws as a hollow smiley face
const char HOLE   = '\xFE';  // Draws as a square hole
...

You can also set special colors depending on what you are drawing. Add this as a simple switch to select the color based on the item to draw after line 83 and before line 84.

For example, you could make the man yellow (like Bart), or brown, or grey (albino white dude?). The zombies could be pink or grey or maroon or whatever you desire.

For water, I would personally use '~' with CYAN on LBLUE.

Well, hope this helps.
Thank you.

I'll try to rework this with your ideas.

I do like the idea of different shapes :).
Topic archived. No new replies allowed.