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.3 by root, Sun Sep 10 16:06:37 2006 UTC vs.
Revision 1.8 by root, Fri Apr 11 21:09:53 2008 UTC

1
2 1
3/* peterm@langmuir.eecs.berkeley.edu: this function generates a random 2/* peterm@langmuir.eecs.berkeley.edu: this function generates a random
4blocked maze with the property that there is only one path from one spot 3blocked maze with the property that there is only one path from one spot
5to any other, and there is always a path from one spot to any other. 4to any other, and there is always a path from one spot to any other.
6 5
14 13
15/* we need to maintain a list of wall points to generate 14/* we need to maintain a list of wall points to generate
16 reasonable mazes: a straightforward recursive random walk maze 15 reasonable mazes: a straightforward recursive random walk maze
17 generator would generate a map with a trivial circle-the-outer-wall solution */ 16 generator would generate a map with a trivial circle-the-outer-wall solution */
18 17
19#include <stdio.h>
20#include <global.h> 18#include <global.h>
21 19
22/*#include <random_map.h>*/ 20#include "random_map.h"
23#include <maze_gen.h> 21#include "rproto.h"
24#include <time.h>
25
26
27/* this include solely, and only, is needed for the definition of RANDOM */
28
29
30 22
31/* global variables that everyone needs: don't want to pass them in 23/* global variables that everyone needs: don't want to pass them in
32 as parameters every time. */ 24 as parameters every time. */
33int *wall_x_list = 0; 25int *wall_x_list = 0;
34int *wall_y_list = 0; 26int *wall_y_list = 0;
41 33
42/* the outsize interface routine: accepts sizes, returns a char 34/* the outsize interface routine: accepts sizes, returns a char
43** maze. option is a flag for either a sparse or a full maze. Sparse 35** maze. option is a flag for either a sparse or a full maze. Sparse
44mazes have sizable rooms. option = 1, full, 0, sparse.*/ 36mazes have sizable rooms. option = 1, full, 0, sparse.*/
45 37
46char ** 38Maze
47maze_gen (int xsize, int ysize, int option) 39maze_gen (int xsize, int ysize, int option)
48{ 40{
49 int i, j; 41 int i, j;
50 42
51 /* allocate that array, set it up */ 43 Maze maze (xsize, ysize);
52 char **maze = (char **) calloc (sizeof (char *), xsize);
53
54 for (i = 0; i < xsize; i++)
55 {
56 maze[i] = (char *) calloc (sizeof (char), ysize);
57 }
58 44
59 /* write the outer walls */ 45 /* write the outer walls */
60 for (i = 0; i < xsize; i++) 46 for (i = 0; i < xsize; i++) maze[i][0] = maze[i][ysize - 1] = '#';
61 maze[i][0] = maze[i][ysize - 1] = '#'; 47 for (j = 0; j < ysize; j++) maze[0][j] = maze[xsize - 1][j] = '#';
62 for (j = 0; j < ysize; j++)
63 maze[0][j] = maze[xsize - 1][j] = '#';
64
65 48
66 /* find how many free wall spots there are */ 49 /* find how many free wall spots there are */
67 wall_free_size = 2 * (xsize - 4) + 2 * (ysize - 4); 50 wall_free_size = 2 * (xsize - 4) + 2 * (ysize - 4);
68 51
69 make_wall_free_list (xsize, ysize); 52 make_wall_free_list (xsize, ysize);
75 /* recursively generate the walls of the maze */ 58 /* recursively generate the walls of the maze */
76 /* first pop a random starting point */ 59 /* first pop a random starting point */
77 while (wall_free_size > 0) 60 while (wall_free_size > 0)
78 { 61 {
79 pop_wall_point (&i, &j); 62 pop_wall_point (&i, &j);
63
80 if (option) 64 if (option)
81 fill_maze_full (maze, i, j, xsize, ysize); 65 fill_maze_full (maze, i, j, xsize, ysize);
82 else 66 else
83 fill_maze_sparse (maze, i, j, xsize, ysize); 67 fill_maze_sparse (maze, i, j, xsize, ysize);
84 } 68 }
89 free (wall_y_list); 73 free (wall_y_list);
90 74
91 return maze; 75 return maze;
92} 76}
93 77
94
95
96/* the free wall points are those outer points which aren't corners or 78/* the free wall points are those outer points which aren't corners or
97 near corners, and don't have a maze wall growing out of them already. */ 79 near corners, and don't have a maze wall growing out of them already. */
98
99void 80void
100make_wall_free_list (int xsize, int ysize) 81make_wall_free_list (int xsize, int ysize)
101{ 82{
102 int i, j, count; 83 int i, j, count;
103 84
104 count = 0; /* entries already placed in the free list */ 85 count = 0; /* entries already placed in the free list */
105 /*allocate it */ 86 /*allocate it */
106 if (wall_free_size < 0) 87 if (wall_free_size < 0)
107 return; 88 return;
89
108 wall_x_list = (int *) calloc (sizeof (int), wall_free_size); 90 wall_x_list = (int *)calloc (sizeof (int), wall_free_size);
109 wall_y_list = (int *) calloc (sizeof (int), wall_free_size); 91 wall_y_list = (int *)calloc (sizeof (int), wall_free_size);
110
111 92
112 /* top and bottom wall */ 93 /* top and bottom wall */
113 for (i = 2; i < xsize - 2; i++) 94 for (i = 2; i < xsize - 2; i++)
114 { 95 {
115 wall_x_list[count] = i; 96 wall_x_list[count] = i;
130 wall_y_list[count] = j; 111 wall_y_list[count] = j;
131 count++; 112 count++;
132 } 113 }
133} 114}
134 115
135
136
137/* randomly returns one of the elements from the wall point list */ 116/* randomly returns one of the elements from the wall point list */
138
139void 117void
140pop_wall_point (int *x, int *y) 118pop_wall_point (int *x, int *y)
141{ 119{
142 int index = RANDOM () % wall_free_size; 120 int index = rndm (wall_free_size);
143 121
144 *x = wall_x_list[index]; 122 *x = wall_x_list[index];
145 *y = wall_y_list[index]; 123 *y = wall_y_list[index];
146 /* write the last array point here */ 124 /* write the last array point here */
147 wall_x_list[index] = wall_x_list[wall_free_size - 1]; 125 wall_x_list[index] = wall_x_list[wall_free_size - 1];
148 wall_y_list[index] = wall_y_list[wall_free_size - 1]; 126 wall_y_list[index] = wall_y_list[wall_free_size - 1];
149 wall_free_size--; 127 wall_free_size--;
150} 128}
151 129
152
153
154/* find free point: randomly look for a square adjacent to this one where 130/* find free point: randomly look for a square adjacent to this one where
155we can place a new block without closing a path. We may only look 131we can place a new block without closing a path. We may only look
156up, down, right, or left. */ 132up, down, right, or left. */
157
158int 133int
159find_free_point (char **maze, int *x, int *y, int xc, int yc, int xsize, int ysize) 134find_free_point (char **maze, int *x, int *y, int xc, int yc, int xsize, int ysize)
160{ 135{
161 136
162/* we will randomly pick from this list, 1=up,2=down,3=right,4=left */ 137/* we will randomly pick from this list, 1=up,2=down,3=right,4=left */
225 if (count == 0) 200 if (count == 0)
226 return -1; /* failed to find any clear points */ 201 return -1; /* failed to find any clear points */
227 202
228 /* choose a random direction */ 203 /* choose a random direction */
229 if (count > 1) 204 if (count > 1)
230 count = RANDOM () % count; 205 count = rndm (count);
231 else 206 else
232 count = 0; 207 count = 0;
208
233 switch (dirlist[count]) 209 switch (dirlist[count])
234 { 210 {
235 case 1: /* up */ 211 case 1: /* up */
236 { 212 {
237 *y = yc + 1; 213 *y = yc + 1;
238 *x = xc; 214 *x = xc;
239 break; 215 break;
240 }; 216 };
241 case 2: /* down */ 217 case 2: /* down */
242 { 218 {
243 *y = yc - 1; 219 *y = yc - 1;
244 *x = xc; 220 *x = xc;
245 break; 221 break;
246 }; 222 };
247 case 3: /* right */ 223 case 3: /* right */
248 { 224 {
249 *y = yc; 225 *y = yc;
250 *x = xc + 1; 226 *x = xc + 1;
251 break; 227 break;
252 } 228 }
253 case 4: /* left */ 229 case 4: /* left */
254 { 230 {
255 *x = xc - 1; 231 *x = xc - 1;
256 *y = yc; 232 *y = yc;
257 break; 233 break;
258 } 234 }
259 default: /* ??? */ 235 default: /* ??? */
260 {
261 return -1; 236 return -1;
262 } 237
263 } 238 }
264 return 1; 239 return 1;
265} 240}
266 241
267/* recursive routine which will fill every available space in the maze 242/* recursive routine which will fill every available space in the maze
274 249
275 /* write a wall here */ 250 /* write a wall here */
276 maze[x][y] = '#'; 251 maze[x][y] = '#';
277 252
278 /* decide if we're going to pick from the wall_free_list */ 253 /* decide if we're going to pick from the wall_free_list */
279 if (RANDOM () % 4 && wall_free_size > 0) 254 if (rndm (4) && wall_free_size > 0)
280 { 255 {
281 pop_wall_point (&xc, &yc); 256 pop_wall_point (&xc, &yc);
282 fill_maze_full (maze, xc, yc, xsize, ysize); 257 fill_maze_full (maze, xc, yc, xsize, ysize);
283 } 258 }
284 259
287 { 262 {
288 fill_maze_full (maze, xc, yc, xsize, ysize); 263 fill_maze_full (maze, xc, yc, xsize, ysize);
289 } 264 }
290} 265}
291 266
292
293/* recursive routine which will fill much of the maze, but will leave 267/* recursive routine which will fill much of the maze, but will leave
294 some free spots (possibly large) toward the center.*/ 268 some free spots (possibly large) toward the center.*/
295
296void 269void
297fill_maze_sparse (char **maze, int x, int y, int xsize, int ysize) 270fill_maze_sparse (char **maze, int x, int y, int xsize, int ysize)
298{ 271{
299 int xc, yc; 272 int xc, yc;
300 273
301 /* write a wall here */ 274 /* write a wall here */
302 maze[x][y] = '#'; 275 maze[x][y] = '#';
303 276
304 /* decide if we're going to pick from the wall_free_list */ 277 /* decide if we're going to pick from the wall_free_list */
305 if (RANDOM () % 4 && wall_free_size > 0) 278 if (rndm (4) && wall_free_size > 0)
306 { 279 {
307 pop_wall_point (&xc, &yc); 280 pop_wall_point (&xc, &yc);
308 fill_maze_sparse (maze, xc, yc, xsize, ysize); 281 fill_maze_sparse (maze, xc, yc, xsize, ysize);
309 } 282 }
310 283
311 /* change the if to a while for a complete maze. */ 284 /* change the if to a while for a complete maze. */
312 if (find_free_point (maze, &xc, &yc, x, y, xsize, ysize) != -1) 285 if (find_free_point (maze, &xc, &yc, x, y, xsize, ysize) != -1)
313 {
314 fill_maze_sparse (maze, xc, yc, xsize, ysize); 286 fill_maze_sparse (maze, xc, yc, xsize, ysize);
315 }
316} 287}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines