This repository has been archived by the owner on May 10, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Maze.cpp
237 lines (183 loc) · 5.15 KB
/
Maze.cpp
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
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include<conio.h> /*to Windows getche()*/
using namespace std;
//key codes
const int KEY_D = 100;
const int KEY_S = 115;
const int KEY_A = 97;
const int KEY_W = 119;
//fields
const int initial = 0;
const int wall = 2147483647;
const int player = 2147483646;
//chars
const char playerChar = '@';
const char emptyChar = ' ';
const char wallChar = '#';
//moves
const int toRight = 0;
const int toDown = 1;
const int toLeft = 2;
const int toUp = 3;
//config
const int mazeSize = 20;
bool randomSeedInitialized = false;
int generateRandom(int max)
{
if (!randomSeedInitialized) {
srand(time(NULL));
randomSeedInitialized = true;
}
//0-based
return rand() % max;
}
void printMaze(int maze[mazeSize][mazeSize])
{
for (int row = 0; row < mazeSize; row++) {
for (int column = 0; column < mazeSize; column++) {
int field = maze[row][column];
cout << (field == wall ? wallChar : field == player ? playerChar : emptyChar);
}
cout << endl;
}
}
bool isPossibleMoveTo(int maze[mazeSize][mazeSize], int moveTo, int currentRow, int currentColumn)
{
bool isPossibleMoveTo = false;
//TODO add the check to see if the adjacents positions are walls
switch (moveTo) {
case toRight:
isPossibleMoveTo = currentColumn < mazeSize - 1 && maze[currentRow][currentColumn + 1] != wall;
break;
case toDown:
isPossibleMoveTo = currentRow < mazeSize - 1 && maze[currentRow + 1][currentColumn] != wall;
break;
case toLeft:
isPossibleMoveTo = currentColumn > 0 && maze[currentRow][currentColumn - 1] != wall;
break;
case toUp:
isPossibleMoveTo = currentRow > 0 && maze[currentRow - 1][currentColumn] != wall;
break;
}
return isPossibleMoveTo;
}
int randomNextMove(int maze[mazeSize][mazeSize], int lastMove, int currentRow, int currentColumn)
{
//right or down ++ // left or up --
int moveTo = -1;
bool canMove = true;
do {
//4 possible movements
moveTo = generateRandom(2); //I see a bug here when moving up //TODO fix this bug
// after a move, you CAN'T move to his oposite direction (example, go to down, after up)
bool isOpositeMove = (moveTo == lastMove + (lastMove > 1 ? -2 : 2));
canMove = !isOpositeMove && isPossibleMoveTo(maze, moveTo, currentRow, currentColumn);
} while (!canMove);
return moveTo;
}
//TODO rename this method name (I'm not realy taking of a place and putting in another)
bool moveOnMaze(int maze[mazeSize][mazeSize], int moveTo, int field, int& currentRow, int& currentColumn, bool clearCurrent)
{
if (!isPossibleMoveTo(maze, moveTo, currentRow, currentColumn)) {
return false;
}
bool moved = moveTo == toRight || moveTo == toDown || moveTo == toLeft || moveTo == toUp;
if (moved) {
if (clearCurrent) {
maze[currentRow][currentColumn] = initial;
}
switch (moveTo) {
case toRight:
currentColumn++;
break;
case toDown:
currentRow++;
break;
case toLeft:
currentColumn--;
break;
case toUp:
currentRow--;
break;
}
maze[currentRow][currentColumn] = field;
}
return moved;
}
void generateMaze(int maze[mazeSize][mazeSize])
{
//TODO to generate a maze I need see if I'll have escape after
//(possible solution: see if the next 3 movements before make a move are free)
int lastMove = -1; // 0 - right // 1 - down // 2 - left // 3 - up
int markAsGenerated = player;// 99999999;
int currentRow = 0;
int currentColumn = 0;
//initial
maze[currentRow][currentColumn] = markAsGenerated;
while (!(currentRow == mazeSize - 1 && currentColumn == mazeSize - 1)) {
//TODO check this, i think that is not correct, but I'm without time to see this now
int moveTo = randomNextMove(maze, lastMove, currentRow, currentColumn);
moveOnMaze(maze, moveTo, markAsGenerated, currentRow, currentColumn,false);
lastMove = moveTo;
}
//populating maze
for (int row = 0; row < mazeSize; row++) {
for (int column = 0; column < mazeSize; column++) {
int field = initial;
if (maze[row][column] != markAsGenerated) {
field = generateRandom(3) > 0 ? wall : initial;
}
maze[row][column] = field;
}
}
}
bool isGameEnd(int maze[mazeSize][mazeSize]) {
return maze[mazeSize-1][mazeSize - 1] == player;
}
void startGame(int maze[mazeSize][mazeSize]) {
int currentRow = 0;
int currentColumn = 0;
maze[currentRow][currentColumn] = player;
printMaze(maze);
// char keyPressed;
int keyPressed;
int moveTo=-1;
int lastMove = -1;
while (!isGameEnd(maze)) {
//TODO this getche wasn't work as expected, see this
//use wdsa for now
//cout << endl << "-------------" << "Direction (w a s d): ";
//cin >> keyPressed;
keyPressed = _getche();
switch (keyPressed) {
case KEY_W://'w':
moveTo = toUp;
break;
case KEY_D://'d':
moveTo = toRight;
break;
case KEY_S://'s':
moveTo = toDown;
break;
case KEY_A://'a':
moveTo = toLeft;
break;
}
//cout << endl << moveTo << endl;
bool moved = moveOnMaze(maze, moveTo, player, currentRow, currentColumn, true);
lastMove = moveTo;
system("cls");
printMaze(maze);
}
cout << endl << " ----- E N D ----- " << endl;
}
int main()
{
int maze[mazeSize][mazeSize];
generateMaze(maze);
startGame(maze);
system("pause");
return 0;
}