-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
191 lines (175 loc) · 5.8 KB
/
main.c
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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include "struct.h"
#include "maze_stack.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
void display_maze(const maze_t maze);
void initialize_maze(maze_t* maze);
int get_potential_directions(freeBox_t* freeBox, const maze_t maze, const int line, const int column);
void update_position(int* currentPosition, const boxWall_e direction);
boxWall_e get_direction(const int nbrOfPotential, const bool* arrayOfPotential);
int main() {
srand(time(NULL));
freeBox_t potentialDirections;
int emptyBoxes = LINE * COLUMN - 1;
int randomDirection;
boxWall_e direction;
maze_t maze;
int currentPosition[2] = {0, 0};
initialize_maze(&maze);
boxInStack_t* maze_stack = NULL;
maze_stack = stack_push(&(maze.box[0][0]), NULL, currentPosition);
maze_stack->box->hasBeenVisited = true;
while (emptyBoxes){
if (get_potential_directions(&potentialDirections,
maze,
currentPosition[0],
currentPosition[1])) {
direction = get_direction(potentialDirections.nbrOfEmptyBoxes, potentialDirections.isBoxEmpty);
maze_stack->box->isWallSolid[direction] = false;
update_position(currentPosition, direction);
maze_stack = stack_push(&(maze.box[currentPosition[0]][currentPosition[1]]), maze_stack, currentPosition);
maze_stack->box->hasBeenVisited = true;
maze_stack->box->isWallSolid[(direction + 2) % 4] = false;
emptyBoxes--;
} else {
while (!get_potential_directions(&potentialDirections,
maze,
currentPosition[0],
currentPosition[1])) {
maze_stack = stack_pop(maze_stack);
for (int i = 0; i < 2; ++i) {
currentPosition[i] = maze_stack->position[i];
}
}
}
}
display_maze(maze);
printf("%d\n", emptyBoxes);
while (getchar() != '\n');
return 0;
}
void update_position(int* currentPosition, const boxWall_e direction)
{
if (direction % 2) {
/* The direction is either LEFT or RIGHT */
currentPosition[1] -= direction - 2;
} else {
/* The direction is either TOP or BOTTOM */
currentPosition[0] += direction - 1;
}
}
boxWall_e get_direction(const int nbrOfPotential, const bool* arrayOfPotential)
{
int randomDirection = rand() % nbrOfPotential;
boxWall_e direction;
for (int i = 0; i < 4; ++i) {
if (arrayOfPotential[i]) {
if (!randomDirection) {
return i;
} else {
randomDirection--;
}
}
}
return 0;
}
int get_potential_directions(freeBox_t* freeBox, const maze_t maze, const int line, const int column)
{
int arrayInd = 0;
freeBox->nbrOfEmptyBoxes = 0;
for (int i = -1; i < 2; i += 2) {
if (line + i < 0 || line + i >= LINE) {
/* The box is out of the maze */
freeBox->isBoxEmpty[arrayInd] = false;
} else if (maze.box[line+i][column].hasBeenVisited) {
freeBox->isBoxEmpty[arrayInd] = false;
} else {
freeBox->isBoxEmpty[arrayInd] = true;
freeBox->nbrOfEmptyBoxes++;
}
arrayInd++;
if (column - i < 0 || column - i >= COLUMN) {
/* The box is out of the maze */
freeBox->isBoxEmpty[arrayInd] = false;
} else if (maze.box[line][column-i].hasBeenVisited) {
freeBox->isBoxEmpty[arrayInd] = false;
} else {
freeBox->isBoxEmpty[arrayInd] = true;
freeBox->nbrOfEmptyBoxes++;
}
arrayInd++;
}
for (int i = 0; i < 4; ++i) {
if (freeBox->isBoxEmpty[i]) {
return 1;
}
}
return 0;
}
void initialize_maze(maze_t* maze)
{
/*Begin by declaring all the maze boxes as empty from all sides*/
for (int i = 0; i < LINE; ++i) {
for (int j = 0; j < COLUMN; ++j) {
for (int k = 0; k < 4; ++k) {
maze->box[i][j].isWallSolid[k] = true;
maze->box[i][j].hasBeenVisited = false;
}
}
}
maze->box[0][0].isWallSolid[TOP] = false;
/* make the top of the maze solid
for (int i = 1; i < COLUMN; ++i) {
maze->box[0][i].isWallSolid[TOP] = true;
}
Left and right side
for (int i = 0; i < LINE; ++i) {
maze->box[i][0].isWallSolid[LEFT] = true;
maze->box[i][COLUMN-1].isWallSolid[RIGHT] = true;
}
Bottom side
for (int i = 0; i < COLUMN; ++i) {
maze->box[LINE-1][i].isWallSolid[BOTTOM] = true;
} */
puts("Maze initialized");
}
void display_maze(const maze_t maze)
{
printf("\n");
for (int i = 0; i < LINE; ++i) {
for (int j = 0; j < COLUMN; ++j) {
if (maze.box[i][j].isWallSolid[TOP]) {
printf("+----+");
} else {
printf("+ +");
}
}
printf("\n");
for (int j = 0; j < COLUMN; ++j) {
if (maze.box[i][j].isWallSolid[LEFT]) {
printf("| ");
} else {
printf(" ");
}
if (maze.box[i][j].isWallSolid[RIGHT]) {
printf("|");
} else {
printf(" ");
}
}
printf("\n");
for (int j = 0; j < COLUMN; ++j) {
if (maze.box[i][j].isWallSolid[BOTTOM]) {
printf("+----+");
} else {
printf("+ +");
}
}
printf("\n");
}
}
#pragma clang diagnostic pop