1*32224Sbostic #ifndef lint 2*32224Sbostic static char sccsid[] = "@(#)btlgammon.c 1.1 (Berkeley) 09/20/87"; 3*32224Sbostic #endif not lint 4*32224Sbostic 5*32224Sbostic /* 6*32224Sbostic ** The game of Backgammon 7*32224Sbostic */ 8*32224Sbostic 9*32224Sbostic #include <stdio.h> 10*32224Sbostic 11*32224Sbostic #define WHITE 0 12*32224Sbostic #define BROWN 1 13*32224Sbostic #define NIL (-1) 14*32224Sbostic #define MAXGMOV 10 15*32224Sbostic #define MAXIMOVES 1000 16*32224Sbostic #define RULES "/usr/games/lib/backrules" 17*32224Sbostic 18*32224Sbostic char level; /*'b'=beginner, 'i'=intermediate, 'e'=expert*/ 19*32224Sbostic 20*32224Sbostic int die1; 21*32224Sbostic int die2; 22*32224Sbostic int i; 23*32224Sbostic int j; 24*32224Sbostic int l; 25*32224Sbostic int m; 26*32224Sbostic int pflg = 1; 27*32224Sbostic int nobroll = 0; 28*32224Sbostic int count; 29*32224Sbostic int imoves; 30*32224Sbostic int goodmoves[MAXGMOV]; 31*32224Sbostic int probmoves[MAXGMOV]; 32*32224Sbostic 33*32224Sbostic int brown[] = { /* brown position table */ 34*32224Sbostic 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 35*32224Sbostic 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, 36*32224Sbostic 0, 0, 0, 0, 0, 0 37*32224Sbostic }; 38*32224Sbostic 39*32224Sbostic int white[] = { /* white position table */ 40*32224Sbostic 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 41*32224Sbostic 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, 42*32224Sbostic 0, 0, 0, 0, 0, 0 43*32224Sbostic }; 44*32224Sbostic 45*32224Sbostic int probability[] = { 46*32224Sbostic 0, 11, 12, 13, 14, 15, 16, 47*32224Sbostic 06, 05, 04, 03, 02, 01 48*32224Sbostic }; 49*32224Sbostic 50*32224Sbostic struct { 51*32224Sbostic int pos[4]; 52*32224Sbostic int mov[4]; 53*32224Sbostic } moves[MAXIMOVES]; 54*32224Sbostic 55*32224Sbostic main() 56*32224Sbostic { 57*32224Sbostic int go[5], tvec[2]; 58*32224Sbostic int k, n, pid, ret, rpid, t; 59*32224Sbostic char s[100]; 60*32224Sbostic 61*32224Sbostic srand(time(0)); 62*32224Sbostic go[5] = NIL; 63*32224Sbostic fprintf(stdout, "Instructions? "); 64*32224Sbostic gets(s); 65*32224Sbostic if(*s == 'y') 66*32224Sbostic instructions(); 67*32224Sbostic putchar('\n'); 68*32224Sbostic fprintf(stdout, "Opponent's level: b - beginner,\n"); 69*32224Sbostic fprintf(stdout, "i - intermediate, e - expert? "); 70*32224Sbostic level='e'; 71*32224Sbostic gets(s); 72*32224Sbostic if(*s == 'b') 73*32224Sbostic level = 'b'; 74*32224Sbostic else if(*s == 'i') 75*32224Sbostic level = 'i'; 76*32224Sbostic putchar('\n'); 77*32224Sbostic fprintf(stdout, "You will play brown.\n\n"); 78*32224Sbostic fprintf(stdout, "Would you like to roll your own dice? "); 79*32224Sbostic gets(s); 80*32224Sbostic putchar('\n'); 81*32224Sbostic if(*s == 'y') 82*32224Sbostic nobroll = 1; 83*32224Sbostic fprintf(stdout, "Would you like to go first? "); 84*32224Sbostic gets(s); 85*32224Sbostic putchar('\n'); 86*32224Sbostic if(*s == 'y') 87*32224Sbostic goto nowhmove; 88*32224Sbostic whitesmv: 89*32224Sbostic roll(WHITE); 90*32224Sbostic fprintf(stdout, "white rolls %d, %d\n", die1, die2); 91*32224Sbostic fprintf(stdout, "white's move is:"); 92*32224Sbostic if(nextmove(white, brown) == NIL) 93*32224Sbostic goto nowhmove; 94*32224Sbostic if(piececount(white, 0, 24) == 0){ 95*32224Sbostic fprintf(stdout, "White wins"); 96*32224Sbostic if(piececount(brown, 0, 6) != 0) 97*32224Sbostic fprintf(stdout, " with a Backgammon!\n"); 98*32224Sbostic else if (piececount(brown, 0, 24) == 24) 99*32224Sbostic fprintf(stdout, " with a Gammon.\n"); 100*32224Sbostic else 101*32224Sbostic fprintf(stdout, ".\n"); 102*32224Sbostic exit(0); 103*32224Sbostic } 104*32224Sbostic nowhmove: 105*32224Sbostic if(pflg) 106*32224Sbostic prtbrd(); 107*32224Sbostic roll(BROWN); 108*32224Sbostic retry: 109*32224Sbostic fprintf(stdout, "\nYour roll is %d %d\n", die1, die2); 110*32224Sbostic fprintf(stdout, "Move? "); 111*32224Sbostic gets(s); 112*32224Sbostic switch(*s) { 113*32224Sbostic case '\0': /* empty line */ 114*32224Sbostic fprintf(stdout, "Brown's move skipped.\n"); 115*32224Sbostic goto whitesmv; 116*32224Sbostic 117*32224Sbostic case 'b': /* how many beared off? */ 118*32224Sbostic fprintf(stdout, "Brown: %d\n", piececount(brown, 0, 24) - 15); 119*32224Sbostic fprintf(stdout, "White: %d\n", piececount(white, 0, 24) - 15); 120*32224Sbostic goto retry; 121*32224Sbostic 122*32224Sbostic case 'p': /* print board */ 123*32224Sbostic prtbrd(); 124*32224Sbostic goto retry; 125*32224Sbostic 126*32224Sbostic case 's': /* stop auto printing of board */ 127*32224Sbostic pflg = 0; 128*32224Sbostic goto retry; 129*32224Sbostic 130*32224Sbostic case 'r': /* resume auto printing */ 131*32224Sbostic pflg = 1; 132*32224Sbostic goto retry; 133*32224Sbostic 134*32224Sbostic case 'm': /* print possible moves */ 135*32224Sbostic pmoves(); 136*32224Sbostic goto retry; 137*32224Sbostic 138*32224Sbostic case 'q': /* i give up */ 139*32224Sbostic exit(0); 140*32224Sbostic 141*32224Sbostic case '!': /* escape to Shell */ 142*32224Sbostic if(s[1] != '\0') 143*32224Sbostic system(s+1); 144*32224Sbostic else if((pid = fork()) == 0) { 145*32224Sbostic execl("/bin/sh", "sh", "-", 0); 146*32224Sbostic fprintf(stderr, "back: cannot exec /bin/sh!\n"); 147*32224Sbostic exit(2); 148*32224Sbostic } 149*32224Sbostic while((rpid = wait(&ret)) != pid && rpid != -1) 150*32224Sbostic ; 151*32224Sbostic goto retry; 152*32224Sbostic 153*32224Sbostic case '?': /* well, what can i do? */ 154*32224Sbostic fprintf(stdout, "<newline> skip this move\n"); 155*32224Sbostic fprintf(stdout, "b number beared off\n"); 156*32224Sbostic fprintf(stdout, "p print board\n"); 157*32224Sbostic fprintf(stdout, "q quit\n"); 158*32224Sbostic fprintf(stdout, "r resume auto print of board\n"); 159*32224Sbostic fprintf(stdout, "s stop auto print of board\n"); 160*32224Sbostic fprintf(stdout, "! escape to Shell\n"); 161*32224Sbostic goto retry; 162*32224Sbostic } 163*32224Sbostic n = sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]); 164*32224Sbostic if((die1 != die2 && n > 2) || n > 4){ 165*32224Sbostic fprintf(stdout, "Too many moves.\n"); 166*32224Sbostic goto retry; 167*32224Sbostic } 168*32224Sbostic go[n] = NIL; 169*32224Sbostic if(*s=='-'){ 170*32224Sbostic go[0]= -go[0]; 171*32224Sbostic t=die1; 172*32224Sbostic die1=die2; 173*32224Sbostic die2=t; 174*32224Sbostic } 175*32224Sbostic for(k = 0; k < n; k++){ 176*32224Sbostic if(0 <= go[k] && go[k] <= 24) 177*32224Sbostic continue; 178*32224Sbostic else{ 179*32224Sbostic fprintf(stdout, "Move %d illegal.\n", go[k]); 180*32224Sbostic goto retry; 181*32224Sbostic } 182*32224Sbostic } 183*32224Sbostic if(play(brown, white, go)) 184*32224Sbostic goto retry; 185*32224Sbostic if(piececount(brown, 0, 24) == 0){ 186*32224Sbostic fprintf(stdout, "Brown wins"); 187*32224Sbostic if(piececount(white, 0, 6) != 0) 188*32224Sbostic fprintf(stdout, " with a Backgammon.\n"); 189*32224Sbostic else if(piececount(white, 0, 24) == 24) 190*32224Sbostic fprintf(stdout, " with a gammon.\n"); 191*32224Sbostic else 192*32224Sbostic fprintf(stdout, ".\n"); 193*32224Sbostic exit(0); 194*32224Sbostic } 195*32224Sbostic goto whitesmv; 196*32224Sbostic } 197*32224Sbostic 198*32224Sbostic play(player,playee,pos) 199*32224Sbostic int *player,*playee,pos[]; 200*32224Sbostic { 201*32224Sbostic int k, n, die, ipos; 202*32224Sbostic 203*32224Sbostic for(k=0; k < player[0]; k++){ /*blots on player[0] must be moved first*/ 204*32224Sbostic if(pos[k] == NIL) 205*32224Sbostic break; 206*32224Sbostic if(pos[k] != 0){ 207*32224Sbostic fprintf(stdout, "Stone on bar must be moved first.\n"); 208*32224Sbostic return(NIL); 209*32224Sbostic } 210*32224Sbostic } 211*32224Sbostic for(k = 0; (ipos=pos[k]) != NIL; k++){ 212*32224Sbostic die = k?die2:die1; 213*32224Sbostic n = 25-ipos-die; 214*32224Sbostic if(player[ipos] == 0) 215*32224Sbostic goto badmove; 216*32224Sbostic if(n > 0 && playee[n] >= 2) 217*32224Sbostic goto badmove; 218*32224Sbostic if(n <= 0){ 219*32224Sbostic if(piececount(player,0,18) != 0) 220*32224Sbostic goto badmove; 221*32224Sbostic if((ipos+die) != 25 && piececount(player,19,24-die)!=0) 222*32224Sbostic goto badmove; 223*32224Sbostic } 224*32224Sbostic player[ipos]--; 225*32224Sbostic player[ipos+die]++; 226*32224Sbostic } 227*32224Sbostic for(k = 0; pos[k] != NIL; k++){ 228*32224Sbostic die = k?die2:die1; 229*32224Sbostic n = 25-pos[k]-die; 230*32224Sbostic if(n>0 && playee[n]==1){ 231*32224Sbostic playee[n]=0; 232*32224Sbostic playee[0]++; 233*32224Sbostic } 234*32224Sbostic } 235*32224Sbostic return(0); 236*32224Sbostic 237*32224Sbostic badmove: 238*32224Sbostic fprintf(stdout, "Move %d illegal.\n", ipos); 239*32224Sbostic while(k--){ 240*32224Sbostic die=k?die2:die1; 241*32224Sbostic player[pos[k]]++; 242*32224Sbostic player[pos[k]+die]--; 243*32224Sbostic } 244*32224Sbostic return(NIL); 245*32224Sbostic } 246*32224Sbostic nextmove(player,playee) 247*32224Sbostic int *player,*playee; 248*32224Sbostic { 249*32224Sbostic int k; 250*32224Sbostic 251*32224Sbostic imoves=0; 252*32224Sbostic movegen(player,playee); 253*32224Sbostic if(die1!=die2){ 254*32224Sbostic k=die1; 255*32224Sbostic die1=die2; 256*32224Sbostic die2=k; 257*32224Sbostic movegen(player,playee); 258*32224Sbostic } 259*32224Sbostic if(imoves==0){ 260*32224Sbostic fprintf(stdout, "no move possible.\n"); 261*32224Sbostic return(NIL); 262*32224Sbostic } 263*32224Sbostic k=strategy(player,playee); /*select kth possible move*/ 264*32224Sbostic prtmov(k); 265*32224Sbostic update(player,playee,k); 266*32224Sbostic return(0); 267*32224Sbostic } 268*32224Sbostic prtmov(k) 269*32224Sbostic int k; 270*32224Sbostic { 271*32224Sbostic int n; 272*32224Sbostic 273*32224Sbostic if(k == NIL) 274*32224Sbostic fprintf(stdout, "No move possible\n"); 275*32224Sbostic else for(n = 0; n < 4; n++){ 276*32224Sbostic if(moves[k].pos[n] == NIL) 277*32224Sbostic break; 278*32224Sbostic fprintf(stdout, " %d, %d",25-moves[k].pos[n],moves[k].mov[n]); 279*32224Sbostic } 280*32224Sbostic fprintf(stdout, "\n"); 281*32224Sbostic } 282*32224Sbostic update(player,playee,k) 283*32224Sbostic int *player,*playee,k; 284*32224Sbostic { 285*32224Sbostic int n,t; 286*32224Sbostic 287*32224Sbostic for(n = 0; n < 4; n++){ 288*32224Sbostic if(moves[k].pos[n] == NIL) 289*32224Sbostic break; 290*32224Sbostic player[moves[k].pos[n]]--; 291*32224Sbostic player[moves[k].pos[n]+moves[k].mov[n]]++; 292*32224Sbostic t=25-moves[k].pos[n]-moves[k].mov[n]; 293*32224Sbostic if(t>0 && playee[t]==1){ 294*32224Sbostic playee[0]++; 295*32224Sbostic playee[t]--; 296*32224Sbostic } 297*32224Sbostic } 298*32224Sbostic } 299*32224Sbostic piececount(player,startrow,endrow) 300*32224Sbostic int *player,startrow,endrow; 301*32224Sbostic { 302*32224Sbostic int sum; 303*32224Sbostic 304*32224Sbostic sum=0; 305*32224Sbostic while(startrow <= endrow) 306*32224Sbostic sum += player[startrow++]; 307*32224Sbostic return(sum); 308*32224Sbostic } 309*32224Sbostic pmoves() 310*32224Sbostic { 311*32224Sbostic int i1, i2; 312*32224Sbostic 313*32224Sbostic fprintf(stdout, "Possible moves are:\n"); 314*32224Sbostic for(i1 = 0; i1 < imoves; i1++){ 315*32224Sbostic fprintf(stdout, "\n%d",i1); 316*32224Sbostic for (i2 = 0; i2<4; i2++){ 317*32224Sbostic if(moves[i1].pos[i2] == NIL) 318*32224Sbostic break; 319*32224Sbostic fprintf(stdout, "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]); 320*32224Sbostic } 321*32224Sbostic } 322*32224Sbostic fprintf(stdout, "\n"); 323*32224Sbostic } 324*32224Sbostic 325*32224Sbostic roll(who) 326*32224Sbostic { 327*32224Sbostic register n; 328*32224Sbostic char s[10]; 329*32224Sbostic 330*32224Sbostic if(who == BROWN && nobroll) { 331*32224Sbostic fprintf(stdout, "Roll? "); 332*32224Sbostic gets(s); 333*32224Sbostic n = sscanf(s, "%d%d", &die1, &die2); 334*32224Sbostic if(n != 2 || die1 < 1 || die1 > 6 || die2 < 1 || die2 > 6) 335*32224Sbostic fprintf(stdout, "Illegal - I'll do it!\n"); 336*32224Sbostic else 337*32224Sbostic return; 338*32224Sbostic } 339*32224Sbostic die1 = ((rand()>>8) % 6) + 1; 340*32224Sbostic die2 = ((rand()>>8) % 6) + 1; 341*32224Sbostic } 342*32224Sbostic 343*32224Sbostic movegen(mover,movee) 344*32224Sbostic int *mover,*movee; 345*32224Sbostic { 346*32224Sbostic int k; 347*32224Sbostic 348*32224Sbostic for(i = 0; i <= 24; i++){ 349*32224Sbostic count = 0; 350*32224Sbostic if(mover[i] == 0) 351*32224Sbostic continue; 352*32224Sbostic if((k=25-i-die1) > 0 && movee[k] >= 2) 353*32224Sbostic if(mover[0] > 0) 354*32224Sbostic break; 355*32224Sbostic else 356*32224Sbostic continue; 357*32224Sbostic if(k <= 0){ 358*32224Sbostic if(piececount(mover, 0, 18) != 0) 359*32224Sbostic break; 360*32224Sbostic if((i+die1) != 25 && piececount(mover,19,i-1) != 0) 361*32224Sbostic break; 362*32224Sbostic } 363*32224Sbostic mover[i]--; 364*32224Sbostic mover[i+die1]++; 365*32224Sbostic count = 1; 366*32224Sbostic for(j = 0; j <= 24; j++){ 367*32224Sbostic if(mover[j]==0) 368*32224Sbostic continue; 369*32224Sbostic if((k=25-j-die2) > 0 && movee[k] >= 2) 370*32224Sbostic if(mover[0] > 0) 371*32224Sbostic break; 372*32224Sbostic else 373*32224Sbostic continue; 374*32224Sbostic if(k <= 0){ 375*32224Sbostic if(piececount(mover,0,18) != 0) 376*32224Sbostic break; 377*32224Sbostic if((j+die2) != 25 && piececount(mover,19,j-1) != 0) 378*32224Sbostic break; 379*32224Sbostic } 380*32224Sbostic mover[j]--; 381*32224Sbostic mover[j+die2]++; 382*32224Sbostic count = 2; 383*32224Sbostic if(die1 != die2){ 384*32224Sbostic moverecord(mover); 385*32224Sbostic if(mover[0] > 0) 386*32224Sbostic break; 387*32224Sbostic else 388*32224Sbostic continue; 389*32224Sbostic } 390*32224Sbostic for(l = 0; l <= 24; l++){ 391*32224Sbostic if(mover[l] == 0) 392*32224Sbostic continue; 393*32224Sbostic if((k=25-l-die1) > 0 && movee[k] >= 2) 394*32224Sbostic if(mover[0] > 0) 395*32224Sbostic break; 396*32224Sbostic else 397*32224Sbostic continue; 398*32224Sbostic if(k <= 0){ 399*32224Sbostic if(piececount(mover, 0, 18) != 0) 400*32224Sbostic break; 401*32224Sbostic if((l+die2) != 25 && piececount(mover,19,l-1) != 0) 402*32224Sbostic break; 403*32224Sbostic } 404*32224Sbostic mover[l]--; 405*32224Sbostic mover[l+die1]++; 406*32224Sbostic count=3; 407*32224Sbostic for(m=0;m<=24;m++){ 408*32224Sbostic if(mover[m]==0) 409*32224Sbostic continue; 410*32224Sbostic if((k=25-m-die1) >= 0 && movee[k] >= 2) 411*32224Sbostic if(mover[0] > 0) 412*32224Sbostic break; 413*32224Sbostic else 414*32224Sbostic continue; 415*32224Sbostic if(k <= 0){ 416*32224Sbostic if(piececount(mover,0,18) != 0) 417*32224Sbostic break; 418*32224Sbostic if((m+die2) != 25 && piececount(mover,19,m-1) != 0) 419*32224Sbostic break; 420*32224Sbostic } 421*32224Sbostic count=4; 422*32224Sbostic moverecord(mover); 423*32224Sbostic if(mover[0] > 0) 424*32224Sbostic break; 425*32224Sbostic } 426*32224Sbostic if(count == 3) 427*32224Sbostic moverecord(mover); 428*32224Sbostic else{ 429*32224Sbostic mover[l]++; 430*32224Sbostic mover[l+die1]--; 431*32224Sbostic } 432*32224Sbostic if(mover[0] > 0) 433*32224Sbostic break; 434*32224Sbostic } 435*32224Sbostic if(count == 2) 436*32224Sbostic moverecord(mover); 437*32224Sbostic else{ 438*32224Sbostic mover[j]++; 439*32224Sbostic mover[j+die1]--; 440*32224Sbostic } 441*32224Sbostic if(mover[0] > 0) 442*32224Sbostic break; 443*32224Sbostic } 444*32224Sbostic if(count == 1) 445*32224Sbostic moverecord(mover); 446*32224Sbostic else{ 447*32224Sbostic mover[i]++; 448*32224Sbostic mover[i+die1]--; 449*32224Sbostic } 450*32224Sbostic if(mover[0] > 0) 451*32224Sbostic break; 452*32224Sbostic } 453*32224Sbostic } 454*32224Sbostic moverecord(mover) 455*32224Sbostic int *mover; 456*32224Sbostic { 457*32224Sbostic int t; 458*32224Sbostic 459*32224Sbostic if(imoves < MAXIMOVES) { 460*32224Sbostic for(t = 0; t <= 3; t++) 461*32224Sbostic moves[imoves].pos[t] = NIL; 462*32224Sbostic switch(count) { 463*32224Sbostic case 4: 464*32224Sbostic moves[imoves].pos[3]=m; 465*32224Sbostic moves[imoves].mov[3]=die1; 466*32224Sbostic 467*32224Sbostic case 3: 468*32224Sbostic moves[imoves].pos[2]=l; 469*32224Sbostic moves[imoves].mov[2]=die1; 470*32224Sbostic 471*32224Sbostic case 2: 472*32224Sbostic moves[imoves].pos[1]=j; 473*32224Sbostic moves[imoves].mov[1]=die2; 474*32224Sbostic 475*32224Sbostic case 1: 476*32224Sbostic moves[imoves].pos[0]=i; 477*32224Sbostic moves[imoves].mov[0]=die1; 478*32224Sbostic imoves++; 479*32224Sbostic } 480*32224Sbostic } 481*32224Sbostic switch(count) { 482*32224Sbostic case 4: 483*32224Sbostic break; 484*32224Sbostic 485*32224Sbostic case 3: 486*32224Sbostic mover[l]++; 487*32224Sbostic mover[l+die1]--; 488*32224Sbostic break; 489*32224Sbostic 490*32224Sbostic case 2: 491*32224Sbostic mover[j]++; 492*32224Sbostic mover[j+die2]--; 493*32224Sbostic break; 494*32224Sbostic 495*32224Sbostic case 1: 496*32224Sbostic mover[i]++; 497*32224Sbostic mover[i+die1]--; 498*32224Sbostic } 499*32224Sbostic } 500*32224Sbostic 501*32224Sbostic strategy(player,playee) 502*32224Sbostic int *player,*playee; 503*32224Sbostic { 504*32224Sbostic int k, n, nn, bestval, moveval, prob; 505*32224Sbostic 506*32224Sbostic n = 0; 507*32224Sbostic if(imoves == 0) 508*32224Sbostic return(NIL); 509*32224Sbostic goodmoves[0] = NIL; 510*32224Sbostic bestval = -32000; 511*32224Sbostic for(k = 0; k < imoves; k++){ 512*32224Sbostic if((moveval=eval(player,playee,k,&prob)) < bestval) 513*32224Sbostic continue; 514*32224Sbostic if(moveval > bestval){ 515*32224Sbostic bestval = moveval; 516*32224Sbostic n = 0; 517*32224Sbostic } 518*32224Sbostic if(n<MAXGMOV){ 519*32224Sbostic goodmoves[n]=k; 520*32224Sbostic probmoves[n++]=prob; 521*32224Sbostic } 522*32224Sbostic } 523*32224Sbostic if(level=='e' && n>1){ 524*32224Sbostic nn=n; 525*32224Sbostic n=0; 526*32224Sbostic prob=32000; 527*32224Sbostic for(k = 0; k < nn; k++){ 528*32224Sbostic if((moveval=probmoves[k]) > prob) 529*32224Sbostic continue; 530*32224Sbostic if(moveval<prob){ 531*32224Sbostic prob=moveval; 532*32224Sbostic n=0; 533*32224Sbostic } 534*32224Sbostic goodmoves[n]=goodmoves[k]; 535*32224Sbostic probmoves[n++]=probmoves[k]; 536*32224Sbostic } 537*32224Sbostic } 538*32224Sbostic return(goodmoves[(rand()>>4)%n]); 539*32224Sbostic } 540*32224Sbostic 541*32224Sbostic eval(player,playee,k,prob) 542*32224Sbostic int *player,*playee,k,*prob; 543*32224Sbostic { 544*32224Sbostic int newtry[31], newother[31], *r, *q, *p, n, sum, first; 545*32224Sbostic int ii, lastwhite, lastbrown; 546*32224Sbostic 547*32224Sbostic *prob = sum = 0; 548*32224Sbostic r = player+25; 549*32224Sbostic p = newtry; 550*32224Sbostic q = newother; 551*32224Sbostic while(player<r){ 552*32224Sbostic *p++= *player++; 553*32224Sbostic *q++= *playee++; 554*32224Sbostic } 555*32224Sbostic q=newtry+31; 556*32224Sbostic for(p = newtry+25; p < q; p++) /* zero out spaces for hit pieces */ 557*32224Sbostic *p = 0; 558*32224Sbostic for(n = 0; n < 4; n++){ 559*32224Sbostic if(moves[k].pos[n] == NIL) 560*32224Sbostic break; 561*32224Sbostic newtry[moves[k].pos[n]]--; 562*32224Sbostic newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++; 563*32224Sbostic if(ii<25 && newother[25-ii]==1){ 564*32224Sbostic newother[25-ii]=0; 565*32224Sbostic newother[0]++; 566*32224Sbostic if(ii<=15 && level=='e') /* hit if near other's home */ 567*32224Sbostic sum++; 568*32224Sbostic } 569*32224Sbostic } 570*32224Sbostic for(lastbrown = 0; newother[lastbrown] == 0; lastbrown++); 571*32224Sbostic ; 572*32224Sbostic for(lastwhite = 0; newtry[lastwhite] == 0; lastwhite++) 573*32224Sbostic ; 574*32224Sbostic lastwhite = 25-lastwhite; 575*32224Sbostic if(lastwhite<=6 && lastwhite<lastbrown) 576*32224Sbostic sum=1000; 577*32224Sbostic /* experts running game. */ 578*32224Sbostic /* first priority is to */ 579*32224Sbostic /* get all pieces into */ 580*32224Sbostic /* white's home */ 581*32224Sbostic if(lastwhite<lastbrown && level=='e' && lastwhite>6) { 582*32224Sbostic for(sum = 1000; lastwhite > 6; lastwhite--) 583*32224Sbostic sum = sum-lastwhite*newtry[25-lastwhite]; 584*32224Sbostic } 585*32224Sbostic for(first = 0; first < 25; first++) 586*32224Sbostic if(newother[first] != 0) /*find other's first piece*/ 587*32224Sbostic break; 588*32224Sbostic q = newtry+25; 589*32224Sbostic for(p = newtry+1; p < q;) /* blocked points are good */ 590*32224Sbostic if(*p++ > 1) 591*32224Sbostic sum++; 592*32224Sbostic if(first > 5) { /* only stress removing pieces if */ 593*32224Sbostic /* homeboard cannot be hit */ 594*32224Sbostic q = newtry+31; 595*32224Sbostic p=newtry+25; 596*32224Sbostic for(n = 6; p < q; n--) 597*32224Sbostic sum += *p++ * n; /*remove pieces, but just barely*/ 598*32224Sbostic } 599*32224Sbostic if(level != 'b'){ 600*32224Sbostic r = newtry+25-first; /*singles past this point can't be hit*/ 601*32224Sbostic for(p = newtry+7; p < r; ) 602*32224Sbostic if(*p++ == 1) /*singles are bad after 1st 6 points if they can be hit*/ 603*32224Sbostic sum--; 604*32224Sbostic q = newtry+3; 605*32224Sbostic for(p = newtry; p < q; ) /*bad to be on 1st three points*/ 606*32224Sbostic sum -= *p++; 607*32224Sbostic } 608*32224Sbostic 609*32224Sbostic for(n = 1; n <= 4; n++) 610*32224Sbostic *prob += n*getprob(newtry,newother,6*n-5,6*n); 611*32224Sbostic return(sum); 612*32224Sbostic } 613*32224Sbostic instructions() 614*32224Sbostic { 615*32224Sbostic register fd, r; 616*32224Sbostic char buf[BUFSIZ]; 617*32224Sbostic 618*32224Sbostic if((fd = open(RULES, 0)) < 0) { 619*32224Sbostic fprintf(stderr, "back: cannot open %s\n", RULES); 620*32224Sbostic return; 621*32224Sbostic } 622*32224Sbostic while(r = read(fd, buf, BUFSIZ)) 623*32224Sbostic write(1, buf, r); 624*32224Sbostic } 625*32224Sbostic 626*32224Sbostic getprob(player,playee,start,finish) 627*32224Sbostic int *player,*playee,start,finish; 628*32224Sbostic { /*returns the probability (times 102) that any 629*32224Sbostic pieces belonging to 'player' and lying between 630*32224Sbostic his points 'start' and 'finish' will be hit 631*32224Sbostic by a piece belonging to playee 632*32224Sbostic */ 633*32224Sbostic int k, n, sum; 634*32224Sbostic 635*32224Sbostic sum = 0; 636*32224Sbostic for(; start <= finish; start++){ 637*32224Sbostic if(player[start] == 1){ 638*32224Sbostic for(k = 1; k <= 12; k++){ 639*32224Sbostic if((n=25-start-k) < 0) 640*32224Sbostic break; 641*32224Sbostic if(playee[n] != 0) 642*32224Sbostic sum += probability[k]; 643*32224Sbostic } 644*32224Sbostic } 645*32224Sbostic } 646*32224Sbostic return(sum); 647*32224Sbostic } 648*32224Sbostic prtbrd() 649*32224Sbostic { 650*32224Sbostic int k; 651*32224Sbostic static char undersc[]="______________________________________________________"; 652*32224Sbostic 653*32224Sbostic fprintf(stdout, "White's Home\n%s\r",undersc); 654*32224Sbostic for(k = 1; k <= 6; k++) 655*32224Sbostic fprintf(stdout, "%4d",k); 656*32224Sbostic fprintf(stdout, " "); 657*32224Sbostic for(k = 7; k <= 12; k++) 658*32224Sbostic fprintf(stdout, "%4d",k); 659*32224Sbostic putchar('\n'); 660*32224Sbostic numline(brown, white, 1, 6); 661*32224Sbostic fprintf(stdout, " "); 662*32224Sbostic numline(brown, white, 7, 12); 663*32224Sbostic putchar('\n'); 664*32224Sbostic colorline(brown, 'B', white, 'W', 1, 6); 665*32224Sbostic fprintf(stdout, " "); 666*32224Sbostic colorline(brown, 'B', white, 'W', 7, 12); 667*32224Sbostic putchar('\n'); 668*32224Sbostic if(white[0] != 0) 669*32224Sbostic fprintf(stdout, "%28dW\n",white[0]); 670*32224Sbostic else 671*32224Sbostic putchar('\n'); 672*32224Sbostic if(brown[0] != 0) 673*32224Sbostic fprintf(stdout, "%28dB\n", brown[0]); 674*32224Sbostic else 675*32224Sbostic putchar('\n'); 676*32224Sbostic colorline(white, 'W', brown, 'B', 1, 6); 677*32224Sbostic fprintf(stdout, " "); 678*32224Sbostic colorline(white, 'W', brown, 'B', 7, 12); 679*32224Sbostic fprintf(stdout, "\n%s\r",undersc); 680*32224Sbostic numline(white, brown, 1, 6); 681*32224Sbostic fprintf(stdout, " "); 682*32224Sbostic numline(white, brown, 7, 12); 683*32224Sbostic putchar('\n'); 684*32224Sbostic for(k = 24; k >= 19; k--) 685*32224Sbostic fprintf(stdout, "%4d",k); 686*32224Sbostic fprintf(stdout, " "); 687*32224Sbostic for(k = 18; k >= 13; k--) 688*32224Sbostic fprintf(stdout, "%4d",k); 689*32224Sbostic fprintf(stdout, "\nBrown's Home\n\n\n\n\n"); 690*32224Sbostic } 691*32224Sbostic numline(upcol,downcol,start,fin) 692*32224Sbostic int *upcol,*downcol,start,fin; 693*32224Sbostic { 694*32224Sbostic int k, n; 695*32224Sbostic 696*32224Sbostic for(k = start; k <= fin; k++){ 697*32224Sbostic if((n = upcol[k]) != 0 || (n = downcol[25-k]) != 0) 698*32224Sbostic fprintf(stdout, "%4d", n); 699*32224Sbostic else 700*32224Sbostic fprintf(stdout, " "); 701*32224Sbostic } 702*32224Sbostic } 703*32224Sbostic colorline(upcol,c1,downcol,c2,start,fin) 704*32224Sbostic int *upcol,*downcol,start,fin; 705*32224Sbostic char c1,c2; 706*32224Sbostic { 707*32224Sbostic int k; 708*32224Sbostic char c; 709*32224Sbostic 710*32224Sbostic for(k = start; k <= fin; k++){ 711*32224Sbostic c = ' '; 712*32224Sbostic if(upcol[k] != 0) 713*32224Sbostic c = c1; 714*32224Sbostic if(downcol[25-k] != 0) 715*32224Sbostic c = c2; 716*32224Sbostic fprintf(stdout, " %c",c); 717*32224Sbostic } 718*32224Sbostic } 719