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

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

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

CVSweb