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

unix.superglobalmegacorp.com

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