ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/maze_gen.C
(Generate patch)

Comparing deliantra/server/random_maps/maze_gen.C (file contents):
Revision 1.20 by root, Sun Jun 27 20:40:54 2010 UTC vs.
Revision 1.21 by root, Tue Jun 29 16:52:53 2010 UTC

60}; 60};
61 61
62/* global variables that everyone needs: don't want to pass them in 62/* global variables that everyone needs: don't want to pass them in
63 as parameters every time. */ 63 as parameters every time. */
64static point *seed_list; 64static point *seed_list;
65static int seed_size; 65static int seed_max, seed_size;
66static int xsize, ysize; 66static int xsize, ysize;
67static char **maze; 67static char **maze;
68
69static void
70push (point p)
71{
72 assert (seed_size < seed_max);
73
74 seed_list [seed_size++] = p;
75
76 maze [p.x][p.y] = '#';
77}
68 78
69/* the free wall points are those outer points which aren't corners or 79/* the free wall points are those outer points which aren't corners or
70 near corners, and don't have a maze wall growing out of them already. */ 80 near corners, and don't have a maze wall growing out of them already. */
71static void 81static void
72make_wall_free_list () 82push_walls ()
73{ 83{
74 // xsize * ysize is plenty too much, but it's temporary
75 seed_list = salloc<point> (xsize * ysize);
76 seed_size = 0;
77
78 /* top and bottom wall */ 84 /* top and bottom wall */
79 for (int x = 2; x < xsize - 2; x++) 85 for (int x = 2; x < xsize - 2; x++)
80 { 86 {
81 seed_list [seed_size++] = point (x, 0); 87 push (point (x, 0));
82 seed_list [seed_size++] = point (x, ysize - 1); 88 push (point (x, ysize - 1));
83 } 89 }
84 90
85 /* left and right wall */ 91 /* left and right wall */
86 for (int y = 2; y < ysize - 2; y++) 92 for (int y = 2; y < ysize - 2; y++)
87 { 93 {
88 seed_list [seed_size++] = point (0, y); 94 push (point ( 0, y));
89 seed_list [seed_size++] = point (xsize - 1, y); 95 push (point (xsize - 1, y));
90 } 96 }
91} 97}
92 98
93/* randomly returns one of the elements from the wall point list */ 99/* randomly returns one of the elements from the wall point list */
94static point 100static point
95pop_point () 101pop_rand ()
96{ 102{
97 int index = rmg_rndm (seed_size); 103 int index = rmg_rndm (seed_size);
98 104
99 point p = seed_list [index]; 105 point p = seed_list [index];
100 106
185 } 191 }
186 192
187 return 1; 193 return 1;
188} 194}
189 195
190/* recursive routine which will fill every available space in the maze
191 with walls*/
192static void
193fill_maze_full (point p)
194{
195 point pc;
196
197 /* write a wall here */
198 maze[p.x][p.y] = '#';
199
200 /* decide if we're going to pick from the wall_free_list */
201 if (rmg_rndm (2) && seed_size)
202 fill_maze_full (pop_point ());
203
204 /* change the while to an if for a sparse maze. */
205 while (find_free_point (pc, p) != -1)
206 fill_maze_full (pc);
207}
208
209/* recursive routine which will fill much of the maze, but will leave
210 some free spots (possibly large) toward the center.*/
211static void
212fill_maze_sparse (point p)
213{
214 point pc;
215
216 /* write a wall here */
217 maze[p.x][p.y] = '#';
218
219 /* decide if we're going to pick from the wall_free_list */
220 if (rmg_rndm (2) && seed_size)
221 fill_maze_full (pop_point ());
222
223 /* change the if to a while for a complete maze. */
224 if (find_free_point (pc, p) != -1)
225 fill_maze_full (pc);
226}
227
228/* the outsize interface routine: accepts sizes, returns a char 196/* the outsize interface routine: accepts sizes, returns a char
229** maze. option is a flag for either a sparse or a full maze. Sparse 197** maze. option is a flag for either a sparse or a full maze. Sparse
230mazes have sizable rooms. option = 1, full, 0, sparse.*/ 198mazes have sizable rooms. option = 3=full, 2=braided, 1=sparse, 0=rooms.*/
231void 199void
232maze_gen (Layout maze, int full) 200maze_gen (Layout maze, int subtype)
233{ 201{
234 xsize = maze->w; 202 xsize = maze->w;
235 ysize = maze->h; 203 ysize = maze->h;
236 ::maze = maze; 204 ::maze = maze;
237 205
239 maze->border (); 207 maze->border ();
240 208
241 if (xsize < 4 || ysize < 4) 209 if (xsize < 4 || ysize < 4)
242 return; 210 return;
243 211
244 make_wall_free_list (); 212 seed_max = xsize * ysize;
213 seed_size = 0;
214 seed_list = salloc<point> (seed_max);
215
216 if (subtype > 0)
217 push_walls ();
218
219 if (subtype == 0 || subtype == 2)
220 for (int i = (xsize + ysize) / 2; i; --i)
221 push (point (rmg_rndm (1, xsize - 2), rmg_rndm (1, ysize - 2)));
222
223 bool full = subtype == 3;
245 224
246 /* recursively generate the walls of the maze */ 225 /* recursively generate the walls of the maze */
247 /* first pop a random starting point */ 226 /* first pop a random starting point */
248 while (seed_size) 227 while (seed_size)
228 {
229 point p = pop_rand ();
230
231 for (;;)
232 {
233 point pc;
234
235 maze [p.x][p.y] = '#';
236
237 if (find_free_point (pc, p) < 0)
238 break;
239
249 if (full) 240 if (full)
250 fill_maze_full (pop_point ()); 241 push (p);
251 else 242
252 fill_maze_sparse (pop_point ()); 243 if (!rmg_rndm (8))
244 {
245 if (!full)
246 push (pc);
247
248 break;
249 }
250
251 p = pc;
252 }
253 }
253 254
254 /* clean up our intermediate data structures. */ 255 /* clean up our intermediate data structures. */
255 sfree (seed_list, xsize * ysize); 256 sfree (seed_list, seed_max);
256} 257}
257 258
258#if 0 259#if 0
259static struct demo 260static struct demo
260{ 261{
263 Layout layout (30, 30); 264 Layout layout (30, 30);
264 rmg_rndm.seed (time (0)); 265 rmg_rndm.seed (time (0));
265 266
266 for(int i=1;i<10;++i) 267 for(int i=1;i<10;++i)
267 { 268 {
268 maze_gen (layout, 1); 269 maze_gen (layout, 3);
269 layout.print (); 270 layout.print ();
270 } 271 }
271 exit (1); 272 exit (1);
272 } 273 }
273} demo; 274} demo;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines