Annotation of 43BSD/games/backgammon/move.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)move.c     5.1 (Berkeley) 5/29/85";
                      9: #endif not lint
                     10: 
                     11: #include "back.h"
                     12: 
                     13: #ifdef DEBUG
                     14: #include <stdio.h>
                     15: FILE   *trace;
                     16: static char    tests[20];
                     17: #endif
                     18: 
                     19: struct BOARD  {                                /* structure of game position */
                     20:        int     b_board[26];                    /* board position */
                     21:        int     b_in[2];                        /* men in */
                     22:        int     b_off[2];                       /* men off */
                     23:        int     b_st[4], b_fn[4];               /* moves */
                     24: 
                     25:        struct BOARD    *b_next;                /* forward queue pointer */
                     26: };
                     27: 
                     28: struct BOARD *freeq = -1;
                     29: struct BOARD *checkq = -1;
                     30: struct BOARD *bsave();
                     31: struct BOARD *nextfree();
                     32: 
                     33:                                        /* these variables are values for the
                     34:                                         * candidate move */
                     35: static int     ch;                             /* chance of being hit */
                     36: static int     op;                             /* computer's open men */
                     37: static int     pt;                             /* comp's protected points */
                     38: static int     em;                             /* farthest man back */
                     39: static int     frc;                            /* chance to free comp's men */
                     40: static int     frp;                            /* chance to free pl's men */
                     41: 
                     42:                                        /* these values are the values for the
                     43:                                         * move chosen (so far) */
                     44: static int     chance;                         /* chance of being hit */
                     45: static int     openmen;                        /* computer's open men */
                     46: static int     points;                         /* comp's protected points */
                     47: static int     endman;                         /* farthest man back */
                     48: static int     barmen;                         /* men on bar */
                     49: static int     menin;                          /* men in inner table */
                     50: static int     menoff;                         /* men off board */
                     51: static int     oldfrc;                         /* chance to free comp's men */
                     52: static int     oldfrp;                         /* chance to free pl's men */
                     53: 
                     54: static int     cp[5];                          /* candidate start position */
                     55: static int     cg[5];                          /* candidate finish position */
                     56: 
                     57: static int     race;                           /* game reduced to a race */
                     58: 
                     59: move (okay)
                     60: int    okay;                                   /* zero if first move */
                     61: {
                     62:        register int    i;              /* index */
                     63:        register int    l;              /* last man */
                     64: 
                     65:        if (okay)  {
                     66:                                                /* see if comp should double */
                     67:                if (gvalue < 64 && dlast != cturn && dblgood())  {
                     68:                        writel (*Colorptr);
                     69:                        dble();                     /* double */
                     70:                                                    /* return if declined */
                     71:                        if (cturn != 1 && cturn != -1)
                     72:                                return;
                     73:                }
                     74:                roll();
                     75:        }
                     76: 
                     77:        race = 0;
                     78:        for (i = 0; i < 26; i++)  {
                     79:                if (board[i] < 0)
                     80:                        l = i;
                     81:        }
                     82:        for (i = 0; i < l; i++)  {
                     83:                if (board[i] > 0)
                     84:                        break;
                     85:        }
                     86:        if (i == l)
                     87:                race = 1;
                     88: 
                     89:                                                /* print roll */
                     90:        if (tflag)
                     91:                curmove (cturn == -1? 18: 19,0);
                     92:        writel (*Colorptr);
                     93:        writel (" rolls ");
                     94:        writec (D0+'0');
                     95:        writec (' ');
                     96:        writec (D1+'0');
                     97:                                                /* make tty interruptable
                     98:                                                 * while thinking */
                     99:        if (tflag)
                    100:                cline();
                    101:        fixtty (noech);
                    102: 
                    103:                                                /* find out how many moves */
                    104:        mvlim = movallow();
                    105:        if (mvlim == 0)  {
                    106:                writel (" but cannot use it.\n");
                    107:                nexturn();
                    108:                fixtty (raw);
                    109:                return;
                    110:        }
                    111: 
                    112:                                                /* initialize */
                    113:        for (i = 0; i < 4; i++)
                    114:                cp[i] = cg[i] = 0;
                    115: 
                    116:                                                /* strategize */
                    117:        trymove (0,0);
                    118:        pickmove();
                    119: 
                    120:                                                /* print move */
                    121:        writel (" and moves ");
                    122:        for (i = 0; i < mvlim; i++)  {
                    123:                if (i > 0)
                    124:                        writec (',');
                    125:                wrint (p[i] = cp[i]);
                    126:                writec ('-');
                    127:                wrint (g[i] = cg[i]);
                    128:                makmove (i);
                    129:        }
                    130:        writec ('.');
                    131: 
                    132:                                                /* print blots hit */
                    133:        if (tflag)
                    134:                curmove (20,0);
                    135:        else
                    136:                writec ('\n');
                    137:        for (i = 0; i < mvlim; i++)
                    138:                if (h[i])
                    139:                        wrhit(g[i]);
                    140:                                                /* get ready for next move */
                    141:        nexturn();
                    142:        if (!okay)  {
                    143:                buflush();
                    144:                sleep (3);
                    145:        }
                    146:        fixtty (raw);                           /* no more tty interrupt */
                    147: }
                    148: 
                    149: trymove (mvnum,swapped)
                    150: register int   mvnum;                          /* number of move (rel zero) */
                    151: int            swapped;                        /* see if swapped also tested */
                    152: 
                    153: {
                    154:        register int    pos;                    /* position on board */
                    155:        register int    rval;                   /* value of roll */
                    156: 
                    157:                                                /* if recursed through all dice
                    158:                                                 * values, compare move */
                    159:        if (mvnum == mvlim)  {
                    160:                binsert (bsave());
                    161:                return;
                    162:        }
                    163: 
                    164:                                                /* make sure dice in always
                    165:                                                 * same order */
                    166:        if (d0 == swapped)
                    167:                swap;
                    168:                                                /* choose value for this move */
                    169:        rval = dice[mvnum != 0];
                    170: 
                    171:                                                /* find all legitimate moves */
                    172:        for (pos = bar; pos != home; pos += cturn)  {
                    173:                                                /* fix order of dice */
                    174:                if (d0 == swapped)
                    175:                        swap;
                    176:                                                /* break if stuck on bar */
                    177:                if (board[bar] != 0 && pos != bar)
                    178:                        break;
                    179:                                                /* on to next if not occupied */
                    180:                if (board[pos]*cturn <= 0)
                    181:                        continue;
                    182:                                                /* set up arrays for move */
                    183:                p[mvnum] = pos;
                    184:                g[mvnum] = pos+rval*cturn;
                    185:                if (g[mvnum]*cturn >= home)  {
                    186:                        if (*offptr < 0)
                    187:                                break;
                    188:                        g[mvnum] = home;
                    189:                }
                    190:                                                /* try to move */
                    191:                if (makmove (mvnum))
                    192:                        continue;
                    193:                else
                    194:                        trymove (mvnum+1,2);
                    195:                                                /* undo move to try another */
                    196:                backone (mvnum);
                    197:        }
                    198: 
                    199:                                                /* swap dice and try again */
                    200:        if ((!swapped) && D0 != D1)
                    201:                trymove (0,1);
                    202: }
                    203: 
                    204: struct BOARD *
                    205: bsave ()  {
                    206:        register int    i;              /* index */
                    207:        struct BOARD    *now;           /* current position */
                    208: 
                    209:        now = nextfree ();              /* get free BOARD */
                    210: 
                    211:                                        /* store position */
                    212:        for (i = 0; i < 26; i++)
                    213:                now->b_board[i] = board[i];
                    214:        now->b_in[0] = in[0];
                    215:        now->b_in[1] = in[1];
                    216:        now->b_off[0] = off[0];
                    217:        now->b_off[1] = off[1];
                    218:        for (i = 0; i < mvlim; i++)  {
                    219:                now->b_st[i] = p[i];
                    220:                now->b_fn[i] = g[i];
                    221:        }
                    222:        return (now);
                    223: }
                    224: 
                    225: binsert (new)
                    226: struct BOARD   *new;                                   /* item to insert */
                    227: {
                    228:        register struct BOARD   *p = checkq;            /* queue pointer */
                    229:        register int            result;                 /* comparison result */
                    230: 
                    231:        if (p == -1)  {                         /* check if queue empty */
                    232:                checkq = p = new;
                    233:                p->b_next = -1;
                    234:                return;
                    235:        }
                    236: 
                    237:        result = bcomp (new,p);                 /* compare to first element */
                    238:        if (result < 0)  {                              /* insert in front */
                    239:                new->b_next = p;
                    240:                checkq = new;
                    241:                return;
                    242:        }
                    243:        if (result == 0)  {                             /* duplicate entry */
                    244:                mvcheck (p,new);
                    245:                makefree (new);
                    246:                return;
                    247:        }
                    248: 
                    249:        while (p->b_next != -1)  {              /* traverse queue */
                    250:                result = bcomp (new,p->b_next);
                    251:                if (result < 0)  {                      /* found place */
                    252:                        new->b_next = p->b_next;
                    253:                        p->b_next = new;
                    254:                        return;
                    255:                }
                    256:                if (result == 0)  {                     /* duplicate entry */
                    257:                        mvcheck (p->b_next,new);
                    258:                        makefree (new);
                    259:                        return;
                    260:                }
                    261:                p = p->b_next;
                    262:        }
                    263:                                                /* place at end of queue */
                    264:        p->b_next = new;
                    265:        new->b_next = -1;
                    266: }
                    267: 
                    268: bcomp (a,b)
                    269: struct BOARD   *a;
                    270: struct BOARD   *b;
                    271: {
                    272:        register int    *aloc = a->b_board;     /* pointer to board a */
                    273:        register int    *bloc = b->b_board;     /* pointer to board b */
                    274:        register int    i;                      /* index */
                    275:        int             result;                 /* comparison result */
                    276: 
                    277:        for (i = 0; i < 26; i++)  {             /* compare boards */
                    278:                result = cturn*(aloc[i]-bloc[i]);
                    279:                if (result)
                    280:                        return (result);                /* found inequality */
                    281:        }
                    282:        return (0);                             /* same position */
                    283: }
                    284: 
                    285: mvcheck (incumbent,candidate)
                    286: register struct BOARD  *incumbent;
                    287: register struct BOARD  *candidate;
                    288: {
                    289:        register int    i;
                    290:        register int    result;
                    291: 
                    292:        for (i = 0; i < mvlim; i++)  {
                    293:                result = cturn*(candidate->b_st[i]-incumbent->b_st[i]);
                    294:                if (result > 0)
                    295:                        return;
                    296:                if (result < 0)
                    297:                        break;
                    298:        }
                    299:        if (i == mvlim)
                    300:                return;
                    301:        for (i = 0; i < mvlim; i++)  {
                    302:                incumbent->b_st[i] = candidate->b_st[i];
                    303:                incumbent->b_fn[i] = candidate->b_fn[i];
                    304:        }
                    305: }
                    306: 
                    307: makefree (dead)
                    308: struct BOARD   *dead;                  /* dead position */
                    309: {
                    310:        dead->b_next = freeq;                   /* add to freeq */
                    311:        freeq = dead;
                    312: }
                    313: 
                    314: struct BOARD *
                    315: nextfree ()  {
                    316:        struct BOARD    *new;
                    317: 
                    318:        if (freeq == -1)  {
                    319:                new = calloc (1,sizeof (struct BOARD));
                    320:                if (new == 0)  {
                    321:                        writel ("\nOut of memory\n");
                    322:                        getout();
                    323:                }
                    324:                new->b_next = -1;
                    325:                return (new);
                    326:        }
                    327: 
                    328:        new = freeq;
                    329:        freeq = freeq->b_next;
                    330: }
                    331: 
                    332: pickmove ()  {
                    333:                                                /* current game position */
                    334:        register struct BOARD   *now = bsave();
                    335:        register struct BOARD   *next;          /* next move */
                    336: 
                    337: #ifdef DEBUG
                    338:        if (trace == NULL)
                    339:                trace = fopen ("bgtrace","w");
                    340:        fprintf (trace,"\nRoll:  %d %d%s\n",D0,D1,race? " (race)": "");
                    341:        fflush (trace);
                    342: #endif
                    343:        do  {                           /* compare moves */
                    344:                bcopy (checkq);
                    345:                next = checkq->b_next;
                    346:                makefree (checkq);
                    347:                checkq = next;
                    348:                movcmp();
                    349:        } while (checkq != -1);
                    350: 
                    351:        bcopy (now);
                    352: }
                    353: 
                    354: bcopy (s)
                    355: register struct BOARD  *s;                     /* game situation */
                    356: {
                    357:        register int    i;                      /* index */
                    358: 
                    359:        for (i = 0; i < 26; i++)
                    360:                board[i] = s->b_board[i];
                    361:        for (i = 0; i < 2; i++)  {
                    362:                in[i] = s->b_in[i];
                    363:                off[i] = s->b_off[i];
                    364:        }
                    365:        for (i = 0; i < mvlim; i++)  {
                    366:                p[i] = s->b_st[i];
                    367:                g[i] = s->b_fn[i];
                    368:        }
                    369: }
                    370: 
                    371: movcmp ()  {
                    372:        register int    i;
                    373:        register int    c;
                    374: 
                    375: #ifdef DEBUG
                    376:        if (trace == NULL)
                    377:                trace = fopen ("bgtrace","w");
                    378: #endif
                    379: 
                    380:        odds (0,0,0);
                    381:        if (!race)  {
                    382:                ch = op = pt = 0;
                    383:                for (i = 1; i < 25; i++)  {
                    384:                        if (board[i] == cturn)
                    385:                                ch = canhit (i,1);
                    386:                                op += abs (bar-i);
                    387:                }
                    388:                for (i = bar+cturn; i != home; i += cturn)
                    389:                        if (board[i]*cturn > 1)
                    390:                                pt += abs(bar-i);
                    391:                frc = freemen (bar)+trapped (bar,cturn);
                    392:                frp = freemen (home)+trapped (home,-cturn);
                    393:        }
                    394:        for (em = bar; em != home; em += cturn)
                    395:                if (board[em]*cturn > 0)
                    396:                        break;
                    397:        em = abs(home-em);
                    398: #ifdef DEBUG
                    399:        fputs ("Board: ",trace);
                    400:        for (i = 0; i < 26; i++)
                    401:                fprintf (trace, " %d",board[i]);
                    402:        if (race)
                    403:                fprintf (trace,"\n\tem = %d\n",em);
                    404:        else
                    405:                fprintf (trace,
                    406:                        "\n\tch = %d, pt = %d, em = %d, frc = %d, frp = %d\n",
                    407:                        ch,pt,em,frc,frp);
                    408:        fputs ("\tMove: ",trace);
                    409:        for (i = 0; i < mvlim; i++)
                    410:                fprintf (trace," %d-%d",p[i],g[i]);
                    411:        fputs ("\n",trace);
                    412:        fflush (trace);
                    413:        strcpy (tests,"");
                    414: #endif
                    415:        if ((cp[0] == 0 && cg[0] == 0) || movegood())  {
                    416: #ifdef DEBUG
                    417:                fprintf (trace,"\t[%s] ... wins.\n",tests);
                    418:                fflush (trace);
                    419: #endif
                    420:                for (i = 0; i < mvlim; i++)  {
                    421:                        cp[i] = p[i];
                    422:                        cg[i] = g[i];
                    423:                }
                    424:                if (!race)  {
                    425:                        chance = ch;
                    426:                        openmen = op;
                    427:                        points = pt;
                    428:                        endman = em;
                    429:                        barmen = abs(board[home]);
                    430:                        oldfrc = frc;
                    431:                        oldfrp = frp;
                    432:                }
                    433:                menin = *inptr;
                    434:                menoff = *offptr;
                    435:        }
                    436: #ifdef DEBUG
                    437:        else  {
                    438:                fprintf (trace,"\t[%s] ... loses.\n",tests);
                    439:                fflush (trace);
                    440:        }
                    441: #endif
                    442: }
                    443: 
                    444: movegood ()  {
                    445:        register int    n;
                    446: 
                    447:        if (*offptr == 15)
                    448:                return (1);
                    449:        if (menoff == 15)
                    450:                return (0);
                    451:        if (race)  {
                    452: #ifdef DEBUG
                    453:                strcat (tests,"o");
                    454: #endif
                    455:                if (*offptr-menoff)
                    456:                        return (*offptr > menoff);
                    457: #ifdef DEBUG
                    458:                strcat (tests,"e");
                    459: #endif
                    460:                if (endman-em)
                    461:                        return (endman > em);
                    462: #ifdef DEBUG
                    463:                strcat (tests,"i");
                    464: #endif
                    465:                if (menin == 15)
                    466:                        return (0);
                    467:                if (*inptr == 15)
                    468:                        return (1);
                    469: #ifdef DEBUG
                    470:                strcat (tests,"i");
                    471: #endif
                    472:                if (*inptr-menin)
                    473:                        return (*inptr > menin);
                    474:                return (rnum(2));
                    475:        } else  {
                    476:                n = barmen-abs(board[home]);
                    477: #ifdef DEBUG
                    478:                strcat (tests,"c");
                    479: #endif
                    480:                if (abs(chance-ch)+25*n > rnum(150))
                    481:                        return (n? (n < 0): (ch < chance));
                    482: #ifdef DEBUG
                    483:                strcat (tests,"o");
                    484: #endif
                    485:                if (*offptr-menoff)
                    486:                        return (*offptr > menoff);
                    487: #ifdef DEBUG
                    488:                strcat (tests,"o");
                    489: #endif
                    490:                if (abs(openmen-op) > 7+rnum(12))
                    491:                        return (openmen > op);
                    492: #ifdef DEBUG
                    493:                strcat (tests,"b");
                    494: #endif
                    495:                if (n)
                    496:                        return (n < 0);
                    497: #ifdef DEBUG
                    498:                strcat (tests,"e");
                    499: #endif
                    500:                if (abs(endman-em) > rnum(2))
                    501:                        return (endman > em);
                    502: #ifdef DEBUG
                    503:                strcat (tests,"f");
                    504: #endif
                    505:                if (abs(frc-oldfrc) > rnum(2))
                    506:                        return (frc < oldfrc);
                    507: #ifdef DEBUG
                    508:                strcat (tests,"p");
                    509: #endif
                    510:                if (abs(n = pt-points) > rnum(4))
                    511:                        return (n > 0);
                    512: #ifdef DEBUG
                    513:                strcat (tests,"i");
                    514: #endif
                    515:                if (*inptr-menin)
                    516:                        return (*inptr > menin);
                    517: #ifdef DEBUG
                    518:                strcat (tests,"f");
                    519: #endif
                    520:                if (abs(frp-oldfrp) > rnum(2))
                    521:                        return (frp > oldfrp);
                    522:                return (rnum(2));
                    523:        }
                    524: }

unix.superglobalmegacorp.com

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