comparison urogue/maze.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 maze.c - functions for dealing with armor
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
10 All rights reserved.
11
12 See the file LICENSE.TXT for full copyright and licensing information.
13 */
14
15 #include <stdlib.h>
16 #include "rogue.h"
17
18 static char *frontier;
19 static char *bits;
20 static int urlines;
21 static int urcols;
22
23 /*
24 domaze()
25 Draw the maze on this level.
26 */
27
28 void
29 do_maze(void)
30 {
31 int i, least;
32 struct room *rp;
33 struct linked_list *item;
34 struct object *obj;
35 struct thing *mp;
36 int treas;
37 coord tp;
38
39 for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
40 {
41 rp->r_nexits = 0; /* no exits */
42 rp->r_flags = ISGONE; /* kill all rooms */
43 rp->r_fires = 0; /* no fires */
44 }
45
46 rp = &rooms[0]; /* point to only room */
47 rp->r_flags = ISDARK; /* mazes always dark */
48 rp->r_pos.x = 0; /* room fills whole screen */
49 rp->r_pos.y = 1;
50 rp->r_max.x = COLS - 1;
51 rp->r_max.y = LINES - 3;
52 draw_maze(); /* put maze into window */
53
54 /* add some gold to make it worth looking for */
55
56 item = spec_item(GOLD, 0, 0, 0);
57 obj = OBJPTR(item);
58 obj->o_count *= (rnd(10) + 5); /* add in one large hunk */
59
60 do
61 {
62 rnd_pos(rp, &tp);
63 }
64 while( mvwinch(stdscr, tp.y, tp.x) != FLOOR);
65
66 obj->o_pos = tp;
67 add_obj(item, tp.y, tp.x);
68
69 /* add in some food to make sure he has enough */
70
71 item = spec_item(FOOD, 0, 0, 0);
72 obj = OBJPTR(item);
73
74 do
75 {
76 rnd_pos(rp, &tp);
77 }
78 while( mvwinch(stdscr, tp.y, tp.x) != FLOOR);
79
80 obj->o_pos = tp;
81 add_obj(item, tp.y, tp.x);
82
83 if (rnd(100) < 5) /* 5% for treasure maze level */
84 {
85 treas = TRUE;
86 least = 20;
87 debug("Treasure maze.");
88 }
89 else /* normal maze level */
90 {
91 least = 1;
92 treas = FALSE;
93 }
94
95 for (i = 0; i < level + least; i++)
96 {
97 if (!treas && rnd(100) < 50) /* put in some little buggers */
98 continue;
99
100 /* Put the monster in */
101
102 item = new_item(sizeof *mp);
103
104 mp = THINGPTR(item);
105
106 do
107 {
108 rnd_pos(rp, &tp);
109 }
110 while(mvwinch(stdscr, tp.y, tp.x) != FLOOR);
111
112 new_monster(item, randmonster(NOWANDER, NOGRAB), &tp, NOMAXSTATS);
113
114 /* See if we want to give it a treasure to carry around. */
115
116 if (rnd(100) < monsters[mp->t_index].m_carry)
117 attach(mp->t_pack, new_thing());
118
119 /* If it carries gold, give it some */
120
121 if (on(*mp, CARRYGOLD))
122 {
123 item = spec_item(GOLD, 0, 0, 0);
124 obj = OBJPTR(item);
125 obj->o_count = GOLDCALC + GOLDCALC + GOLDCALC;
126 obj->o_pos = mp->t_pos;
127 attach(mp->t_pack, item);
128 }
129
130 }
131 }
132
133 /*
134 draw_maze()
135 Generate and draw the maze on the screen
136 */
137
138 void
139 draw_maze(void)
140 {
141 int i, j, more;
142 char *ptr;
143
144 urlines = (LINES - 3) / 2;
145 urcols = (COLS - 1) / 2;
146
147 bits = ur_alloc((unsigned int) ((LINES - 3) * (COLS - 1)));
148 frontier = ur_alloc((unsigned int) (urlines * urcols));
149 ptr = frontier;
150
151 while (ptr < (frontier + (urlines * urcols)))
152 *ptr++ = TRUE;
153
154 for (i = 0; i < LINES - 3; i++)
155 {
156 for (j = 0; j < COLS - 1; j++)
157 {
158 if (i % 2 == 1 && j % 2 == 1)
159 *moffset(i, j) = FALSE; /* floor */
160 else
161 *moffset(i, j) = TRUE; /* wall */
162 }
163 }
164
165 for (i = 0; i < urlines; i++)
166 {
167 for (j = 0; j < urcols; j++)
168 {
169 do
170 more = findcells(i, j);
171 while (more != 0);
172 }
173 }
174
175 crankout();
176 ur_free(frontier);
177 ur_free(bits);
178 }
179
180 /*
181 moffset()
182 Calculate memory address for bits
183 */
184
185 char *
186 moffset(int y, int x)
187 {
188 return (bits + (y * (COLS - 1)) + x);
189 }
190
191 /*
192 foffset()
193 Calculate memory address for frontier
194 */
195
196 char *
197 foffset(int y, int x)
198 {
199 return (frontier + (y * urcols) + x);
200 }
201
202 /*
203 findcells()
204 Figure out cells to open up
205 */
206
207 int
208 findcells(int y, int x)
209 {
210 int rtpos, i;
211
212 struct
213 {
214 int num_pos; /* number of frontier cells next to you */
215
216 struct
217 {
218 int y_pos;
219 int x_pos;
220 } conn[4]; /* the y,x position of above cell */
221 } mborder;
222
223 *foffset(y, x) = FALSE;
224 mborder.num_pos = 0;
225
226 if (y < urlines - 1) { /* look below */
227 if (*foffset(y + 1, x))
228 {
229 mborder.conn[mborder.num_pos].y_pos = y + 1;
230 mborder.conn[mborder.num_pos].x_pos = x;
231 mborder.num_pos += 1;
232 }
233 }
234
235 if (y > 0) /* look above */
236 {
237 if (*foffset(y - 1, x))
238 {
239 mborder.conn[mborder.num_pos].y_pos = y - 1;
240 mborder.conn[mborder.num_pos].x_pos = x;
241 mborder.num_pos += 1;
242 }
243 }
244
245 if (x < urcols - 1) /* look right */
246 {
247 if (*foffset(y, x + 1))
248 {
249 mborder.conn[mborder.num_pos].y_pos = y;
250 mborder.conn[mborder.num_pos].x_pos = x + 1;
251 mborder.num_pos += 1;
252 }
253 }
254
255 if (x > 0) /* look left */
256 {
257 if (*foffset(y, x - 1))
258 {
259 mborder.conn[mborder.num_pos].y_pos = y;
260 mborder.conn[mborder.num_pos].x_pos = x - 1;
261 mborder.num_pos += 1;
262 }
263 }
264
265 if (mborder.num_pos == 0)/* no neighbors available */
266 return(0);
267 else
268 {
269 i = rnd(mborder.num_pos);
270 rtpos = mborder.num_pos - 1;
271 rmwall(mborder.conn[i].y_pos, mborder.conn[i].x_pos, y, x);
272 return(rtpos);
273 }
274 }
275
276 /*
277 rmwall()
278 Removes appropriate walls from the maze
279 */
280
281 void
282 rmwall(int newy, int newx, int oldy, int oldx)
283 {
284 int xdif, ydif;
285
286 xdif = newx - oldx;
287 ydif = newy - oldy;
288
289 *moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE;
290
291 findcells(newy, newx);
292 }
293
294
295 /*
296 crankout()
297 Does actual drawing of maze to window
298 */
299
300 void
301 crankout(void)
302 {
303 int x, y;
304
305 for (y = 0; y < LINES - 3; y++)
306 {
307 move(y + 1, 0);
308
309 for (x = 0; x < COLS - 1; x++)
310 {
311 if (*moffset(y, x)) /* here is a wall */
312 {
313 if (y == 0 || y == LINES - 4) /* top or bottom line */
314 addch('-');
315 else if (x == 0 || x == COLS - 2) /* left | right side */
316 addch('|');
317 else if (y % 2 == 0 && x % 2 == 0)
318 {
319 if (*moffset(y, x - 1) || *moffset(y, x + 1))
320 addch('-');
321 else
322 addch('|');
323 }
324 else if (y % 2 == 0)
325 addch('-');
326 else
327 addch('|');
328 }
329 else
330 addch(FLOOR);
331 }
332 }
333 }