Annotation of early-roguelike/urogue/maze.c, Revision 1.1.1.1
1.1 rubenllo 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: }
CVSweb