[BACK]Return to maze.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / xrogue

Annotation of early-roguelike/xrogue/maze.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:     maze.c  -  functions for dealing with mazes
                      3:
                      4:     XRogue: Expeditions into the Dungeons of Doom
                      5:     Copyright (C) 1991 Robert Pietkivitch
                      6:     All rights reserved.
                      7:
                      8:     Based on "Advanced Rogue"
                      9:     Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
                     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 <curses.h>
                     17: #include "rogue.h"
                     18:
                     19: struct cell {
                     20:         char y_pos;
                     21:         char x_pos;
                     22: };
                     23: struct b_cellscells {
                     24:         unsigned char num_pos;  /* number of frontier cells next to you */
                     25:         struct cell conn[4];    /* the y,x position of above cell */
                     26: } b_cells;
                     27:
                     28: static char     *maze_frontier, *maze_bits;
                     29: static int      maze_lines, maze_cols;
                     30: static char    *moffset(int y, int x);
                     31: static char    *foffset(int y, int x);
                     32: static void     rmwall(int newy, int newx, int oldy, int oldx);
                     33: static void     draw_maze(void);
                     34: static int      findcells(int y, int x);
                     35:
                     36: /*
                     37:  * crankout:
                     38:  *      Does actual drawing of maze to window
                     39:  */
                     40:
                     41: static
                     42: void
                     43: crankout(void)
                     44: {
                     45:     reg int x, y;
                     46:
                     47:     for (y = 0; y < lines - 3; y++) {
                     48:         move(y + 1, 0);
                     49:         for (x = 0; x < cols - 1; x++) {
                     50:             if (*moffset(y, x)) {           /* here is a wall */
                     51:                 if(y==0 || y==lines-4) /* top or bottom line */
                     52:                     addch(HORZWALL);
                     53:                 else if(x==0 || x==cols-2) /* left | right side */
                     54:                     addch(VERTWALL);
                     55:                 else if (y % 2 == 0 && x % 2 == 0) {
                     56:                     if(*moffset(y, x-1) || *moffset(y, x+1))
                     57:                         addch(HORZWALL);
                     58:                     else
                     59:                         addch(VERTWALL);
                     60:                 }
                     61:                 else if (y % 2 == 0)
                     62:                     addch(HORZWALL);
                     63:                 else
                     64:                     addch(VERTWALL);
                     65:             }
                     66:             else
                     67:                 addch(FLOOR);
                     68:         }
                     69:     }
                     70: }
                     71:
                     72: /*
                     73:  * domaze:
                     74:  *      Draw the maze on this level.
                     75:  */
                     76:
                     77: void
                     78: do_maze(void)
                     79: {
                     80:         reg int least;
                     81:         reg struct room *rp;
                     82:         reg struct linked_list *item;
                     83:         reg struct object *obj;
                     84:         int cnt;
                     85:         bool treas;
                     86:         coord tp;
                     87:
                     88:         for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
                     89:                 rp->r_flags = ISGONE;           /* kill all rooms */
                     90:                 rp->r_fires = NULL;             /* no fires */
                     91:         }
                     92:         rp = &rooms[0];                         /* point to only room */
                     93:         rp->r_flags = ISDARK;                   /* mazes always dark */
                     94:         rp->r_pos.x = 0;                        /* room fills whole screen */
                     95:         rp->r_pos.y = 1;
                     96:         rp->r_max.x = cols - 1;
                     97:         rp->r_max.y = lines - 3;
                     98:         draw_maze();                            /* put maze into window */
                     99:         /*
                    100:          * add some gold to make it worth looking for
                    101:          */
                    102:         item = spec_item(GOLD, 0, 0, 0);
                    103:         obj = OBJPTR(item);
                    104:         obj->o_count *= (rnd(50) + 50);         /* add in one large hunk */
                    105:         attach(lvl_obj, item);
                    106:         cnt = 0;
                    107:         do {
                    108:             rnd_pos(rp, &tp);
                    109:         } until (mvinch(tp.y, tp.x) == FLOOR || cnt++ > 2500);
                    110:         mvaddch(tp.y, tp.x, GOLD);
                    111:         obj->o_pos = tp;
                    112:         /*
                    113:          * add in some food to make sure he has enough
                    114:          */
                    115:         item = spec_item(FOOD, 0, 0, 0);
                    116:         obj = OBJPTR(item);
                    117:         attach(lvl_obj, item);
                    118:         do {
                    119:             rnd_pos(rp, &tp);
                    120:         } until (mvinch(tp.y, tp.x) == FLOOR || cnt++ > 2500);
                    121:         mvaddch(tp.y, tp.x, FOOD);
                    122:         obj->o_pos = tp;
                    123:
                    124:         /* it doesn't mater if it's a treasure maze or a normal maze,
                    125:          * more than enough monsters will be genned.
                    126:          */
                    127:         least = rnd(11)+5;
                    128:         if (least < 6) {
                    129:         least = 7;
                    130:         treas = FALSE;
                    131:     }
                    132:     else treas = TRUE;
                    133:         genmonsters(least, treas);
                    134:
                    135:         /* sometimes they're real angry */
                    136:         if (rnd(100) < 65) {
                    137:             /* protect the good charactors */
                    138:             if (player.t_ctype == C_PALADIN ||
                    139:                 player.t_ctype == C_RANGER  || player.t_ctype == C_MONK) {
                    140:                 aggravate(TRUE, FALSE);
                    141:             }
                    142:             else {
                    143:                 aggravate(TRUE, TRUE);
                    144:             }
                    145:         }
                    146: }
                    147:
                    148: /*
                    149:  * draw_maze:
                    150:  *      Generate and draw the maze on the screen
                    151:  */
                    152:
                    153: static
                    154: void
                    155: draw_maze(void)
                    156: {
                    157:         reg int i, j, more;
                    158:         reg char *ptr;
                    159:
                    160:         maze_lines = (lines - 3) / 2;
                    161:         maze_cols = (cols - 1) / 2;
                    162:         maze_bits = ALLOC((lines - 3) * (cols - 1));
                    163:         maze_frontier = ALLOC(maze_lines * maze_cols);
                    164:         ptr = maze_frontier;
                    165:         while (ptr < (maze_frontier + (maze_lines * maze_cols)))
                    166:                 *ptr++ = TRUE;
                    167:         for (i = 0; i < lines - 3; i++) {
                    168:                 for (j = 0; j < cols - 1; j++) {
                    169:                         if (i % 2 == 1 && j % 2 == 1)
                    170:                                 *moffset(i, j) = FALSE;         /* floor */
                    171:                         else
                    172:                                 *moffset(i, j) = TRUE;          /* wall */
                    173:                 }
                    174:         }
                    175:         for (i = 0; i < maze_lines; i++) {
                    176:                 for (j = 0; j < maze_cols; j++) {
                    177:                         do
                    178:                                 more = findcells(i,j);
                    179:                         while(more != 0);
                    180:                 }
                    181:         }
                    182:         crankout();
                    183:         FREE(maze_frontier);
                    184:         FREE(maze_bits);
                    185: }
                    186:
                    187: /*
                    188:  * findcells:
                    189:  *      Figure out cells to open up
                    190:  */
                    191:
                    192: static int
                    193: findcells(int y, int x)
                    194: {
                    195:         reg int rtpos, i;
                    196:
                    197:         *foffset(y, x) = FALSE;
                    198:         b_cells.num_pos = 0;
                    199:         if (y < maze_lines - 1) {                               /* look below */
                    200:                 if (*foffset(y + 1, x)) {
                    201:                         b_cells.conn[b_cells.num_pos].y_pos = y + 1;
                    202:                         b_cells.conn[b_cells.num_pos].x_pos = x;
                    203:                         b_cells.num_pos += 1;
                    204:                 }
                    205:         }
                    206:         if (y > 0) {                                    /* look above */
                    207:                 if (*foffset(y - 1, x)) {
                    208:                         b_cells.conn[b_cells.num_pos].y_pos = y - 1;
                    209:                         b_cells.conn[b_cells.num_pos].x_pos = x;
                    210:                         b_cells.num_pos += 1;
                    211:
                    212:                 }
                    213:         }
                    214:         if (x < maze_cols - 1) {                                /* look right */
                    215:                 if (*foffset(y, x + 1)) {
                    216:                         b_cells.conn[b_cells.num_pos].y_pos = y;
                    217:                         b_cells.conn[b_cells.num_pos].x_pos = x + 1;
                    218:                         b_cells.num_pos += 1;
                    219:                 }
                    220:         }
                    221:         if (x > 0) {                                    /* look left */
                    222:                 if (*foffset(y, x - 1)) {
                    223:                         b_cells.conn[b_cells.num_pos].y_pos = y;
                    224:                         b_cells.conn[b_cells.num_pos].x_pos = x - 1;
                    225:                         b_cells.num_pos += 1;
                    226:
                    227:                 }
                    228:         }
                    229:         if (b_cells.num_pos == 0)               /* no neighbors available */
                    230:                 return 0;
                    231:         else {
                    232:                 i = rnd(b_cells.num_pos);
                    233:                 rtpos = b_cells.num_pos - 1;
                    234:                 rmwall(b_cells.conn[i].y_pos, b_cells.conn[i].x_pos, y, x);
                    235:                 return rtpos;
                    236:         }
                    237: }
                    238:
                    239: /*
                    240:  * foffset:
                    241:  *      Calculate memory address for frontier
                    242:  */
                    243:
                    244: static char *
                    245: foffset(int y, int x)
                    246: {
                    247:
                    248:         return (maze_frontier + (y * maze_cols) + x);
                    249: }
                    250:
                    251:
                    252: /*
                    253:  * Maze_view:
                    254:  *      Returns true if the player can see the specified location within
                    255:  *      the confines of a maze (within one column or row)
                    256:  */
                    257:
                    258: bool
                    259: maze_view(int y, int x)
                    260: {
                    261:     register int start, goal, delta, ycheck = 0, xcheck = 0, absy, absx, see_radius;
                    262:     register bool row;
                    263:
                    264:     /* Get the absolute value of y and x differences */
                    265:     absy = hero.y - y;
                    266:     absx = hero.x - x;
                    267:     if (absy < 0) absy = -absy;
                    268:     if (absx < 0) absx = -absx;
                    269:
                    270:     /* If we are standing in a wall, we can see a bit more */
                    271:     switch (winat(hero.y, hero.x)) {
                    272:         case VERTWALL:
                    273:         case HORZWALL:
                    274:         case WALL:
                    275:         case SECRETDOOR:
                    276:         case DOOR:
                    277:             see_radius = 2;
                    278:         otherwise:
                    279:             see_radius = 1;
                    280:     }
                    281:
                    282:     /* Must be within one or two rows or columns */
                    283:     if (absy > see_radius && absx > see_radius) return(FALSE);
                    284:
                    285:     if (absx > see_radius) {            /* Go along row */
                    286:         start = hero.x;
                    287:         goal = x;
                    288:         ycheck = hero.y;
                    289:         row = TRUE;
                    290:     }
                    291:     else {                      /* Go along column */
                    292:         start = hero.y;
                    293:         goal = y;
                    294:         xcheck = hero.x;
                    295:         row = FALSE;
                    296:     }
                    297:
                    298:     if (start <= goal) delta = 1;
                    299:     else delta = -1;
                    300:
                    301:     /* Start one past where we are standing */
                    302:     if (start != goal) start += delta;
                    303:
                    304:     /* If we are in a wall, we want to look in the area outside the wall */
                    305:     if (see_radius > 1) {
                    306:         if (row) {
                    307:             /* See if above us it okay first */
                    308:             switch (winat(ycheck, start)) {
                    309:                 case VERTWALL:
                    310:                 case HORZWALL:
                    311:                 case WALL:
                    312:                 case DOOR:
                    313:                 case SECRETDOOR:
                    314:                     /* No good, try one up */
                    315:                     if (y > hero.y) ycheck++;
                    316:                     else ycheck--;
                    317:                 otherwise:
                    318:                     see_radius = 1;     /* Just look straight over the row */
                    319:             }
                    320:         }
                    321:         else {
                    322:             /* See if above us it okay first */
                    323:             switch (winat(start, xcheck)) {
                    324:                 case VERTWALL:
                    325:                 case HORZWALL:
                    326:                 case WALL:
                    327:                 case DOOR:
                    328:                 case SECRETDOOR:
                    329:                     /* No good, try one over */
                    330:                     if (x > hero.x) xcheck++;
                    331:                     else xcheck--;
                    332:                 otherwise:
                    333:                     see_radius = 1;     /* Just look straight up the column */
                    334:             }
                    335:         }
                    336:     }
                    337:
                    338:     /* Check boundary again */
                    339:     if (absy > see_radius && absx > see_radius) return(FALSE);
                    340:
                    341:     while (start != goal) {
                    342:         if (row) xcheck = start;
                    343:         else     ycheck = start;
                    344:
                    345:         if (xcheck < 0 || ycheck < 0)
                    346:             return FALSE;
                    347:         switch (winat(ycheck, xcheck)) {
                    348:             case VERTWALL:
                    349:             case HORZWALL:
                    350:             case WALL:
                    351:             case DOOR:
                    352:             case SECRETDOOR:
                    353:                 return(FALSE);
                    354:         }
                    355:         start += delta;
                    356:     }
                    357:     return(TRUE);
                    358: }
                    359:
                    360:
                    361: /*
                    362:  * moffset:
                    363:  *      Calculate memory address for bits
                    364:  */
                    365:
                    366: static char *
                    367: moffset(int y, int x)
                    368: {
                    369:     return (maze_bits + (y * (cols - 1)) + x);
                    370: }
                    371:
                    372: /*
                    373:  * rmwall:
                    374:  *      Removes appropriate walls from the maze
                    375:  */
                    376: static
                    377: void
                    378: rmwall(int newy, int newx, int oldy, int oldx)
                    379: {
                    380:         reg int xdif,ydif;
                    381:
                    382:         xdif = newx - oldx;
                    383:         ydif = newy - oldy;
                    384:
                    385:         *moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE;
                    386:         findcells(newy, newx);
                    387: }
                    388:

CVSweb