Annotation of researchv9/jtools/src/demo/pacman/monsters.c, revision 1.1

1.1     ! root        1: /*----------------------------------------------------------------------*/
        !             2: /*                                                                     */
        !             3: /*     PACMAN for BBN BitGraphs                                        */
        !             4: /*                                                                     */
        !             5: /*               File: monsters.c68                                    */
        !             6: /*           Contents: monster definitions and manipulation routines   */
        !             7: /*             Author: Bob Brown (rlb)                                 */
        !             8: /*                     Purdue CS                                       */
        !             9: /*               Date: May, 1982                                       */
        !            10: /*        Description: Initialization, movement, drawing routines.     */
        !            11: /*                     Interacts with several pacman routines.         */
        !            12: /*                                                                     */
        !            13: /*----------------------------------------------------------------------*/
        !            14: 
        !            15: #include "style.h"
        !            16: #include "pacman.h"
        !            17: 
        !            18: /*
        !            19: **  Monster structure initialization
        !            20: **
        !            21: ** The following lists the static part of the monster structures, in the order
        !            22: ** that they leave the stable.
        !            23: */
        !            24: 
        !            25: monster Monster[MAXMONSTER] = {
        !            26:        { 45, 36, MOVEUP,     0,    5,   -10 },
        !            27:        { 45, 41, MOVEUP,    24,    0,   -20 }, /* fast, but stupid */
        !            28:        { 39, 33, MOVEDOWN,  52,    9,     0 },
        !            29:        { 39, 48, MOVEDOWN,  80,   13,     5 }, /* slow, but methodical */
        !            30: };
        !            31: 
        !            32: /*
        !            33: ** monnew - create a new set of monsters.
        !            34: **
        !            35: **     Called once at the beginning of a game.
        !            36: */
        !            37: 
        !            38: monnew()
        !            39: {
        !            40:        register monster *mptr;
        !            41:        for ( mptr=Monster ; mptr < &Monster[MAXMONSTER] ; mptr++ )
        !            42:                mptr->time = Monbase + mptr->inittime;
        !            43: }
        !            44: 
        !            45: /*
        !            46: ** moninit - reinitialize the monsters.
        !            47: **
        !            48: **     Called at the beginning of each wave or when Pacman dies.
        !            49: */
        !            50: 
        !            51: moninit()
        !            52: {
        !            53:        register monster *mptr;
        !            54:        for ( mptr=Monster ; mptr < &Monster[MAXMONSTER] ; mptr++ ) {
        !            55:                if ( mptr == Monster ) {
        !            56:                        mptr->row = STARTROW;
        !            57:                        mptr->col = STARTCOL;
        !            58:                        mptr->dir = MOVERIGHT;
        !            59:                        mptr->movestate = ROAMING;
        !            60:                } else {
        !            61:                        mptr->row = mptr->initrow;
        !            62:                        mptr->col = mptr->initcol;
        !            63:                        mptr->dir = mptr->initdir;
        !            64:                        mptr->movestate = STABLED;
        !            65:                }
        !            66:                mptr->mrow = SCtoMZ(mptr->row);
        !            67:                mptr->mcol = SCtoMZ(mptr->col);
        !            68:                mptr->state = DANGEROUS;
        !            69:                mptr->delay = mptr->initdelay;
        !            70:                mptr->font = MONSTERCHAR[0];
        !            71:                Monseeking = FALSE;
        !            72:                mondraw(mptr);
        !            73:                eladd(mptr->time+STARTDELAY,monmove,(char *)mptr);
        !            74:        }
        !            75: }
        !            76: /*
        !            77: ** monfont - change the font of the monsters.
        !            78: **
        !            79: **     Called when Pacman swallows a pill or starts getting weaker.
        !            80: */
        !            81: 
        !            82: monfont(chr)
        !            83: char chr;
        !            84: {
        !            85:        register monster *mptr;
        !            86:        for ( mptr=Monster ; mptr < &Monster[MAXMONSTER] ; mptr++ ) {
        !            87:                monfont1(mptr,chr);
        !            88:        }
        !            89: }
        !            90: 
        !            91: monfont1(mptr,chr)
        !            92: register monster *mptr;
        !            93: char chr;
        !            94: {
        !            95:                mondraw(mptr);
        !            96:                mptr->font = chr;
        !            97:                mondraw(mptr);
        !            98: }
        !            99: /*
        !           100: ** moncomp - turn on/off (i.e. complement) all the monsters
        !           101: */
        !           102: 
        !           103: moncomp()
        !           104: {
        !           105:        register monster *mptr;
        !           106:        for ( mptr=Monster ; mptr < &Monster[MAXMONSTER] ; mptr++ )
        !           107:                mondraw(mptr);
        !           108: }
        !           109: 
        !           110: /*
        !           111: ** mondraw - complement a single monster
        !           112: */
        !           113: 
        !           114: mondraw(mptr)
        !           115: register monster *mptr;
        !           116: {
        !           117:        blt40(mptr->font,mptr->row,mptr->col,INVERT);
        !           118: }
        !           119: 
        !           120: /*
        !           121: ** Move a particular monster
        !           122: **
        !           123: ** This routine moves a given monster based its current movestate
        !           124: */
        !           125: 
        !           126: int
        !           127: monmove(mptr)
        !           128: register monster *mptr;
        !           129: {
        !           130:        register move *newmove;
        !           131:        int newdelay;
        !           132:        /*
        !           133:        ** Motion depends on the monster movestate
        !           134:        */
        !           135:        mondraw(mptr);
        !           136:        switch ( mptr->movestate ) {
        !           137:        /*
        !           138:        ** In the center box - won't come out until time delay elapses and
        !           139:        ** the pacman isn't dangerous (fixes ambush bug).
        !           140:        */
        !           141:        case STABLED:
        !           142:                newmove = bounce(mptr);
        !           143:                if ( mptr->delay > 0 )
        !           144:                        mptr->delay = max(mptr->delay-1,0);
        !           145:                else
        !           146:                        mptr->movestate = LEAVING;
        !           147:                break;
        !           148:        case LEAVING:
        !           149:                newmove = tostart(mptr);
        !           150:                if ( newmove->row == STARTROW && newmove->col == STARTCOL )
        !           151:                        mptr->movestate = ROAMING;
        !           152:                break;
        !           153:        /*
        !           154:        ** If roaming about, switch to seeking if someone sees him and fall
        !           155:        ** into seeking code.
        !           156:        */
        !           157:        case ROAMING:
        !           158:                if ( Monseeking )
        !           159:                        mptr->movestate = SEEKING;
        !           160:                else if ( seeshim(mptr) ) {
        !           161:                        Monseeking = TRUE;
        !           162:                        mptr->movestate = SEEKING;
        !           163:                } else {
        !           164:                        newmove = dumbmove(mptr);
        !           165:                        break;
        !           166:                }
        !           167:        /*
        !           168:        **  When seeking the pacman, they may always make a random move.  if the
        !           169:        **  Pacman is powerful, then they move away if edible, else random.
        !           170:        */
        !           171:        case SEEKING:
        !           172:                if ( grand(0,100) < Seekprob+mptr->bonus && !Pacman.safe && !(Pacman.power>0 && mptr->state==DANGEROUS))
        !           173:                        newmove = seekmove(mptr);
        !           174:                else
        !           175:                        newmove = dumbmove(mptr);
        !           176:                break;
        !           177:        case HOMING:
        !           178:                newmove = todoor(mptr);
        !           179:                if ( newmove->row == STARTROW && newmove->col == STARTCOL )
        !           180:                        mptr->movestate = HOMING2;
        !           181:                break;
        !           182:        case HOMING2:
        !           183:                newmove = tostable(mptr);
        !           184:                if ( newmove->row==mptr->initrow && newmove->col==mptr->initcol ) {
        !           185:                        mptr->movestate = STABLED;
        !           186:                        mptr->state = DANGEROUS;
        !           187:                        mptr->font = MONSTERCHAR[mptr->initdir];
        !           188:                        newmove->dir = mptr->initdir;
        !           189:                        mptr->delay = Pacman.power+(mptr-Monster)*24;
        !           190:                }
        !           191:                break;
        !           192:        }
        !           193:        /*
        !           194:        ** Move the monster on the screen
        !           195:        */
        !           196:        mptr->row = newmove->row;
        !           197:        mptr->col = newmove->col;
        !           198:        mptr->dir = newmove->dir;
        !           199:        mptr->mrow = SCtoMZ(mptr->row);
        !           200:        mptr->mcol = SCtoMZ(mptr->col);
        !           201:        if ( mptr->state == DANGEROUS )
        !           202:                mptr->font = MONSTERCHAR[mptr->dir];
        !           203:        mondraw(mptr);
        !           204:        /*
        !           205:        ** Check for collision with the pacman
        !           206:        */
        !           207:        if ( mptr->state == DANGEROUS && collide(mptr) && Pacman.alive ) {
        !           208:                pacdie();
        !           209:                return;
        !           210:        }
        !           211:        /*
        !           212:        **  The time till next move depends on whether the monster is alive,
        !           213:        **  or is in the slow corridor, or is weakened by the pacman's power.
        !           214:        */
        !           215:        newdelay = mptr->state==DEAD ? EYESDELAY :
        !           216:                   inslow(mptr->row,mptr->col) ? Pacman.time+SLOWDELTA :
        !           217:                   mptr->time+Pacman.power*POWERDELAY;
        !           218: 
        !           219:        eladd(newdelay,monmove,mptr);
        !           220: }
        !           221: /*
        !           222: ** Simplest of all possible move commands - chooses random direction
        !           223: */
        !           224: move *
        !           225: dumbmove(mptr)
        !           226: register monster *mptr;
        !           227: {
        !           228:        register int moves;
        !           229:        static move movelist[4];
        !           230:        if ( !aligns(mptr->row, mptr->col) ) {
        !           231:                onestep(mptr->row,mptr->col,mptr->dir,&movelist[0]);
        !           232:                return movelist;
        !           233:        }
        !           234:        moves=compmoves(mptr->row,mptr->col,movelist,mptr->dir,FALSE);
        !           235:        if (moves == 1 )
        !           236:                return movelist;
        !           237:        return &movelist[grand(0,moves-1)];
        !           238: }
        !           239: /*
        !           240: **  Direction seeking Monster move
        !           241: */
        !           242: move *
        !           243: seekmove(mptr)
        !           244: register monster *mptr;
        !           245: {
        !           246:        register int moves;
        !           247:        static move movelist[4];
        !           248:        if ( !aligns(mptr->row, mptr->col) ) {
        !           249:                onestep(mptr->row,mptr->col,mptr->dir,&movelist[0]);
        !           250:                return movelist;
        !           251:        }
        !           252:        /*
        !           253:        ** Monsters can reverse once when the pacman swallows a pill -
        !           254:        ** Should save it until the pacman is close (unimplemented).
        !           255:        */
        !           256:        if ( mptr->canreverse ) {
        !           257:                moves=compmoves(mptr->row,mptr->col,movelist,0,FALSE);
        !           258:                mptr->canreverse = FALSE;
        !           259:        } else
        !           260:                moves=compmoves(mptr->row,mptr->col,movelist,mptr->dir,FALSE);
        !           261:        if (moves == 1 )
        !           262:                return movelist;
        !           263:        if ( mptr->state == EDIBLE )
        !           264:                return furthest(movelist,moves,Pacman.row,Pacman.col);
        !           265:        return closest(movelist,moves,Pacman.row,Pacman.col);
        !           266: }
        !           267: /*
        !           268: **  Compute all the possible moves a monster can make.
        !           269: **
        !           270: */
        !           271: 
        !           272: compmoves(mrow, mcol, list, curdir, doorok)
        !           273: int mrow, mcol, curdir;
        !           274: register move *list;
        !           275: bool doorok;
        !           276: {
        !           277:        register int moves, i;
        !           278:        /*
        !           279:        **  The list of moves will not include the direction opposite
        !           280:        **  of curdir, if it is nonzero.  This statement computes the
        !           281:        **  opposite direction effeciently.
        !           282:        */
        !           283:        if ( curdir > 0 )
        !           284:                curdir = ((curdir+1)&3)+1;
        !           285:        moves = 0;
        !           286:        for ( i=1 ; i<=4 ; i++ ) {
        !           287:                if ( i == curdir )
        !           288:                        continue;
        !           289:                onestep(mrow,mcol,i,list);
        !           290:                if ( (doorok && hitdoor(list->row,list->col)) ||
        !           291:                    !(hitwall(list->row,list->col,i)||(i==MOVEUP&&hitblk(list->row,list->col))) ) {
        !           292:                        list++;
        !           293:                        moves++;
        !           294:                }
        !           295:        }
        !           296:        return moves;
        !           297: }
        !           298: onestep(mrow, mcol, dir, list)
        !           299: register int mrow, mcol, dir;
        !           300: register move *list;
        !           301: {
        !           302:        list->col = mcol;
        !           303:        list->row = mrow;
        !           304:        list->dir = dir;
        !           305:        switch ( dir ) {
        !           306:        case MOVERIGHT:
        !           307:                list->col++;
        !           308:                break;
        !           309:        case MOVEUP:
        !           310:                list->row--;
        !           311:                break;
        !           312:        case MOVELEFT:
        !           313:                list->col--;
        !           314:                break;
        !           315:        case MOVEDOWN:
        !           316:                list->row++;
        !           317:                break;
        !           318:        }
        !           319:        if ( list->col < 0 )
        !           320:                list->col += MZtoSC(MAZECOLS);
        !           321:        if ( list->col >= MZtoSC(MAZECOLS) )
        !           322:                list->col = 0;
        !           323: }
        !           324: /*
        !           325: ** Choose the move from a list the goes in the direction closest to a
        !           326: ** given point.
        !           327: **
        !           328: **   SCREEN COORDINATES
        !           329: */
        !           330: move *
        !           331: closest(list,moves,row,col)
        !           332: register move *list;
        !           333: register int moves;
        !           334: register int row, col;
        !           335: {
        !           336:        register move *lptr;
        !           337:        int dist, diff, diffr, diffc;
        !           338:        dist = 0x7fff;
        !           339:        for ( ; moves>0 ; moves-- ) {
        !           340:                diffr = iabs(row-list->row);
        !           341:                diffc = iabs(col-list->col);
        !           342:                diff = max(diffr,diffc);
        !           343:                if ( diff < dist ) {
        !           344:                        lptr = list;
        !           345:                        dist = diff;
        !           346:                }
        !           347:                list++;
        !           348:        }
        !           349:        return lptr;
        !           350: }
        !           351: move *
        !           352: furthest(list,moves,row,col)
        !           353: register move *list;
        !           354: register int moves;
        !           355: register int row, col;
        !           356: {
        !           357:        register move *lptr;
        !           358:        int dist, diff, diffr, diffc;
        !           359:        dist = -1;
        !           360:        for ( ; moves>0 ; moves-- ) {
        !           361:                diffr = iabs(row-list->row);
        !           362:                diffc = iabs(col-list->col);
        !           363:                diff = min(diffr,diffc);
        !           364:                if ( diff > dist ) {
        !           365:                        lptr = list;
        !           366:                        dist = diff;
        !           367:                }
        !           368:                list++;
        !           369:        }
        !           370:        return lptr;
        !           371: }
        !           372: 
        !           373: /*
        !           374: ** Check if a monster "sees" the pacman
        !           375: */
        !           376: seeshim(mptr)
        !           377: register monster *mptr;
        !           378: {
        !           379:        register int rdiff, cdiff;
        !           380:        register int i;
        !           381:        rdiff = abs(mptr->row - Pacman.row);
        !           382:        cdiff = abs(mptr->col - Pacman.col);
        !           383:        switch ( mptr->dir ) {
        !           384:        case MOVERIGHT:
        !           385:                if ( rdiff > 3 || mptr->col > Pacman.col )
        !           386:                        return FALSE;
        !           387:                for ( i=mptr->mcol ; i<Pacman.mcol ; i++ )
        !           388:                        if ( (Board[mptr->mrow][i]&TYPEMASK) <= WALLMAX )
        !           389:                                return FALSE;
        !           390:                return TRUE;
        !           391:        case MOVEUP:
        !           392:                if ( cdiff > 3 || mptr->row < Pacman.row )
        !           393:                        return FALSE;
        !           394:                for ( i=mptr->mrow ; i>Pacman.mrow ; i-- )
        !           395:                        if ( (Board[i][mptr->mcol]&TYPEMASK) <= WALLMAX )
        !           396:                                return FALSE;
        !           397:                return TRUE;
        !           398:        case MOVELEFT:
        !           399:                if ( rdiff > 3 || mptr->col < Pacman.col )
        !           400:                        return FALSE;
        !           401:                for ( i=mptr->mcol ; i>Pacman.mcol ; i-- )
        !           402:                        if ( (Board[mptr->mrow][i]&TYPEMASK) <= WALLMAX )
        !           403:                                return FALSE;
        !           404:                return TRUE;
        !           405:        case MOVEDOWN:
        !           406:                if ( cdiff > 3 || mptr->row > Pacman.row )
        !           407:                        return FALSE;
        !           408:                for ( i=mptr->mrow ; i<Pacman.mrow ; i++ )
        !           409:                        if ( (Board[i][mptr->mcol]&TYPEMASK) <= WALLMAX )
        !           410:                                return FALSE;
        !           411:                return TRUE;
        !           412:        }
        !           413: }
        !           414: 
        !           415: /*
        !           416: ** Bounce the monster around in the stable
        !           417: */
        !           418: move *
        !           419: bounce(mptr)
        !           420: register monster *mptr;
        !           421: {
        !           422:        static move newmove;
        !           423:        onestep(mptr->row, mptr->col, mptr->dir, &newmove);
        !           424:        if ( hitwall(newmove.row, newmove.col,mptr->dir) ) {
        !           425:                mptr->dir = ((mptr->dir+1)&3)+1;
        !           426:                onestep(mptr->row, mptr->col, mptr->dir, &newmove);
        !           427:        }
        !           428:        return &newmove;
        !           429: }
        !           430: /*
        !           431: ** move a monster closer to the starting position
        !           432: */
        !           433: move *
        !           434: tostart(mptr)
        !           435: register monster *mptr;
        !           436: {
        !           437:        static move movelist[4];
        !           438:        int moves;
        !           439:        moves = compmoves(mptr->row, mptr->col, movelist, mptr->dir, TRUE);
        !           440:        if ( mptr->col != STARTCOL )
        !           441:                return closest(movelist,moves, mptr->row, STARTCOL);
        !           442:        return closest(movelist,moves, STARTROW, STARTCOL);
        !           443: }
        !           444: /*
        !           445: ** Move the monster towards the door
        !           446: */
        !           447: move *
        !           448: todoor(mptr)
        !           449: register monster *mptr;
        !           450: {
        !           451:        static move movelist[4];
        !           452:        int moves;
        !           453:        if ( !aligns(mptr->row, mptr->col) ) {
        !           454:                onestep(mptr->row,mptr->col,mptr->dir,&movelist[0]);
        !           455:                return movelist;
        !           456:        }
        !           457:        moves = compmoves(mptr->row, mptr->col, movelist, mptr->dir, FALSE);
        !           458:        return closest(movelist,moves, STARTROW, STARTCOL);
        !           459: 
        !           460: }
        !           461: /*
        !           462: ** move a monster back to the stable
        !           463: */
        !           464: move *
        !           465: tostable(mptr)
        !           466: register monster *mptr;
        !           467: {
        !           468:        static move movelist[4];
        !           469:        int moves;
        !           470:        moves = compmoves(mptr->row, mptr->col, movelist, mptr->dir, TRUE);
        !           471:        if ( mptr->row!=mptr->initrow )
        !           472:                return closest(movelist,moves, mptr->initrow, mptr->col);
        !           473:        return closest(movelist,moves, mptr->initrow, mptr->initcol);
        !           474: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.