[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     ! 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