Randomisation Each Time The 2D Array Is Called

Basically I am making an adventure game in a 2D array, I would like the character to move around fighting monsters and have that represented in a 2D array. I have the movement done and I have just figured out how to detect if there is another character on the players coordinates. Right now my problem is because I've used rand() to determine where each of my monsters are every time my map updates the monsters also move, I understand why this is happening but the only way I can think of fixing it is to put the randomisation of the monsters coordinates into main or somewhere that only gets called once.

I was wondering if I could make an array that stored all of those coordinates within a couple lines of code. For example if I wanted 17 monsters if I could make an array with 17 parts then have each of them hold their own X and Y variable, then put that array into the for loop that spawns monsters something like:

1
2
3
4
5
6
for (int i = 0; i < AMMOUNT_OF_MONSTERS; i++)
{
	monsterX = myXArray[i];
	monsterY = myYArray[i];
	map[monsterX][monsterY] = 'M';
}




It would be a huge help of someone could show me how to fix this, I am quite new to C++ and I would like to learn as much as I can.


Thank you,

Michael Burdge.



Here is everything I have so far, i have made the size of the map so small and limited the amount of things spawning to test the detection without having to rely on randomisation.




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
#include "stdafx.h"
#include <ctime>
#include <iostream>

#define GRID_SIZE 3
#define AMMOUNT_OF_MONSTERS 1//17
#define AMMOUNT_OF_CHURCHES 1//10
#define AMMOUNT_OF_SURVIVORS 1//6
using namespace std;

int NewMap(int playerX, int playerY);
//int ContinueMap(int moveDistance, int direction);
void FightMonster();
void HealAtChurch();
void RecruitSurvivor();


int main()
{
	int playerX;
	int playerY;

	bool canContinue;

	playerX = GRID_SIZE / 2;
	playerY = GRID_SIZE / 2;

	int direction;
	char directionCHR;
	int moveDistance;
	time_t t;

	srand((unsigned)time(&t));

	cout << "The Aim Is To Kill" << endl;
	cout << "A = Adventurer: You are the Adventurer" << endl;
	cout << "M = Monsters: Fight Monsters" << endl;
	cout << "C = Churches: Heal After Fighting Monsters" << endl;
	cout << "S = Survivors: Recruit People To Help Fight Monsters" << endl;

	NewMap(playerX, playerY);

	for (int i = 0; i < 5; i++)
	{

		do
		{
			cout << "Which Direction Would You Like To Move?" << endl << "N for North, E for East, S for South, W for West" << endl;

			cin >> directionCHR;

			if (directionCHR == 'N' || directionCHR == 'n')
			{
				direction = 0;
			}
			else if (directionCHR == 'E' || directionCHR == 'e')
			{
				direction = 1;
			}
			else if (directionCHR == 'S' || directionCHR == 's')
			{
				direction = 2;
			}
			else if (directionCHR == 'W' || directionCHR == 'w')
			{
				direction = 3;
			}
		} while (directionCHR != 'N' && directionCHR != 'n' && directionCHR != 'E' && directionCHR != 'e' && directionCHR != 'S' && directionCHR != 's' && directionCHR != 'W' && directionCHR != 'w');

		do
		{
			canContinue = true;

			cout << "How Far Would You Like To Move?" << endl;

			cin >> moveDistance;

			if (direction == 0) // the reason why i did it like this is because originally i had the movement in the function along with the generation of the map.
			{
				playerX -= moveDistance;
				if (playerX < 0)
				{
					cout << "out of bounds" << endl;
					canContinue = false;
					playerX = 1;
				}
			}
			else if (direction == 1)
			{
				playerY += moveDistance;
				if (playerY > GRID_SIZE)
				{
					cout << "out of bounds" << endl;
					canContinue = false;
					playerY = GRID_SIZE - 1;
				}
			}
			else if (direction == 2)
			{
				playerX += moveDistance;
				if (playerX > GRID_SIZE)
				{
					cout << "out of bounds" << endl;
					canContinue = false;
					playerX = GRID_SIZE - 1;
				}
			}
			else if (direction == 3)
			{
				playerY -= moveDistance;
				if (playerY < 0)
				{
					cout << "out of bounds" << endl;
					canContinue = false;
					playerY = 1;
				}
			}
		} while (!canContinue);

		NewMap(playerX, playerY);

	}
	return 0;
}

int NewMap(int playerX, int playerY)
{

	char map[GRID_SIZE][GRID_SIZE];
	char grid = 176; //what ive chosen as the map ground, i chose this because it looks good as a background

	int x; //Map X
	int y; //Map Y


	int howManyMonsters; //How many Monsters on the map
	int monsterX; //Monsters X
	int monsterY; //Monsters Y


	int howManyChurches; //How many Churches on the map
	int churchX; //Church X
	int churchY; //Church Y

	int howManySurvivors; //How many Survivors on the map
	int survivorX; //Survivor X
	int survivorY; //Survivor Y




	for (x = 0; x < GRID_SIZE; x++)
	{
		for (y = 0; y < GRID_SIZE; y++)
		{
			map[x][y] = grid; //chooses what the map is
			map[playerX][playerY] = 'A';
		}
	}

	for (howManyMonsters = 0; howManyMonsters < AMMOUNT_OF_MONSTERS; howManyMonsters++) // to create the ammount of monsters i want
	{
		do // to randomize the coordinates of the monsters so they arent overwriting anything.
		{
			x = rand() % GRID_SIZE;
			y = rand() % GRID_SIZE;
			monsterX = rand() % GRID_SIZE; //will randomize each monsters X position
			monsterY = rand() % GRID_SIZE; //will randomize each monsters Y position
		} while (map[x][y] != grid && map[x][y] != map[playerX][playerY]); // this is so the monster wont replace the adventurer with monsters
		map[monsterX][monsterY] = 'M';// place monsters at map[monsterX][monsterY]
	}

	for (howManyChurches = 0; howManyChurches < AMMOUNT_OF_CHURCHES; howManyChurches++)
	{
		do
		{
			x = rand() % GRID_SIZE;
			y = rand() % GRID_SIZE;
			churchX = rand() % GRID_SIZE; //will randomize each church X position
			churchY = rand() % GRID_SIZE; //will randomize each church Y position
		} while (map[x][y] != grid && map[x][y] != 'M' && map[x][y] != map[playerX][playerY]); // so we dont replace the adventurer or monsters with churches
		map[churchX][churchY] = 'C';

	}

	for (howManySurvivors = 0; howManySurvivors < AMMOUNT_OF_SURVIVORS; howManySurvivors++)
	{
		do
		{
			x = rand() % GRID_SIZE;
			y = rand() % GRID_SIZE;
			survivorX = rand() % GRID_SIZE; //will randomize each survivor X position
			survivorY = rand() % GRID_SIZE; //will randomize each survivor Y position
		} while (map[x][y] != grid && map[x][y] != 'M' && map[x][y] != 'C' && map[x][y] != map[playerX][playerY]); //so we dont replace the adventurer, monsters or churches with survivors
		map[survivorX][survivorY] = 'S';

	}

	for (x = 0; x < GRID_SIZE; x++)//this here makes the spacing between each background character, i made a space between them because 
	{
		for (y = 0; y < GRID_SIZE; y++)
		{
			cout << map[x][y] << " ";
		}
		cout << endl;
	}

	for (x = 0; x < GRID_SIZE; x++)
	{
		for (y = 0; y < GRID_SIZE; y++)
		{
			if (map[playerX][playerY] == char('M'))
			{
				FightMonster(); //runs the function to fight a monster.
				map[playerX][playerY] = 'A'; // places the Adventurer aka the player in that position
			}
			else if (map[playerX][playerY] == char('C'))
			{
				HealAtChurch(); //runs the function to heal at the churche.
				map[playerX][playerY] = 'A'; // places the Adventurer aka the player in that position
			}
			else if (map[playerX][playerY] == char('S'))
			{
				RecruitSurvivor(); // runs the function to recruit a survivor;
				map[playerX][playerY] = 'A'; // places the Adventurer aka the player in that position
			}
			else
			{
				map[playerX][playerY] = 'A'; // places the Adventurer aka the player in that position
			}
		}
	}
return 0;
}




void FightMonster()
{
	cout << "FIGHT A MONSTER" << endl;
}

void HealAtChurch()
{
	cout << "HEAL AT A CHURCH" << endl;
}

void RecruitSurvivor()
{
	cout << "RECRUIT A SURVIVOR" << endl;
}


)
Last edited on
Look at this block.

161
162
163
164
165
166
167
168
169
170
171
	for (howManyMonsters = 0; howManyMonsters < AMMOUNT_OF_MONSTERS; howManyMonsters++) // to create the ammount of monsters i want
	{
		do // to randomize the coordinates of the monsters so they arent overwriting anything.
		{
			x = rand() % GRID_SIZE;
			y = rand() % GRID_SIZE;
			monsterX = rand() % GRID_SIZE; //will randomize each monsters X position
			monsterY = rand() % GRID_SIZE; //will randomize each monsters Y position
		} while (map[x][y] != grid && map[x][y] != map[playerX][playerY]); // this is so the monster wont replace the adventurer with monsters
		map[monsterX][monsterY] = 'M';// place monsters at map[monsterX][monsterY]
	}


As you stated, every time you redraw your map, you re-locate your monsters. Instead, create your monsters at the beginning like this:

1
2
3
4
5
6
7
8
struct Location { int x; int y;};

Location monster[AMOUNT_OF_MONSTERS];
for (int i = 0; i < AMOUNT_OF_MONSTERS; ++i)
{
	monster[i].x = rand() % GRID_SIZE; //will randomize each monsters X position
	monster[i].y = rand() % GRID_SIZE; //will randomize each monsters Y position
}


Then change your do-loop to
if (map[monster[i].x][monster[i].y] != grid && map[monster[i].x][monster[i].y] != map[playerX][playerY])

This probably isn't quite right, but it should get you thinking in the right direction. I would recommend only working with on addition at a time. Comment out your churches and survivors until you get monsters working, and then add things back in steps.
Last edited on
yes, moving random setup to either main or better still, a function that is called only once from main, would be ideal.

You can do better:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct mobxy  //user defined type for xy coordinates
{
   int x;
   int y;
}
...

mobxy monsterlist[17];  //an array of 17 monsters or really, just 17 x/y pairs. 
for (int i = 0; i < AMMOUNT_OF_MONSTERS; i++)
{
   monsterlist[i].x = somex;
   monsterlist[i].y = somey;
   map[somex][somey] = 'M'
}


what you are looking for here is probably object oriented programming where you can bundle your data (like the x/y pairs and all) together into one single user defined type along with some functions that do the work. The struct above is the beginnings of this, but you will need to study a bit to use these ideas.

what you probably would like is...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class monster
{
    public: //for now this lets anyone and everything touch the class data members. 
    mobxy current_position;
    int current_health;
    string type;
    monster()  //what to do when the object is created, called a constructor 
      { //with this simply creating a monster gives it a random starting location!
          current_position.x = rand()%maxX;
          current_position.y = rand()%maxY;  
          current_health = 100; //whatever   
          type = "Orc";
      }    
    bool isdead();
};

bool monster::isdead()  //this function is part of the class.  it had a header in the class above.
{
     return (health <= 0);  //if it has 0 or less health, it died.   
}


These are just some off the cuff really basic examples of what you might like to do.
then you can allocate an array (or better, a vector..!) of 17 monsters and they all immediately have a starting location and health and all. You can just start fighting them!

Last edited on
Thank you both for replying, I have looked over what you both have said and tried implementing it yet it hasn't worked, I am still getting the same result. Every time I load the map it will change where the monster spawns.


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
struct Character
{

	int X;
	int Y;

	int health;
	string name;

	Character()
	{
		health = 99999;
		name = "ChangeMe";
	}
}; 



class Monster
{
	public:
	Character _Character[AMMOUNT_OF_MONSTERS];
	string type;

	Monster()
	{
		for (int howManyMonsters = 0; howManyMonsters < AMMOUNT_OF_MONSTERS; howManyMonsters++)
		{
			_Character[howManyMonsters].X = rand() % GRID_SIZE;//will randomize each monsters X position
			_Character[howManyMonsters].Y = rand() % GRID_SIZE;//will randomize each monsters Y position
		}
	}
};


for (howManyMonsters = 0; howManyMonsters < AMMOUNT_OF_MONSTERS; howManyMonsters++) // to create the ammount of monsters i want
	{
		if (map[x][y] != grid && map[x][y] != map[playerX][playerY])
		{
			map[_Monster._Character[howManyMonsters].X][_Monster._Character[howManyMonsters].Y] = 'M';
		}	
	}
Topic archived. No new replies allowed.