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.27 by root, Sat Apr 23 04:56:52 2011 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) Crossfire Development Team (restored, original file without copyright notice) 5 * Copyright (©) 1994-2004 Crossfire Development Team (restored, original file without copyright notice)
6 * 6 *
7 * Deliantra is free software: you can redistribute it and/or modify it under 7 * Deliantra is free software: you can redistribute it and/or modify it under
8 * the terms of the Affero GNU General Public License as published by the 8 * the terms of the Affero GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your 9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version. 10 * option) any later version.
39 39
40#include <vector> 40#include <vector>
41 41
42#include <global.h> 42#include <global.h>
43 43
44#include "random_map.h" 44#include <rmg.h>
45#include "rproto.h" 45#include "rproto.h"
46
47struct point
48{
49 short x;
50 short y;
51
52 point ()
53 {
54 }
55
56 point (int x, int y)
57 : x(x), y(y)
58 {
59 }
60};
61 46
62/* global variables that everyone needs: don't want to pass them in 47/* global variables that everyone needs: don't want to pass them in
63 as parameters every time. */ 48 as parameters every time. */
64static point *seed_list; 49static fixed_stack<point> seeds;
65static int seed_size;
66static int xsize, ysize; 50static int xsize, ysize;
67static char **maze; 51static char **maze;
52
53static void
54push (point p)
55{
56 seeds.push (p);
57 maze [p.x][p.y] = '#';
58}
59
60/* randomly returns one of the elements from the wall point list */
61static point
62pop_rand ()
63{
64 return seeds.remove (rmg_rndm (seeds.size));
65}
68 66
69/* the free wall points are those outer points which aren't corners or 67/* 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. */ 68 near corners, and don't have a maze wall growing out of them already. */
71static void 69static void
72make_wall_free_list () 70push_walls ()
73{ 71{
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 */ 72 /* top and bottom wall */
79 for (int x = 2; x < xsize - 2; x++) 73 for (int x = 2; x < xsize - 2; x++)
80 { 74 {
81 seed_list [seed_size++] = point (x, 0); 75 push (point (x, 0));
82 seed_list [seed_size++] = point (x, ysize - 1); 76 push (point (x, ysize - 1));
83 } 77 }
84 78
85 /* left and right wall */ 79 /* left and right wall */
86 for (int y = 2; y < ysize - 2; y++) 80 for (int y = 2; y < ysize - 2; y++)
87 { 81 {
88 seed_list [seed_size++] = point (0, y); 82 push (point ( 0, y));
89 seed_list [seed_size++] = point (xsize - 1, y); 83 push (point (xsize - 1, y));
90 } 84 }
91}
92
93/* randomly returns one of the elements from the wall point list */
94static point
95pop_point ()
96{
97 int index = rmg_rndm (seed_size);
98
99 point p = seed_list [index];
100
101 /* write the last array point here */
102 seed_list [index] = seed_list [--seed_size];
103
104 return p;
105} 85}
106 86
107/* find free point: randomly look for a square adjacent to this one where 87/* find free point: randomly look for a square adjacent to this one where
108we can place a new block without closing a path. We may only look 88we can place a new block without closing a path. We may only look
109up, down, right, or left. */ 89up, down, right, or left. */
185 } 165 }
186 166
187 return 1; 167 return 1;
188} 168}
189 169
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 170/* the outsize interface routine: accepts sizes, returns a char
229** maze. option is a flag for either a sparse or a full maze. Sparse 171** maze. option is a flag for either a sparse or a full maze. Sparse
230mazes have sizable rooms. option = 1, full, 0, sparse.*/ 172mazes have sizable rooms. option = 3=full, 2=braided, 1=sparse, 0=rooms.*/
231void 173void
232maze_gen (Layout maze, int full) 174maze_gen (layout &maze, int subtype)
233{ 175{
234 xsize = maze->w; 176 xsize = maze.w;
235 ysize = maze->h; 177 ysize = maze.h;
236 ::maze = maze; 178 ::maze = maze;
237 179
238 maze->clear (); 180 maze.clear ();
239 maze->border (); 181 maze.border ();
240 182
241 if (xsize < 4 || ysize < 4) 183 if (xsize < 4 || ysize < 4)
242 return; 184 return;
243 185
244 make_wall_free_list (); 186 seeds.reset (xsize * ysize);
187
188 if (subtype > 0)
189 push_walls ();
190
191 if (subtype == 0 || subtype == 2)
192 for (int i = (xsize + ysize) / 2; i; --i)
193 push (point (rmg_rndm (1, xsize - 2), rmg_rndm (1, ysize - 2)));
194
195 bool full = subtype == 3;
245 196
246 /* recursively generate the walls of the maze */ 197 /* recursively generate the walls of the maze */
247 /* first pop a random starting point */ 198 /* first pop a random starting point */
248 while (seed_size) 199 while (seeds.size)
249 if (full)
250 fill_maze_full (pop_point ());
251 else
252 fill_maze_sparse (pop_point ());
253
254 /* clean up our intermediate data structures. */
255 sfree (seed_list, xsize * ysize);
256}
257
258#if 0
259static struct demo
260{
261 demo ()
262 { 200 {
263 Layout layout (30, 30); 201 point p = pop_rand ();
264 rmg_rndm.seed (time (0));
265 202
266 for(int i=1;i<10;++i) 203 for (;;)
267 { 204 {
268 maze_gen (layout, 1); 205 point pc;
269 layout.print (); 206
207 maze [p.x][p.y] = '#';
208
209 if (find_free_point (pc, p) < 0)
210 break;
211
212 if (full)
213 push (p);
214
215 if (!rmg_rndm (8))
216 {
217 if (!full)
218 push (pc);
219
220 break;
221 }
222
223 p = pc;
270 } 224 }
271 exit (1);
272 } 225 }
273} demo; 226
274#endif 227 seeds.free ();
228}
229

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines