Annotation of coherent/d/usr/games/pacman/pac.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * pacman
        !             3:  * dal 1982
        !             4:  * steve 1/24/90 added ndelay for reasonable slowness on AT
        !             5:  * steve 10/4/90 kludged to make speed setting slightly more cogent
        !             6:  * steve 10/9/90 made arrow keys work
        !             7:  * steve 10/10/90 added -c option to work on video cards
        !             8:  * steve 6/10/92 added #if _I386 conditionalization for COH386;
        !             9:  *     cleaned up a few of the more offensive pointer/int fubars of dal.
        !            10:  *     The i386 version must be setuid sys, so it can read /dev/mem.
        !            11:  */
        !            12: 
        !            13: #include "term.c"
        !            14: #include "io.c"
        !            15: 
        !            16: #if    _I386
        !            17: #define        SCRBASE_M       0xB0000         /* monochrome screen base address */
        !            18: #define        SCRBASE_C       0xB8000         /* color board screen base address */
        !            19: #else
        !            20: #define        SCRBASE_M       0xB000          /* monochrome screen base segment */
        !            21: #define        SCRBASE_C       0xB800          /* color board screen base segment */
        !            22: #endif
        !            23: 
        !            24: #define        rand()  ((rn+=rn+((((rn<<0^rn<<1^rn<<8^rn<<9)>>15)^1)&1))&1)
        !            25: int            rn;
        !            26: #define        track() (board>1)
        !            27: #define        nprox() (board>2? (board-3)/2+5 : 0)
        !            28: #define        F_VERT  22
        !            29: #define        F_HORZ  63
        !            30: #define        F_HHID  2
        !            31: #define        F_HOFF  ((80-F_HORZ)/2)
        !            32: #define        F_VOFF  ((24-F_VERT)/2)
        !            33: #define        S_BP    10000
        !            34: #define        S_PN    3
        !            35: #define        S_GH    200
        !            36: #define        S_FD    10
        !            37: #define        S_EN    50
        !            38: /*
        !            39: #define        S_FR    (board<5? (board-1)*200+100 : (board-4)*1000)
        !            40: */
        !            41: #define        S_FR    ((board-1)*200+100)
        !            42: #define        F_GH    0
        !            43: #define        F_PC    4
        !            44: #define        F_FR    5
        !            45: #define        F_BN    6
        !            46: #define        F_FD    7
        !            47: #define        F_EN    8
        !            48: #define        F_DR    9
        !            49: #define        F_TN    10
        !            50: #define        F_WL    11
        !            51: #define        F_BC    12
        !            52: #define        F_BMSK  ((1<<F_BC)-1)
        !            53: #define        F_GMSK  (((1<<F_GH+4)-1)&~((1<<F_GH+0)-1))
        !            54: #define        G_ETIM  24
        !            55: #define        G_BTIM  8
        !            56: #define        G_TMQN  8
        !            57: #define        G_TOFF(n)       (5+(n)*G_TMQN)
        !            58: enum   {G_ERAS, G_WRIT, G_MOVE, G_BLUE, G_INIT};
        !            59: #define        E_TMQN  16
        !            60: #define        E_TOFF  1
        !            61: #define        P_TMQN  (9*(2-P_HALF))
        !            62: #define        P_TOFF  0
        !            63: enum   {P_ERAS, P_WRIT, P_MOVE, P_UPDI, P_INIT};
        !            64: #define        axis(v) ((v)&1)
        !            65: #define        incr(v) (1-((v)&2))
        !            66: #define        hm(v)   (axis(v)==0)
        !            67: #define        vm(v)   (axis(v)!=0)
        !            68: #define        om(v)   ((v)^2)
        !            69: 
        !            70: int            ndelay = 10;
        !            71: int            limit[2] = {F_HORZ-2, F_VERT-1};
        !            72: int            edibles;
        !            73: int            pacmen = S_PN+1;
        !            74: int            stop;
        !            75: int            e_s;
        !            76: long           score;
        !            77: long           bonus;
        !            78: int            board = 1;
        !            79: int            p_p[3];
        !            80: int            p_h[2];
        !            81: int            p_l;
        !            82: int            p_m;
        !            83: int            p_d;
        !            84: int            p_i[3];
        !            85: unsigned       p_n;
        !            86: unsigned       e_n;
        !            87: int            e_k;
        !            88: int            energ[4][2];
        !            89: int            r_s;
        !            90: int            r_t[2];
        !            91: int            r_d;
        !            92: int            r_p[2];
        !            93: int            g_g[2][2];
        !            94: int            g_v[4];
        !            95: struct ghost   {
        !            96:        int             g_p[3];
        !            97:        int             g_q[3];
        !            98:        int             g_h[3];
        !            99:        int             g_s;
        !           100:        int             g_d;
        !           101:        int             g_e;
        !           102:        int             g_f;
        !           103:        int             g_r;
        !           104:        int             g_o;
        !           105:        unsigned        g_n;
        !           106: } ghost[4];
        !           107: 
        !           108: #define        D       (1<<F_DR)
        !           109: #define        E       (1<<F_EN)
        !           110: #define        F       (1<<F_FD)
        !           111: #define        G       (1<<F_GH)
        !           112: #define        P       (1<<F_PC)
        !           113: #define        R       (1<<F_FR)
        !           114: #define        T       (1<<F_TN)
        !           115: #define        W       (1<<F_WL)
        !           116: int    field[F_VERT][F_HORZ] = {
        !           117: {W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W},
        !           118: {W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,W,W},
        !           119: {W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,W,W,0,F,0,W,W},
        !           120: {W,W,W,W,W,0,E,0,W,W,W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,W,W,0,F,0,W,W},
        !           121: {W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0},
        !           122: {W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,0,F,0,W,W,W,0,F,0,W,W,W,W,W,W,W,W},
        !           123: {W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,W,W,W,0,F,0,F,0,F,0,F,0,W,W},
        !           124: {W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,W,W,0,0,0,W,W},
        !           125: {W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,0,0,0,0,0,0,0,0,0,G},
        !           126: {W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,0,0,W,W,W,W,W,W,D,D},
        !           127: {T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,0,F,0,0,0,0,0,0,0,W,W,W,0,G,0,0,G},
        !           128: {W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,0,0,W,W,W,W,W,W,W,W},
        !           129: {W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,0,0,0,0,0,0,0,0,0,R},
        !           130: {W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,0,0,W,W,W,W,W,W,W,W},
        !           131: {W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,W,W},
        !           132: {W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,W,W,0,F,0,W,W},
        !           133: {W,W,W,W,W,0,E,0,F,0,F,0,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,0,P},
        !           134: {W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,F,0,W,W,W,0,F,0,W,W,W,W,W,W,W,W},
        !           135: {W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,W,W,W,0,F,0,F,0,F,0,F,0,W,W},
        !           136: {W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W},
        !           137: {W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0},
        !           138: {W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W}
        !           139: };
        !           140: #undef D
        !           141: #undef E
        !           142: #undef F
        !           143: #undef G
        !           144: #undef P
        !           145: #undef R
        !           146: #undef T
        !           147: #undef W
        !           148: 
        !           149: int    cn[3];
        !           150: unsigned       scrbase = SCRBASE_M;    /* monochrome screen by default */
        !           151: 
        !           152: nc(x, y, z)
        !           153: {
        !           154:        cn[0]=(x);
        !           155:        cn[1]=(y);
        !           156:        cn[2]=(z);
        !           157:        mc(cn);
        !           158:        return (field[cn[1]][cn[0]]);
        !           159: }
        !           160: 
        !           161: mc(p)
        !           162: register *p;
        !           163: {
        !           164:        register a, i;
        !           165: 
        !           166:        a = axis(p[2]);
        !           167:        i = incr(p[2]);
        !           168:        if ((unsigned)(p[a]+=i) > limit[a])
        !           169:                p[a] -= i*(limit[a]+1);
        !           170: }
        !           171: 
        !           172: 
        !           173: main(argc, argv) int argc; char *argv[];
        !           174: {
        !           175:        char c;
        !           176: 
        !           177:        if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'c') {
        !           178:                --argc;
        !           179:                ++argv;
        !           180:                scrbase = SCRBASE_C;            /* color screen if -c */
        !           181:        }
        !           182:        if (argc > 1)
        !           183:                ndelay = atoi(argv[1]);
        !           184:        setup();
        !           185:        map();
        !           186: loop:
        !           187:        cls();
        !           188:        if (argc == 1) {
        !           189:                atrb(s_a);
        !           190:                curs(1, 0);
        !           191:                bufstr("Speed [default ");
        !           192:                dprint((long)ndelay);
        !           193:                bufstr("]? ");
        !           194:                bflush();
        !           195:                inputecho(&c);
        !           196:                if (c == '\n')
        !           197:                        ;               /* take old ndelay, initially 10 */
        !           198:                else if (c < '0' || c > '9')
        !           199:                        goto loop;      /* bogus nachos */
        !           200:                else                    /* input ndelay char by char, ugh */
        !           201:                        for (ndelay = 0; c >= '0' && c <= '9'; inputecho(&c)) {
        !           202:                                ndelay *= 10;
        !           203:                                ndelay += c - '0';
        !           204:                        }
        !           205:                if (c != '\n')
        !           206:                        goto loop;      /* bogus terminator */
        !           207:                curs(1, 0);
        !           208:                bufstr("                         ");
        !           209:                bflush();
        !           210:        }
        !           211:        score = 0;
        !           212:        bonus = S_BP;
        !           213:        curs(1, 0);
        !           214:        bufstr("      ");
        !           215:        while (play())
        !           216:                ++board;
        !           217:        for (;;) {
        !           218:                cls();
        !           219:                atrb(s_a);
        !           220:                curs(1, 0);
        !           221:                bufstr("Your score was ");
        !           222:                dprint(score);
        !           223:                bufstr(" on level ");
        !           224:                bufchr(board + 'A' - 1);
        !           225:                bufstr(" at speed ");
        !           226:                dprint((long)ndelay);
        !           227:                bufchr('.');
        !           228:                curs(2, 0);
        !           229:                bufstr("Do you want to play again [y or n]? ");
        !           230:                bflush();
        !           231:                c = 0;
        !           232:                inputecho(&c);
        !           233:                switch (c) {
        !           234:                case 'Y':
        !           235:                case 'y':
        !           236:                case '\n':
        !           237:                        board = 1;
        !           238:                        edibles = 0;
        !           239:                        pacmen = S_PN+1;
        !           240:                        goto loop;
        !           241:                case 'Q':
        !           242:                case 'q':
        !           243:                case 'N':
        !           244:                case 'n':
        !           245:                        reset();
        !           246:                        exit(0);
        !           247:                }
        !           248:        }
        !           249: }
        !           250: 
        !           251: play()
        !           252: {
        !           253:        register i, j;
        !           254:        register *f;
        !           255:        register k;
        !           256: 
        !           257:        while (pacmen) {
        !           258:                e_n = E_TOFF;
        !           259:                e_k = 0;
        !           260:                r_c[1] = board-1+'A';
        !           261:                if (edibles == 0) {
        !           262:                        f = field;
        !           263:                        for (j=0; j<F_VERT; ++j)
        !           264:                                for (i=0; i<F_HORZ; ++i)
        !           265:                                        if ((*f++&=~(1<<F_BN|1<<F_PC|F_GMSK))
        !           266:                                         &  (1<<F_FD|1<<F_EN))
        !           267:                                                ++edibles;
        !           268:                        plot(0, 0, F_HORZ, F_VERT);
        !           269:                        if (score == 0) {
        !           270:                                pleft();
        !           271:                                --pacmen;
        !           272:                                r_d = edibles/2;
        !           273:                                i = rand();
        !           274:                                r_t[0] = (1+0)*edibles/(2+i);
        !           275:                                i = rand();
        !           276:                                r_t[1] = (2+i)*edibles/(3+i);
        !           277:                                curs(1, 0);
        !           278:                                atrb(s_a);
        !           279:                                bufchr('0');
        !           280:                        }
        !           281:                }
        !           282:                pacman(P_INIT, 0);
        !           283:                pacman(P_UPDI, 0);
        !           284:                ghosts(G_INIT, 0, F_GMSK);
        !           285:                ghosts(G_WRIT, 1, F_GMSK);
        !           286:                curs(2, 0);
        !           287:                atrb(r_c[0]);
        !           288:                bufchr(r_c[1]);
        !           289:                curs(p_h[1]+F_VOFF, p_h[0]-4+F_HOFF);
        !           290:                atrb(s_a);
        !           291:                bufstr("GET READY");
        !           292:                delay(10);
        !           293:                pleft();
        !           294:                delay(5);
        !           295:                plot(p_p[0]-4, p_p[1], 9, 1);
        !           296:                pacman(P_WRIT, 1);
        !           297:                animate();
        !           298:                if (stop) {
        !           299:                        if (r_s) {
        !           300:                                r_s = 0;
        !           301:                                plot(r_p[0], r_p[1], 1, 1);
        !           302:                        }
        !           303:                        k = 0;
        !           304:                        while ((stop&1<<k+F_GH) == 0)
        !           305:                                ++k;
        !           306:                        f = &ghost[k].g_q[2];
        !           307:                        ghosts(G_ERAS, 1, ~stop&F_GMSK);
        !           308:                        beep();
        !           309:                        for (i=0; i<12; ++i) {
        !           310:                                *f ^= 2;
        !           311:                                ghosts(G_WRIT, 1, stop);
        !           312:                                delay(1);
        !           313:                                ghosts(G_ERAS, 1, stop);
        !           314:                        }
        !           315:                        for (i=0; i<12; ++i) {
        !           316:                                p_p[2] += (p_d)? -1: 1;
        !           317:                                p_p[2] &= 3;
        !           318:                                pacman(P_WRIT, 1);
        !           319:                                delay(1);
        !           320:                                pacman(P_ERAS, 1);
        !           321:                        }
        !           322:                        --pacmen;
        !           323:                } else
        !           324:                        return (1);
        !           325:        }
        !           326:        return (0);
        !           327: }
        !           328: 
        !           329: map()
        !           330: {
        !           331:        register x, y, z;
        !           332:        register e, g;
        !           333:        register *f;
        !           334: 
        !           335:        e = 0;
        !           336:        g = 0;
        !           337:        f = field;
        !           338:        for (y=0; y<F_VERT; ++y)
        !           339:                for (x=0; x<=F_HORZ/2; ++x)
        !           340:                        field[y][F_HORZ-x-1] = field[y][x];
        !           341:        for (y=0; y<F_VERT; ++y)
        !           342:                for (x=0; x<F_HORZ; ++f, ++x) {
        !           343:                        if (*f & (1<<F_EN)) {
        !           344:                                energ[e][0] = x;
        !           345:                                energ[e][1] = y;
        !           346:                                ++e;
        !           347:                        } else if (*f & (1<<F_GH)) {
        !           348:                                ghost[g].g_h[0] = x;
        !           349:                                ghost[g].g_h[1] = y;
        !           350:                                *f &= ~(1<<F_GH);
        !           351:                                if ((g++&1) == 0) {
        !           352:                                        g_g[g/2][0] = x;
        !           353:                                        g_g[g/2][1] = y;
        !           354:                                }
        !           355:                        } else if (*f & (1<<F_PC)) {
        !           356:                                p_h[0] = x;
        !           357:                                p_h[1] = y;
        !           358:                                *f &= ~(1<<F_PC);
        !           359:                        } else if (*f & (1<<F_FR)) {
        !           360:                                r_p[0] = x;
        !           361:                                r_p[1] = y;
        !           362:                        }
        !           363:                        for (z=0; z<4; ++z)
        !           364:                                if (nc(x, y, z) & 1<<F_WL)
        !           365:                                        *f |= 1<<F_WL+z+1;
        !           366:                }
        !           367: }
        !           368: 
        !           369: 
        !           370: animate()
        !           371: {
        !           372:        register i, c;
        !           373:        register unsigned clock;
        !           374:        register struct ghost *g;
        !           375:        register *p;
        !           376:        char key = '\0';
        !           377:        long oscore;
        !           378:        int gscore;
        !           379: 
        !           380:        oscore = score;
        !           381:        e_s = 0;
        !           382:        stop = 0;
        !           383:        for (clock=0; !stop && edibles; ++clock) {
        !           384:                i = 0;
        !           385:                if (input(&key) || p_n==clock) switch (key) {
        !           386:                case KEY_N:
        !           387:                        ++i;
        !           388:                case KEY_W:
        !           389:                        ++i;
        !           390:                case KEY_S:
        !           391:                        ++i;
        !           392:                case KEY_E:
        !           393:                        if (vm(i) && hm(p_p[2])) {
        !           394:                                c = nc(p_p[0], p_p[1], i);
        !           395:                                if (c & (1<<F_DR|1<<F_WL|1<<F_WL+p_p[2]+1))
        !           396:                                        break;
        !           397:                                if (c & 1<<F_WL+om(p_p[2])+1)
        !           398:                                        mc(p_p);
        !           399:                        } else if (hm(i) && vm(p_p[2])) {
        !           400:                                if (nc(p_p[0]+incr(i), p_p[1]+p_l, i) & 1<<F_WL)
        !           401:                                        break;
        !           402:                                p_p[1] += p_l;
        !           403:                                p_l = 0;
        !           404:                        } else if (p_p[2] == i) {
        !           405:                                if (p_m) {
        !           406:                                        key = '\0';
        !           407:                                        break;
        !           408:                                }
        !           409:                        } else if (vm(i) && p_l) {
        !           410:                                p_p[1] += p_l;
        !           411:                                p_l = -p_l;
        !           412:                        }
        !           413:                        p_p[2] = i;
        !           414:                        p_m = 1;
        !           415:                        p_n = clock;
        !           416:                        key = '\0';
        !           417:                        break;
        !           418:                case KEY_C:
        !           419:                        p_m = 0;
        !           420:                        key = '\0';
        !           421:                        break;
        !           422:                }
        !           423:                if (p_n == clock) {
        !           424:                        if (ndelay)
        !           425:                                delay(1);
        !           426:                        pacman(P_ERAS, 1);
        !           427:                        pacman(P_MOVE, 0);
        !           428:                        pacman(P_UPDI, 0);
        !           429:                        p_d ^= 1;
        !           430:                        pacman(P_WRIT, 1);
        !           431:                        p = &field[p_p[1]+p_l][p_p[0]];
        !           432:                        for (i=-1; i<2; ++i) {
        !           433:                                if (r_s && (p[i]&1<<F_FR)) {
        !           434:                                        score += S_FR;
        !           435:                                        r_s = 0;
        !           436:                                        atrb(s_a);
        !           437:                                        curs(r_p[1]+F_VOFF, r_p[0]+F_HOFF);
        !           438:                                        c = dprint((long)S_FR);
        !           439:                                        delay(5);
        !           440:                                        plot(r_p[0], r_p[1], c, 1);
        !           441:                                        continue;
        !           442:                                }
        !           443:                                if ((c=p[i]) & 1<<F_BN)
        !           444:                                        continue;
        !           445:                                p[i] = c | 1<<F_BN;
        !           446:                                if (c & 1<<F_FD) {
        !           447:                                        score += S_FD;
        !           448:                                } else if (c & 1<<F_EN) {
        !           449:                                        ghosts(G_BLUE, 1, F_GMSK);
        !           450:                                        gscore = S_GH;
        !           451:                                        score += S_EN;
        !           452:                                } else
        !           453:                                        continue;
        !           454:                                --edibles;
        !           455:                                if (edibles==r_t[0] || edibles==r_t[1]) {
        !           456:                                        r_s = r_d;
        !           457:                                        plot(r_p[0], r_p[1], 1, 1);
        !           458:                                }
        !           459:                        }
        !           460:                        if (r_s && --r_s==0)
        !           461:                                plot(r_p[0], r_p[1], 1, 1);
        !           462:                        if (e_s) for (g=ghost,i=1<<F_GH; i&F_GMSK; i<<=1,++g) {
        !           463:                                if (g->g_s!=1 || contact(g->g_p, 3)==0)
        !           464:                                        continue;
        !           465:                                curs(g->g_p[1]+F_VOFF, g->g_p[0]-1+F_HOFF);
        !           466:                                beep();
        !           467:                                atrb(s_a);
        !           468:                                c = dprint((long)gscore);
        !           469:                                delay(5);
        !           470:                                atrb(0);
        !           471:                                curs(g->g_p[1]+F_VOFF, g->g_p[0]-1+F_HOFF);
        !           472:                                while (c--)
        !           473:                                        bufchr(' ');
        !           474:                                g->g_s = 2;
        !           475:                                g->g_e = 0;
        !           476:                                plot(g->g_p[0]-1, g->g_p[1], 4, 1);
        !           477:                                score += gscore;
        !           478:                                gscore *= 2;
        !           479:                        }
        !           480:                }
        !           481:                for (g=ghost,i=1<<F_GH; i&F_GMSK; i<<=1,++g) {
        !           482:                        if (g->g_n != clock)
        !           483:                                continue;
        !           484:                        ghosts(G_ERAS, 1, i);
        !           485:                        ghosts(G_MOVE, 0, i);
        !           486:                        ghosts(G_WRIT, 1, i);
        !           487:                }
        !           488:                if (e_n == clock) {
        !           489:                        ++e_k;
        !           490:                        p = energ[(e_k&=7)&3];
        !           491:                        plot(p[0], p[1], 1, 1);
        !           492:                        e_n += E_TMQN;
        !           493:                }
        !           494:                if (score != oscore) {
        !           495:                        curs(1, 0);
        !           496:                        atrb(s_a);
        !           497:                        dprint(score);
        !           498:                        if (score>=bonus && oscore<bonus) {
        !           499:                                bonus += S_BP;
        !           500:                                if (pacmen < S_PN+1) {
        !           501:                                        beep();
        !           502:                                        ++pacmen;
        !           503:                                        pleft();
        !           504:                                }
        !           505:                        }
        !           506:                        oscore = score;
        !           507:                }
        !           508:                bflush();
        !           509:        }
        !           510: }
        !           511: 
        !           512: dprint(l)
        !           513: long l;
        !           514: {
        !           515:        register c, d = 1, e = 0;
        !           516:        static long mag[] = {1, 10, 100, 1000, 10000, 100000};
        !           517: 
        !           518:        while (mag[d] <= l)
        !           519:                ++d;
        !           520:        while (d--) {
        !           521:                for (c=0; l>=mag[d]; ++c)
        !           522:                        l -= mag[d];
        !           523:                bufchr(c+'0');
        !           524:                ++e;
        !           525:        }
        !           526:        return (e);
        !           527: }
        !           528: 
        !           529: pleft()
        !           530: {
        !           531:        register i, j;
        !           532:        register char *c;
        !           533: 
        !           534:        for (i=0; i<S_PN+1; ++i) {
        !           535:                curs(22-2*i, 0);
        !           536:                c = p_cc[pacmen>i+1? 0 : 1];
        !           537:                for (j=0; j<3; ++j) {
        !           538:                        atrb(*c++);
        !           539:                        bufchr(*c++);
        !           540:                }
        !           541:        }
        !           542: }
        !           543: 
        !           544: pacman(s, p)
        !           545: {
        !           546:        register i;
        !           547:        register *f;
        !           548: 
        !           549:        switch (s) {
        !           550:        case P_ERAS:
        !           551:                for (i=0; i<p_i[2]; ++i) {
        !           552:                        f = &field[p_i[1]+i][p_i[0]];
        !           553:                        *f++ &= ~(1<<F_PC);
        !           554:                        *f++ &= ~(1<<F_PC);
        !           555:                        *f   &= ~(1<<F_PC);
        !           556:                }
        !           557:                plot(p_i[0], p_i[1], 3, p_i[2]);
        !           558:                break;
        !           559:        case P_WRIT:
        !           560:                for (i=0; i<p_i[2]; ++i) {
        !           561:                        f = &field[p_i[1]+i][p_i[0]];
        !           562:                        *f++ |= (1<<F_PC);
        !           563:                        *f++ |= (1<<F_PC);
        !           564:                        *f   |= (1<<F_PC);
        !           565:                }
        !           566:                break;
        !           567:        case P_MOVE:
        !           568:                p_n += (P_TMQN*2-p_n%(P_TMQN*2)+P_TOFF);
        !           569:                if (p_m) {
        !           570:                        i = nc(p_p[0], p_p[1], p_p[2]);
        !           571:                        if (vm(p_p[2]))
        !           572:                                if (p_l) {
        !           573:                                        p_p[1] += p_l;
        !           574:                                        p_l = 0;
        !           575:                                } else if (i & (1<<F_WL|1<<F_DR))
        !           576:                                        p_m = 0;
        !           577:                                else if (P_HALF)
        !           578:                                        p_l = incr(p_p[2]);
        !           579:                                else
        !           580:                                        p_p[1] += incr(p_p[2]);
        !           581:                        else if (i & 1<<F_WL+p_p[2]+1)
        !           582:                                p_m = 0;
        !           583:                        else {
        !           584:                                mc(p_p);
        !           585:                                if (!P_HALF && (p_p[0]&1))
        !           586:                                        mc(p_p);
        !           587:                        }
        !           588:                }
        !           589:                break;
        !           590:        case P_UPDI:
        !           591:                p_i[0] = p_p[0]-1;
        !           592:                p_i[1] = p_p[1]+(p_l>>1);
        !           593:                p_i[2] = 1+(p_l&1);
        !           594:                break;
        !           595:        case P_INIT:
        !           596:                p_p[0] = p_h[0];
        !           597:                p_p[1] = p_h[1];
        !           598:                p_p[2] = 1;
        !           599:                p_l = 0;
        !           600:                p_m = 0;
        !           601:                p_d = 0;
        !           602:                p_n = P_TOFF;
        !           603:                break;
        !           604:        }
        !           605:        if (p)
        !           606:                plot(p_i[0], p_i[1], 3, p_i[2]);
        !           607: }
        !           608: 
        !           609: ghosts(s, p, m)
        !           610: {
        !           611:        register struct ghost *g;
        !           612:        register *f;
        !           613:        register i;
        !           614: 
        !           615:        for (g=ghost,i=1<<F_GH; i&F_GMSK; i<<=1,++g) {
        !           616:                if ((m&i) == 0)
        !           617:                        continue;
        !           618:                switch (s) {
        !           619:                case G_ERAS:
        !           620:                        f = &field[g->g_p[1]][g->g_p[0]];
        !           621:                        *f &= ~i;
        !           622:                        *(f-1) &= ~i;
        !           623:                        *(f+1) &= ~i;
        !           624:                        break;
        !           625:                case G_WRIT:
        !           626:                        f = &field[g->g_p[1]][g->g_p[0]];
        !           627:                        *f |= i;
        !           628:                        *(f-1) |= i;
        !           629:                        *(f+1) |= i;
        !           630:                        break;
        !           631:                case G_MOVE:
        !           632:                        g->g_p[0] = g->g_q[0];
        !           633:                        g->g_p[1] = g->g_q[1];
        !           634:                        g->g_p[2] = g->g_q[2];
        !           635:                        f = g_v;
        !           636:                        switch (g->g_s) {
        !           637:                        case 0:
        !           638:                                if (field[g->g_p[1]][g->g_p[0]] & 1<<F_TN)
        !           639:                                        g->g_n += G_TMQN*8;
        !           640:                                else
        !           641:                                        g->g_n += G_TMQN*4;
        !           642:                                if (g->g_r > 0)
        !           643:                                        if (--g->g_r) {
        !           644:                                                g->g_f ^= 2;
        !           645:                                                break;
        !           646:                                        } else {
        !           647:                                                --g->g_r;
        !           648:                                                g->g_f = 0;
        !           649:                                        }
        !           650:                                if (g->g_r) {
        !           651:                                        if (vector(g, g_g[0], 0))
        !           652:                                                g->g_r = 0;
        !           653:                                } else if (contact(g->g_p, 3) && stop<i) {
        !           654:                                        stop = i;
        !           655:                                        break;
        !           656:                                } else if (track() && sight(g->g_p)) {
        !           657:                                        vector(g, p_p, p_l);
        !           658:                                } else if (nprox() && prox(g->g_p)<=nprox()) {
        !           659:                                        vector(g, p_p, p_l);
        !           660:                                } else {
        !           661:                                        g_v[0] = g->g_p[2];
        !           662:                                        g_v[1] = 3&(g->g_p[2]+
        !           663:                                                 (((g-ghost)^g->g_p[2])&2)-1);
        !           664:                                        g_v[2] = g_v[1]^2;
        !           665:                                        g_v[3] = g_v[0]^2;
        !           666:                                        f += (rand()&rand());
        !           667:                                }
        !           668:                                goto select;
        !           669:                        case 1:
        !           670:                                if (--g->g_e == 0) {
        !           671:                                        g->g_s = 0;
        !           672:                                        g->g_d = 0;
        !           673:                                        --e_s;
        !           674:                                } else if (g->g_e <= G_BTIM)
        !           675:                                        g->g_d ^= 1;
        !           676:                                g->g_n += G_TMQN*8;
        !           677:                                vector(g, p_p, p_l);
        !           678:                                f = g_v+2;
        !           679:                                goto select;
        !           680:                        case 2:
        !           681:                                if (g->g_r == 0) {
        !           682:                                        g->g_r--;
        !           683:                                        g->g_d = 0;
        !           684:                                }
        !           685:                                g->g_n += G_TMQN*2;
        !           686:                                if (vector(g, g_g[1], 0)) {
        !           687:                                        g->g_q[2] ^= 2;
        !           688:                                        while (g->g_n%(G_TMQN*4) != g->g_o)
        !           689:                                                g->g_n += G_TMQN*2;
        !           690:                                        g->g_s = 0;
        !           691:                                        g->g_f = 0;
        !           692:                                        --e_s;
        !           693:                                        break;
        !           694:                                }
        !           695:                                f = g_v;
        !           696:                        select:
        !           697:                                if (vm(*f)
        !           698:                                &&  nc(g->g_p[0], g->g_p[1], *f)
        !           699:                                 &  (1<<F_WL|1<<F_WL+1|1<<F_WL+3
        !           700:                                 |  (!g->g_r)<<F_DR)
        !           701:                                   ) {
        !           702:                                        if (++f-g_v > 3)
        !           703:                                                f = g_v;
        !           704:                                        goto select;
        !           705:                                }
        !           706:                                if (hm(*f)
        !           707:                                &&  nc(g->g_p[0]+2*incr(*f), g->g_p[1], *f)
        !           708:                                 &  1<<F_WL
        !           709:                                   ) {
        !           710:                                        if (++f-g_v > 3)
        !           711:                                                f = g_v;
        !           712:                                        goto select;
        !           713:                                }
        !           714:                                if ((*f^g->g_p[2])==2 && g->g_e<G_ETIM-1) {
        !           715:                                        if (++f-g_v > 3)
        !           716:                                                f = g_v;
        !           717:                                        goto select;
        !           718:                                }
        !           719:                                g->g_q[2] = *f;
        !           720:                                do {
        !           721:                                        mc(g->g_q);
        !           722:                                        if (vm(g->g_q[2])
        !           723:                                        ||  (g->g_q[0]&1) == 0
        !           724:                                           )
        !           725:                                                break;
        !           726:                                        if (g->g_r
        !           727:                                        && (g->g_q[0] == g_g[0][0]
        !           728:                                        &&  g->g_q[1] == g_g[0][1]
        !           729:                                        ||  g->g_q[0] == g_g[1][0]
        !           730:                                        &&  g->g_q[1] == g_g[1][1]
        !           731:                                           ))
        !           732:                                                break;
        !           733:                                        mc(g->g_q);
        !           734:                                } while (0);
        !           735:                                if (g->g_p[2] == g->g_q[2])
        !           736:                                        g->g_f ^= 2;
        !           737:                                else if ((g->g_p[2]^g->g_q[2]) & 1)
        !           738:                                        g->g_f = 0;
        !           739:                        }
        !           740:                        break;
        !           741:                case G_BLUE:
        !           742:                        if (g->g_s < 2) {
        !           743:                                if (g->g_s == 0)
        !           744:                                        if (g->g_r)
        !           745:                                                break;
        !           746:                                        else
        !           747:                                                ++e_s;
        !           748:                                g->g_s = 1;
        !           749:                                g->g_e = G_ETIM;
        !           750:                                g->g_d = 0;
        !           751:                        }
        !           752:                        break;
        !           753:                case G_INIT:
        !           754:                        g->g_p[0] = g->g_q[0] = g->g_h[0];
        !           755:                        g->g_p[1] = g->g_q[1] = g->g_h[1];
        !           756:                        g->g_q[2] = g_i[g-ghost];
        !           757:                        g->g_s = 0;
        !           758:                        g->g_d = 0;
        !           759:                        g->g_e = 0;
        !           760:                        g->g_f = 0;
        !           761:                        g->g_r = 12*((g-ghost&1)*2+(g-ghost&2)/2);
        !           762:                        g->g_n = g->g_o = G_TOFF(g-ghost);
        !           763:                        break;
        !           764:                }
        !           765:                if (p)
        !           766:                        plot(g->g_p[0]-1, g->g_p[1], 3, 1);
        !           767:        }
        !           768: }
        !           769: 
        !           770: plot(x, y, nx, ny)
        !           771: {
        !           772:        register b, f;
        !           773:        register struct ghost *g;
        !           774:        register char *c;
        !           775:        register int *p;
        !           776:        register i;
        !           777:        register z0, z1, z2, z3;
        !           778: 
        !           779:        if (x < 0) {
        !           780:                nx -= x;
        !           781:                x = 0;
        !           782:        }
        !           783:        if ((nx+=x) > F_HORZ-F_HHID)
        !           784:                nx = F_HORZ-F_HHID;
        !           785:        for (ny+=y; y<ny; ++y) {
        !           786:                curs(y+F_VOFF, x+F_HOFF);
        !           787:                p = &field[y][x];
        !           788:                for (i=x; i<nx; ++i) {
        !           789:                        if ((f=*p++&F_BMSK)==0 || i<F_HHID)
        !           790:                                c = b_c;
        !           791:                        else {
        !           792:                                for (b=0; (f&1)==0; ++b)
        !           793:                                        f >>= 1;
        !           794:                                switch (b) {
        !           795:                                case F_GH+0:
        !           796:                                case F_GH+1:
        !           797:                                case F_GH+2:
        !           798:                                case F_GH+3:
        !           799:                                        g = ghost + b - F_GH;
        !           800: /*
        !           801:                                        c = g_c[b-F_GH]
        !           802:                                               [g->g_q[2]^(g->g_f&P_GFLP)]
        !           803:                                               [g->g_s-g->g_d]
        !           804:                                               [i-g->g_p[0]+1];
        !           805: */
        !           806:                                        z0 = b-F_GH;
        !           807:                                        z1 = g->g_q[2]^(g->g_f&P_GFLP);
        !           808:                                        z2 = g->g_s-g->g_d;
        !           809:                                        z3 = i-g->g_p[0]+1;
        !           810:                                        c = g_c[z0][z1][z2][z3];
        !           811:                                        break;
        !           812:                                case F_PC:
        !           813:                                        c = p_c[y-p_i[1]+(p_l&1)][p_p[2]]
        !           814:                                               [p_d][i-p_i[0]];
        !           815:                                        break;
        !           816:                                case F_FR:
        !           817:                                        c = r_s? r_c : b_c;
        !           818:                                        break;
        !           819:                                case F_BN:
        !           820:                                        c = b_c;
        !           821:                                        break;
        !           822:                                case F_FD:
        !           823:                                        c = f_c;
        !           824:                                        break;
        !           825:                                case F_EN:
        !           826:                                        c = e_c[e_k>>2];
        !           827:                                        break;
        !           828:                                case F_DR:
        !           829:                                        c = d_c;
        !           830:                                        break;
        !           831:                                case F_TN:
        !           832:                                        c = b_c;
        !           833:                                        break;
        !           834:                                case F_WL:
        !           835:                                        c = w_c;
        !           836:                                        break;
        !           837:                                }
        !           838:                        }
        !           839:                        atrb(*c++);
        !           840:                        bufchr(*c);
        !           841:                }
        !           842:        }
        !           843: }
        !           844: 
        !           845: contact(p, n)
        !           846: register *p;
        !           847: {
        !           848:        register dx, dy;
        !           849: 
        !           850:        dx = p_p[0] - p[0];
        !           851:        dy = p_p[1]*2 + p_l - p[1]*2;
        !           852:        if ((dy==0 && n>dx && dx>-n)
        !           853:        ||  (dx==0 && n>dy && dy>-n)
        !           854:           )
        !           855:                return (1);
        !           856:        return (0);
        !           857: }
        !           858: 
        !           859: prox(p)
        !           860: register *p;
        !           861: {
        !           862:        register dx, dy;
        !           863: 
        !           864:        if ((dx=p_p[0]-p[0]) < 0)
        !           865:                dx = -dx;
        !           866:        if ((dy=p_p[1]*2+p_l-p[1]*2) < 0)
        !           867:                dy = -dy;
        !           868:        if (dy > dx)
        !           869:                return (dy);
        !           870:        return (dx);
        !           871: }
        !           872: 
        !           873: vector(g, t, o)
        !           874: register struct ghost *g;
        !           875: register *t;
        !           876: {
        !           877:        register i;
        !           878:        int d[2], s[2] = {0, 0};
        !           879: 
        !           880:        if ((d[0]=t[0]-g->g_p[0]) < 0) {
        !           881:                        d[0] =- d[0];
        !           882:                        s[0] =  2;
        !           883:        } else if (d[0] == 0)
        !           884:                if (hm(g->g_p[2]))
        !           885:                        s[0] = g->g_p[2]&2^2;
        !           886:                else
        !           887:                        s[0] = rand()*2;
        !           888:        if ((d[1]=t[1]*2+o-g->g_p[1]*2) < 0) {
        !           889:                        d[1] =- d[1];
        !           890:                        s[1] =  2;
        !           891:        } else if (d[1] == 0)
        !           892:                if (vm(g->g_p[2]))
        !           893:                        s[1] = g->g_p[2]&2^2;
        !           894:                else
        !           895:                        s[1] = rand()*2;
        !           896:        if (d[0] > d[1])
        !           897:                i = 0;
        !           898:        else if (d[1] > d[0])
        !           899:                i = 1;
        !           900:        else
        !           901:                i = axis(g->g_p[2]);
        !           902:        t = g_v;
        !           903:        *t++ = i | s[i];
        !           904:        *t++ = (i^1) | s[i^1];
        !           905:        *t++ = (i^1) | (s[i^1]^2);
        !           906:        *t   = i | (s[i]^2);
        !           907:        if (d[0] | d[1])
        !           908:                return (0);
        !           909:        return (1);
        !           910: }
        !           911: 
        !           912: sight(p)
        !           913: register *p;
        !           914: {
        !           915:        register v;
        !           916:        int q[3];
        !           917: 
        !           918:        if (p[0] != p_p[0]
        !           919:        &&  p[1] != p_p[1]
        !           920:           )
        !           921:                return (0);
        !           922:        for (v=p[2]-1; v<=p[2]+1; ++v) {
        !           923:                q[0] = p[0];
        !           924:                q[1] = p[1];
        !           925:                q[2] = v&3;
        !           926:                while ((field[q[1]][q[0]]&1<<F_WL) == 0) {
        !           927:                        if (q[0]==p_p[0] && q[1]==p_p[1])
        !           928:                                return (1);
        !           929:                        mc(q);
        !           930:                }
        !           931:        }
        !           932:        return (0);
        !           933: }

unix.superglobalmegacorp.com

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