Annotation of coherent/d/usr/games/pacman/pac.c, revision 1.1.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.