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