Crash in AI program

Hi!
I am currently programming a program which simulates a AI by the means of 4 "chars" in a char array. They all want to get the reward dots which are spawned randomly with a chance of 1 on 20. The ai scripting is not yet finished, nor am i letting all the ai "chars" do their thing at this moment. This is because ive found some "Randomly" appearing crash in the code. Iam saying "Randomly" because there does seem to be a patern in the crash, its after a dot has spawned and theres always a creature near the wall (buffer overflow in char array?). I've let my friend (hes a bigger n00b then me ;)) compile and run it and hes also getting another error in the program. Does anyone know whats going on?

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
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
//////////////////////////////
// Creatur[0] = Blinky 
// Creatur[1] = Pinky  
// Creatur[2] = Inky  
// Creatur[3] = Clyde  
// AI test by tHaH4x0r 
//////////////////////////////

//----------------------- Declerations -------------------------------
#include "windows.h"
#include<dos.h>
#include<process.h>
#include<string>   
#include<fstream>   
#include<stdio.h>
#include<iostream>
#include<conio.h>
#include<ctime>

using namespace std;

//----------------------- Classes --------------


class Creatures{
public:
	Creatures(){
	Points = 0;
	}

	int RequestP(){
	return Points;
	}

	void IncrP(){
	Points++;
	};

private:
	int Points;
};

////////////////////

class AEngine{
private:
Creatures Creatur[4];
char Field[20][21];
bool DotPres;
int DotLoc[2];
int GSQ[2];

public:
AEngine(){

// Seed Random number generator
	time_t qTime;
	time(&qTime);
	srand((unsigned int)qTime);
	
// Init the field
	DotPres = false;
	char EmptField[20][21] = {
"********************",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"********************"};
	for(int Row=0;Row<20;Row++){
		for(int Col=0;Col<20;Col++){
		Field[Row][Col]=EmptField[Row][Col];
		}
	}

// Spawn creatures
char GridSpot;
bool FoundSpot =  false;
int NumCreat = 1;
	while(!FoundSpot){
			int uiRow = 1 + (rand() % 20);
			int uiCol = 1 + (rand() % 20);
			GridSpot = GetGridSQ(uiRow, uiCol);

				if(GridSpot==' '){
				Field[uiRow][uiCol]=NumCreat;
				NumCreat++;
				}
				if(NumCreat==2){
				FoundSpot = true;
				}
	}

}

// Request a grid square
char GetGridSQ(int Row, int Col){
	return(Field[Row][Col]);
}

// Check for Dot precense (true==present)
bool GetDot(){
return(DotPres);
}

// Spawn a random reward dot on a random grid square
void SpawnRwrdDot(){
	bool ValdSQ = false;
	int uiRow;
	int uiCol;
// 1 on 20 chance of spawn, IF THERES A DOT PRESENT!
	if(!DotPres){
		if((rand() % 20)==1){
			while(!ValdSQ){
			uiRow = 1 + (rand() % 20);
			uiCol = 1 + (rand() % 20);
			char GridSpot = GetGridSQ(uiRow, uiCol);
				if(GridSpot==' '){ValdSQ=true;}
			}
			DotPres=true;
			Field[uiRow][uiCol]='.';
			DotLoc[0]=uiRow;
			DotLoc[1]=uiCol;
		}
	}
}

// Requests the position of the creature and returns it in the array GSQ[2] //([0]=Row [1]=Col)
void GetCreatSQ(int Num_Creat){

	for(int Row=0; Row<20; Row++){
		for(int Col=0; Col<20; Col++){
			if(GetGridSQ(Row,Col)==Num_Creat){
			GSQ[0]=Row;
			GSQ[1]=Col;
			}
		}
	}

}

// Move creature with the direction
void MoveCreat_dir(char Num_Creat, int Direc){
int RowF, ColF;
bool ValidMV = false;

	for(int Row=0; Row<20; Row++){
		for(int Col=0; Col<20; Col++){
			if(GetGridSQ(Row,Col)==Num_Creat){
			bool FoundC = true;
			RowF=Row;
			ColF=Col;
			}
		}
	}
		while(!ValidMV){
			switch(Direc){
			case 0:
				if(GetGridSQ(RowF+1, ColF)==' '){
				Field[RowF][ColF]=' ';
				Field[RowF+1][ColF]=Num_Creat;
				ValidMV = true;
				}
				else if(GetGridSQ(RowF+1, ColF)=='.'){
				Field[RowF][ColF]=' ';
				Field[RowF+1][ColF]=Num_Creat;
				DotPres = false;
				Creatur[Num_Creat].IncrP();
				ValidMV = true;
				}
				break;
			case 1:
				if(GetGridSQ(RowF-1, ColF)==' '){
				Field[RowF][ColF]=' ';
				Field[RowF-1][ColF]=Num_Creat;
				ValidMV = true;
				}
				else if(GetGridSQ(RowF+1, ColF)=='.'){
				Field[RowF][ColF]=' ';
				Field[RowF-1][ColF]=Num_Creat;
				DotPres = false;
				Creatur[Num_Creat].IncrP();
				ValidMV = true;
				}
				break;
			case 2:
				if(GetGridSQ(RowF, ColF+1)==' '){
				Field[RowF][ColF]=' ';
				Field[RowF][ColF-1]=Num_Creat;
				ValidMV = true;
				}
				else if(GetGridSQ(RowF+1, ColF)=='.'){
				Field[RowF][ColF]=' ';
				Field[RowF][ColF-1]=Num_Creat;
				DotPres = false;
				Creatur[Num_Creat].IncrP();
				ValidMV = true;
				}
				break;
			case 3:
				if(GetGridSQ(RowF, ColF-1)==' '){
				Field[RowF][ColF]=' ';
				Field[RowF][ColF+1]=Num_Creat;
				ValidMV = true;
				}
				else if(GetGridSQ(RowF+1, ColF)=='.'){
				Field[RowF][ColF]=' ';
				Field[RowF][ColF+1]=Num_Creat;
				DotPres = false;
				Creatur[Num_Creat].IncrP();
				ValidMV = true;
				}
				break;
			default:
			cout << "illegal move!: foutcode 0x04" << endl;
			system("pause");
			}
		}
}

// Move creature randomly
void MoveCreat_rand(char Num_Creat){
	bool FoundC = true;
	bool ValdMv = false;
	int RowF, ColF;
	int NextM;

	for(int Row=0; Row<20; Row++){
		for(int Col=0; Col<20; Col++){
			if(GetGridSQ(Row,Col)==Num_Creat){
			bool FoundC = true;
			RowF=Row;
			ColF=Col;
			}
		}
	}

	if(FoundC==true){
		while(!ValdMv){
		NextM = (rand() % 4);
			switch(NextM){
			case 0:
				if(GetGridSQ(RowF+1, ColF)==' '){
				ValdMv = true;
				Field[RowF][ColF]=' ';
				Field[RowF+1][ColF]=Num_Creat;
				}
				break;
			case 1:
				if(GetGridSQ(RowF-1, ColF)==' '){
				ValdMv = true;
				Field[RowF][ColF]=' ';
				Field[RowF-1][ColF]=Num_Creat;
				}
				break;
			case 2:
				if(GetGridSQ(RowF, ColF+1)==' '){
				ValdMv = true;
				Field[RowF][ColF]=' ';
				Field[RowF][ColF+1]=Num_Creat;
				}
				break;
			case 3:
				if(GetGridSQ(RowF, ColF-1)==' '){
				ValdMv = true;
				Field[RowF][ColF]=' ';
				Field[RowF][ColF-1]=Num_Creat;
				}
				break;
			default:
			cout << "something went horribly wrong, its an illegal move!: foutcode 0x01" << endl;
			system("pause");
			}
		}
	}
	else{
	cout << "creature isnt present: foutcode 0x02" << endl;
	system("pause");
	}
}

void DispField(){
	for(int Row=0; Row<20; Row++){
		for(int Col=0; Col<20; Col++){
		cout << Field[Row][Col];
		}
	cout << endl;
	}
	cout << "\n\n" << endl;
	char Bi = 0;
	char Pi = 1;
	char Iy = 2;
	char Cy = 3;

	cout << "Blinky - 0 : " << Creatur[0].RequestP() << endl;
	cout << "Pinky  - 1 : " << Creatur[1].RequestP() << endl;
	cout << "Inky   - 2 : " << Creatur[2].RequestP() << endl;
	cout << "Clyde  - 3 : " << Creatur[3].RequestP() << endl;
}

// Where it all happens, the ai moves if a dot is present :)
void MoveAI(int CreatNum){
	switch(CreatNum){
	case 0:
		// Blinky
		GetCreatSQ(0);
		if (DotLoc[0]<GSQ[0]){
		MoveCreat_dir(0, 0);
		}
		else if (DotLoc[0]>GSQ[0]){
		MoveCreat_dir(0, 1);
		}
		else if (DotLoc[1]<GSQ[1]){
		MoveCreat_dir(0, 3);
		}
		else if (DotLoc[1]>GSQ[1]){
		MoveCreat_dir(0, 2);
		}
		break;
	case 1:
		// Pinky
		GetCreatSQ(0);
		if (DotLoc[0]<GSQ[0]){
		MoveCreat_dir(1, 0);
		}
		else if (DotLoc[0]>GSQ[0]){
		MoveCreat_dir(1, 1);
		}
		else if (DotLoc[1]<GSQ[1]){
		MoveCreat_dir(1, 2);
		}
		else if (DotLoc[1]>GSQ[1]){
		MoveCreat_dir(1, 3);
		}
		break;
	case 2:
		// Inky
		MoveCreat_rand(2);
		break;
	default:
	cout << "WTF dit kan niet, is geen karakter: foutcode 0x03" << endl;
	system("pause");
	}

}

};



//---------------------- Main -------------
int main(){
AEngine Engine;
while(1){
	if(Engine.GetDot()){
	Engine.MoveAI(1);
	}
	else{
	Engine.MoveCreat_rand(1);
	}
Engine.DispField();
Engine.SpawnRwrdDot();
Sleep(300);
system("cls");
}
}


PS: Sorry for my bad grammer and spelling, im dutch ;)


* EDIT
Ive editted the program so only 1 ai is present and does stuff, when a dot spawns it continuously goes up till the wall and then crashes :/
Last edited on
I haven't tested anything so I can't be sure.
However I think your problem is here:

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
// Init the field
	DotPres = false;
	char EmptField[20][21] = {
"********************",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"*                  *",
"********************"};
	for(int Row=0;Row<20;Row++){
		for(int Col=0;Col<20;Col++){
		Field[Row][Col]=EmptField[Row][Col];
		}
	}


You're creating a [20] [21] but only seem to use [20][20] of it. I find this odd. It shouldn't cause any errors tho.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Spawn creatures
char GridSpot;
bool FoundSpot =  false;
int NumCreat = 1;
	while(!FoundSpot){
			int uiRow = 1 + (rand() % 20);
			int uiCol = 1 + (rand() % 20);
			GridSpot = GetGridSQ(uiRow, uiCol);

				if(GridSpot==' '){
				Field[uiRow][uiCol]=NumCreat;
				NumCreat++;
				}
				if(NumCreat==2){
				FoundSpot = true;
				}
	}

}

This however is a problem. Or more specificly:

1
2
			int uiRow = 1 + (rand() % 20);
			int uiCol = 1 + (rand() % 20);

The rand() % 20 creates a number between 0-19 (including 0 and 19). Then you add 1.
Hoever the array is only [20] [20] large (i'm excluding the 21 becouse it seems it is supposed to be unused). So the scope (is that the right word?) of the valid calls are between 0-19 (including 0 and 19).

This means the program tries to access and write outside the scope of the array. This can cause an instant crash or memmory corruption.

OK this was a very long way of saying: try removing the 1 +
btw. The same thing happens a few lines lower.

EDIT:
Now that I think about it. The fact that the array is larger than it should be means that the dots can be placed outside the wall. Making it unreachable for the creatures. Creating a host of new potential problems.
Last edited on
Thanks for the reply ;)
That the array is larger then it should be, shouldnt pose a problem because the numbers generated for the randomness (is that a word?) are not in the range of 21 but ill change it anyways because 21 is, like you said, useless.
I saw the line:
int x = 1 + (rand() % 20);
in an other code, it now generates a random value between 0-19 then adds 1 so the range is between 1-20 (i dont need 0 because its a wall).
I suppose i could change this to:
int x = 1 + (rand() % 19);
for it to be within 1-19 (i dont need 20 either because its a wall to).
Although i dont think this is the source of the bug either because the code checks if a wall is present and only places a dot when the char has the value " " (white space).
Ill first try removing the +1 when i have the time (school etc) which is probaly later this evening.
Topic archived. No new replies allowed.