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