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

Annotation of early-roguelike/arogue5/maze.c, Revision 1.1

1.1     ! rubenllo    1: /*
        !             2:  * maze
        !             3:  *
        !             4:  * Advanced Rogue
        !             5:  * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Based on "Super-Rogue"
        !             9:  * Copyright (C) 1984 Robert D. Kindelberger
        !            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:
        !            24: struct bordercells {
        !            25:        unsigned char num_pos;  /* number of frontier cells next to you */
        !            26:        struct cell conn[4];    /* the y,x position of above cell */
        !            27: } border_cells;
        !            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(10) + 1);          /* 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) < 10) {                    /* 10% for treasure maze */
        !           126:                treas = TRUE;
        !           127:                least = 6;
        !           128:                debug("treasure maze");
        !           129:        }
        !           130:        else {                                  /* normal maze level */
        !           131:                least = 1;
        !           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 = 0, xcheck = 0, absy, absx, see_radius;
        !           248:     register bool row;
        !           249:     char ch;   /* What we are standing on (or near) */
        !           250:
        !           251:     /* Get the absolute value of y and x differences */
        !           252:     absy = hero.y - y;
        !           253:     absx = hero.x - x;
        !           254:     if (absy < 0) absy = -absy;
        !           255:     if (absx < 0) absx = -absx;
        !           256:
        !           257:     /* If we are standing in a wall, we can see a bit more */
        !           258:     switch (ch = CCHAR( winat(hero.y, hero.x) )) {
        !           259:        case '|':
        !           260:        case '-':
        !           261:        case WALL:
        !           262:        case SECRETDOOR:
        !           263:        case DOOR:
        !           264:            see_radius = 2;
        !           265:        otherwise:
        !           266:            see_radius = 1;
        !           267:     }
        !           268:
        !           269:     /* Must be within one or two rows or columns */
        !           270:     if (absy > see_radius && absx > see_radius) return(FALSE);
        !           271:
        !           272:     if (absx > see_radius) {           /* Go along row */
        !           273:        start = hero.x;
        !           274:        goal = x;
        !           275:        ycheck = hero.y;
        !           276:        row = TRUE;
        !           277:     }
        !           278:     else {                     /* Go along column */
        !           279:        start = hero.y;
        !           280:        goal = y;
        !           281:        xcheck = hero.x;
        !           282:        row = FALSE;
        !           283:     }
        !           284:
        !           285:     if (start <= goal) delta = 1;
        !           286:     else delta = -1;
        !           287:
        !           288:     /* Start one past where we are standing */
        !           289:     if (start != goal) start += delta;
        !           290:
        !           291:     /* If we are in a wall, we want to look in the area outside the wall */
        !           292:     if (see_radius > 1) {
        !           293:        if (row) {
        !           294:            /* See if above us it okay first */
        !           295:            switch (winat(ycheck, start)) {
        !           296:                case '|':
        !           297:                case '-':
        !           298:                case WALL:
        !           299:                case DOOR:
        !           300:                case SECRETDOOR:
        !           301:                    /* No good, try one up */
        !           302:                    if (y > hero.y) ycheck++;
        !           303:                    else ycheck--;
        !           304:                otherwise:
        !           305:                    see_radius = 1;     /* Just look straight over the row */
        !           306:            }
        !           307:        }
        !           308:        else {
        !           309:            /* See if above us it okay first */
        !           310:            switch (winat(start, xcheck)) {
        !           311:                case '|':
        !           312:                case '-':
        !           313:                case WALL:
        !           314:                case DOOR:
        !           315:                case SECRETDOOR:
        !           316:                    /* No good, try one over */
        !           317:                    if (x > hero.x) xcheck++;
        !           318:                    else xcheck--;
        !           319:                otherwise:
        !           320:                    see_radius = 1;     /* Just look straight up the column */
        !           321:            }
        !           322:        }
        !           323:     }
        !           324:
        !           325:     /* Check boundary again */
        !           326:     if (absy > see_radius && absx > see_radius) return(FALSE);
        !           327:
        !           328:     while (start != goal) {
        !           329:        if (row) xcheck = start;
        !           330:        else ycheck = start;
        !           331:        switch (winat(ycheck, xcheck)) {
        !           332:            case '|':
        !           333:            case '-':
        !           334:            case WALL:
        !           335:            case DOOR:
        !           336:            case SECRETDOOR:
        !           337:                return(FALSE);
        !           338:        }
        !           339:        start += delta;
        !           340:     }
        !           341:     return(TRUE);
        !           342: }
        !           343:
        !           344: 
        !           345: /*
        !           346:  * moffset:
        !           347:  *     Calculate memory address for bits
        !           348:  */
        !           349: char *
        !           350: moffset(int y, int x)
        !           351: {
        !           352:
        !           353:        return (bits + (y * (COLS - 1)) + x);
        !           354: }
        !           355:
        !           356:
        !           357:
        !           358: 
        !           359: /*
        !           360:  * rmwall:
        !           361:  *     Removes appropriate walls from the maze
        !           362:  */
        !           363: void
        !           364: rmwall(int newy, int newx, int oldy, int oldx)
        !           365: {
        !           366:        reg int xdif,ydif;
        !           367:
        !           368:        xdif = newx - oldx;
        !           369:        ydif = newy - oldy;
        !           370:
        !           371:        *moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE;
        !           372:        findcells(newy, newx);
        !           373: }

CVSweb