while loop not exiting predictably or fulfilling statement at top

So, I have a loop that generates me a random maze. However, it never gets the the desired end. It reaches a random number of loops till the end and then quits without fulfilling the top statement or hitting the break loop.

I've added std::cout to debug but I haven't been able to figure it out.
Here is the 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
while (numOpenCells > 0){ //loop until there aren't any more open cells
  //getting the new cell
    int newCell[2];
    int mX = cCell[1];
    int mY = cCell[0];
    std::string newDir = nextDirOpen(cCell); //next unused cell
    if (newDir == "None"){
      newDir = nextDirVisited(cCell);
      if (newDir == "None"){ //just in case we back track where we shouldn't
       /* std::cout << "Error, no area to back track to!" << std::endl;
        std::cout << "Area of Issue: ( " << cCell[1] << ", " << cCell[0] << ") " << std::endl;
        break; //and ends the process */
        std::cout << "Issue: " << cCell[1] << " " << cCell[0] << std::endl;
        break;
      }else{
        std::cout << "Backtracking: " << newDir << std::endl;
        newCell[0] = newPosY(cCell, newDir);
        newCell[1] = newPosX(cCell, newDir);
        maze[mY][mX] = 'U';
      }
    }else{
      std::cout << "Digging: " << newDir << std::endl;
      newCell[0] = newPosY(cCell, newDir);
      newCell[1] = newPosX(cCell, newDir);
      maze[mY][mX] = 'V';
    }
    //proper actions with new cell
    destWall(cCell, newDir); //destroy the wall
    cCell[0] = newCell[0];
    cCell[1] = newCell[1];
    numOpenCells = OpenNum();
    std::cout << numOpenCells << std::endl;
  }


Could it be i'm using the wrong random generator?
(srand())
Last edited on
> Here is the code:
¿are we supposed to imagine what your functions do and how are they coded?
Fine, have fun with 250 lines of 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
#include <iostream>
#include <vector>
#include <string>
#include <ctime>
#include <cstdlib>
/*
Starter Cell = S;
Open = O;
Visited = V;
Used = U;
Destroyed Wall = X;

maze[y][x];
cell[2] = {y, x};

*/



//global maze var (prevents monotonous typing) (also optimizes?)
std::vector<std::vector<char>> maze(13, std::vector<char>(13, '#'));

void setUp(){ //create the proper cell openings
  for (int x = 0; x < 13; x++){
    for (int y = 0; y < 13; y++){
      if ((x+1)%2==0 && (y+1)%2==0){//both x and y even
        maze[y][x] = 'O';
      }
    }
  }
}

void cleanUp(){ //cleanup the cell markings used to avoid classes use
  for (int y = 0; y < 13; y++){
    for (int x = 0; x < 13; x++){
      char cell = maze[y][x];
      if (cell == 'O'){
        maze[y][x] = ' ';
      }else if (cell == 'V'){
        maze[y][x] = ' ';
      }else if (cell == 'U'){
        maze[y][x] = ' ';
      }else if (cell == 'X'){
        maze[y][x] = ' ';
      }
    }
  }
}

void output(){ //output maze to console
  for (int y = 0; y < 13; y++){
    for (int x = 0; x < 13; x++){
      std::cout << maze[y][x] << ' ';
    }
    std::cout << std::endl;
  }
}

std::string cellType(int cell[2]){ //identify cell type to be able to determine course of action
  int x = cell[1];
  int y = cell[0];
  char cData = maze[y][x];
  if (cData == 'O'){
    return "Open";
  }else if (cData == 'V'){
    return "Visited";
  }else if (cData == 'U'){
    return "Used";
  }else if (cData == 'X'){
    return "Destroyed Wall";
  }else if (cData == '#'){
    return "Wall";
  }
  return "Could not classify";
}

void getSCell(int sCell[2]){ //the maze has to start some where, gets a starter cell
  srand(time(NULL));//seed for the pseudo-random thingy
  int pPos[6] = {1,3,5,7,9,11};
  sCell[0] = pPos[(rand() % 6)];
  sCell[1] = pPos[(rand() % 6)];
}

int OpenNum(){
  int num = 0;
  for (int x = 0; x < 13; x++){
    for (int y = 0; y < 13; y++){
      int cell[2] = {y, x};
      std::string cTyp = cellType(cell);
      if (cTyp == "Open"){
        num++;
      }
    }
  }
  return num;
}

void destWall(int cCell[2], std::string dir){ //destroy wall (this is what makes the maze visible)
  int y = cCell[0];
  int x = cCell[1];
  if (dir == "Up"){
    if (y > 1){
      maze[y - 1][x] = 'X';
    }
  }else if (dir == "Down"){
    if (y < 12){
      maze[y + 1][x] = 'X';
    }
  }else if (dir == "Left"){
    if (x > 1){
      maze[y][x - 1] = 'X';
    }
  }else if (dir == "Right"){
    if (x < 12){
      maze[y][x + 1] = 'X';
    }
  }
}

int newPosX(int cCell[2], std::string dir){
  int x = cCell[1];
  if (dir == "Left"){
    if (x > 1){
      return (x - 2);
    }
  }else if (dir == "Right"){
    if (x < 12){
      return (x + 2);
    }
  } 
  return x;
}

int newPosY(int cCell[2], std::string dir){
  int y = cCell[0];
  if (dir == "Up"){
    if (y > 1){
      return (y - 2);
    }
  }else if (dir == "Down"){
      if (y < 12){
        return (y + 2);
      }
    }
  return y;
}

std::string nextDirOpen(int cCell[2]){
  srand(time(NULL));
  int y = cCell[0];
  int x = cCell[1];
  std::string dirs[4] = {"Up", "Down", "Left", "Right"};
  std::string pDirs[4];
  int index = 0;
  for (int i = 0; i < 4; i++){
    int newCell[2] = {newPosY(cCell, dirs[i]), newPosX(cCell, dirs[i])}; //get the new cell
    /*std::cout << newCell[0] << " " << newCell[1] << std::endl;
    std::cout << cCell[0] << " " << cCell[1] << std::endl;
    std::cout << std::endl; */
    if (newCell[0] != cCell[0] || newCell[1] != cCell[1]){ //if it isn't the same
      std::string cType = cellType(newCell); //get the cell type
      if (cType == "Open"){ //is it an Open cell?
        pDirs[index] = dirs[i]; // add it to the array
        index++;
      }
    }
  }
  if (index > 0){
    int r = rand() % index;
    return pDirs[r]; //returns a random direction that is possible
  }
  return "None";
  
}

std::string nextDirVisited(int cCell[2]){
  srand(time(NULL));
  int y = cCell[0];
  int x = cCell[1];
  std::string dirs[4] = {"Up", "Down", "Left", "Right"};
  std::string pDirs[4];
  int index = 0;
  for (int i = 0; i < 4; i++){
    int newCell[2] = {newPosY(cCell, dirs[i]), newPosX(cCell, dirs[i])}; //get the new cell
    if (newCell[0] != cCell[0] || newCell[1] != cCell[1]){ //if it isn't the same
      std::string cType = cellType(newCell); //get the cell type
      if (cType == "Visited"){ //is it an Open cell?
        pDirs[index] = dirs[i]; // add it to the array
        index++;
      }
    }
  }
  if (index > 0){
    int r = rand() % index;
    return pDirs[r]; //returns a random direction that is possible
  }
  return "None";
  
}

void generate(){
  setUp();
  //starter cell
  int sCell[2];
  getSCell(sCell);
  //current cell
  int cCell[2] = {sCell[1], sCell[0]}; //remember it is y x
  int numOpenCells = OpenNum(); //gets us the number of open cells
  
  while (numOpenCells > 0){ //loop until there aren't any more open cells
  //getting the new cell
    int newCell[2];
    int mX = cCell[1];
    int mY = cCell[0];
    std::string newDir = nextDirOpen(cCell); //next unused cell
    if (newDir == "None"){
      newDir = nextDirVisited(cCell);
      if (newDir == "None"){ //just in case we back track where we shouldn't
       /* std::cout << "Error, no area to back track to!" << std::endl;
        std::cout << "Area of Issue: ( " << cCell[1] << ", " << cCell[0] << ") " << std::endl;
        break; //and ends the process */
        std::cout << "Issue: " << cCell[1] << " " << cCell[0] << std::endl;
        break;
      }else{
        std::cout << "Backtracking: " << newDir << std::endl;
        newCell[0] = newPosY(cCell, newDir);
        newCell[1] = newPosX(cCell, newDir);
        maze[mY][mX] = 'U';
      }
    }else{
      std::cout << "Digging: " << newDir << std::endl;
      newCell[0] = newPosY(cCell, newDir);
      newCell[1] = newPosX(cCell, newDir);
      maze[mY][mX] = 'V';
    }
    //proper actions with new cell
    destWall(cCell, newDir); //destroy the wall
    cCell[0] = newCell[0];
    cCell[1] = newCell[1];
    numOpenCells = OpenNum();
    std::cout << numOpenCells << std::endl;
  }
  //output();
}

int main() {
  generate();
  output();
  std::cout << "We good!" << std::endl;
}
1
2
3
4
5
6
//newPosY
}else if (dir == "Down"){
	if (y < 12){
		return (y + 2);
	}
}
your maze is 13x13
say that y=11 and dir="Down", you'll update y to 13, out of bounds.
this sounds familiar...
I hate it when I'm stupid. Thank you so much.
To bless you, here is a random maze:

# # # # # # # # # # # # # 
#       #               # 
#   # # # # # # # # #   # 
#           #           # 
# # # # #   #   # # # # # 
#           #           # 
#   # # # # # # # # #   # 
#               #       # 
# # # # # # #   #   # # # 
#               #       # 
#   # # # # # # # # #   # 
#                       # 
# # # # # # # # # # # # #
Topic archived. No new replies allowed.