1: # include <stdio.h>
   2: 
   3: #
   4: #define NIL (-1)
   5: #define MAXGMOV 10
   6: #define MAXIMOVES 1000
   7:     char level;     /*'b'=beginner, 'i'=intermediate, 'e'=expert*/
   8: int die1;
   9: int die2;
  10: int i;
  11: int j;
  12: int l;
  13: int m;
  14: int count;
  15: int red[]     {0,2,0,0,0,0,0,0,0,0,0,0,5,
  16:          0,0,0,0,3,0,5,0,0,0,0,0,
  17:          0,0,0,0,0,0};
  18: int white[]   {0,2,0,0,0,0,0,0,0,0,0,0,5,
  19:          0,0,0,0,3,0,5,0,0,0,0,0,
  20:          0,0,0,0,0,0};
  21: int probability[]{0,11,12,13,14,15,16,
  22:             06,05,04,03,02,01};
  23: int imoves;
  24: int goodmoves[MAXGMOV] ;
  25: int probmoves[MAXGMOV] ;
  26: struct {int pos[4],mov[4];} moves[MAXIMOVES] ;
  27: 
  28: main()
  29: {
  30:     int t,k,n,go[5];
  31:     char s[100];
  32:     go[5]=NIL;
  33:     srand();
  34:     printf( "Do you want instructions? Type 'y' for yes,\n");
  35:     printf( "anything else means no.?? ");
  36:     getstr(s);
  37:     if(*s=='y')instructions();
  38:     printf( "Choose the level of your oppponent.\n");
  39:     printf( "Type 'b' for beginner, or 'i' for intermediate.\n");
  40:     printf( "Anything else gets you an expert.?? ");
  41:     level='e';
  42:     getstr(s);
  43:     if(*s=='b')level='b';
  44:     else if(*s=='i')level='i';
  45:     printf( "You will play red. Do you wan't to move first?\n");
  46:     printf( "Type 'y' for yes, anything else means no.?? ");
  47:     getstr(s);
  48:     if(*s=='y')goto nowhmove;
  49: whitesmv:
  50:     roll();
  51:     printf( "white rolls %d,%d\n",die1,die2);
  52:     printf( "white's move is:");
  53:     if(nextmove(white,red)==NIL)goto nowhmove;
  54:     if(piececount(white,0,24)==0){
  55:         printf( "White wins\n");
  56:         printf( "Aren't you ashamed. You've been beaten by a computer.\n");
  57:         exit();
  58:     }
  59: nowhmove:
  60:     prtbrd();
  61: 
  62:     roll();
  63: retry:
  64:     printf( "your roll is %d,  %d\n",die1,die2);
  65:     printf( "your move, please?? ");
  66:     getstr(s);
  67:     if(*s==0){
  68:         printf( "red's move skipped\n");
  69:         goto whitesmv;
  70:     }
  71:     n=sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]);
  72:     if((die1!=die2&&n>2)||n>4){
  73:         printf( "you've made too many moves\n");
  74:         goto retry;
  75:     }
  76:     go[n]=NIL;
  77:     if(*s=='-'){
  78:         go[0]= -go[0];
  79:         t=die1;
  80:         die1=die2;
  81:         die2=t;
  82:     }
  83:     for(k=0;k<n;k++){
  84:         if(0<=go[k] && go[k]<=24)continue;
  85:         else{
  86:         printf( "move %d is illegal\n",go[k]);
  87:         goto retry;
  88:         }
  89:     }
  90:     if(play(red,white,go))goto retry;
  91:     if(piececount(red,0,24)==0){
  92:         printf( "Red wins.\n");
  93:         printf( "Congratulations! You have just defeated a dumb machine.\n");
  94:         exit();
  95:     }
  96:     goto whitesmv;
  97: }
  98: 
  99: getstr(s)
 100: char *s;
 101: {
 102:     while((*s=getchar())!='\n')s++;
 103:     *s=0;
 104: }
 105: 
 106: play(player,playee,pos)
 107: int *player,*playee,pos[];
 108: {
 109:     int k,n,die,ipos;
 110:     for(k=0;k<player[0];k++){  /*blots on player[0] must be moved first*/
 111:         if(pos[k]==NIL)break;
 112:         if(pos[k]!=0){
 113:         printf( "piece on position 0 must be moved first\n");
 114:         return(-1);
 115:         }
 116:     }
 117:     for(k=0;(ipos=pos[k])!=NIL;k++){
 118:         die=k?die2:die1;
 119:         n=25-ipos-die;
 120:         if(player[ipos]==0)goto badmove;
 121:         if(n>0&&playee[n]>=2)goto badmove;
 122:         if(n<=0){
 123:         if(piececount(player,0,18)!=0)goto badmove;
 124:         if((ipos+die)!=25&&
 125:             piececount(player,19,24-die)!=0)goto badmove;
 126:         }
 127:         player[ipos]--;
 128:         player[ipos+die]++;
 129:     }
 130:     for(k=0;pos[k]!=NIL;k++){
 131:         die=k?die2:die1;
 132:         n=25-pos[k]-die;
 133:         if(n>0 && playee[n]==1){
 134:         playee[n]=0;
 135:         playee[0]++;
 136:         }
 137:     }
 138:     return(0);
 139: 
 140: badmove:
 141:     printf( "Move %d is not legal.\n",ipos);
 142:     while(k--){
 143:         die=k?die2:die1;
 144:         player[pos[k]]++;
 145:         player[pos[k]+die]--;
 146:     }
 147:     return(-1);
 148: }
 149: nextmove(player,playee)
 150: int *player,*playee;
 151: {
 152:     int k;
 153:     imoves=0;
 154:     movegen(player,playee);
 155:     if(die1!=die2){
 156:     k=die1;
 157:     die1=die2;
 158:     die2=k;
 159:     movegen(player,playee);
 160:     }
 161:     if(imoves==0){
 162:         printf( "roll was %d,%d; no white move possible\n",die1,die2);
 163:         return(NIL);
 164:     }
 165:     k=strategy(player,playee);      /*select kth possible move*/
 166:     prtmov(k);
 167:     update(player,playee,k);
 168:     return(0);
 169: }
 170: prtmov(k)
 171: int k;
 172: {
 173:     int n;
 174:     if(k==NIL)printf( "no move possible\n");
 175:     else for(n=0;n<4;n++){
 176:         if(moves[k].pos[n]==NIL)break;
 177:         printf( "    %d, %d",25-moves[k].pos[n],moves[k].mov[n]);
 178:     }
 179:     printf( "\n");
 180: }
 181: update(player,playee,k)
 182: int *player,*playee,k;
 183: {
 184:     int n,t;
 185:     for(n=0;n<4;n++){
 186:         if(moves[k].pos[n]==NIL)break;
 187:         player[moves[k].pos[n]]--;
 188:         player[moves[k].pos[n]+moves[k].mov[n]]++;
 189:         t=25-moves[k].pos[n]-moves[k].mov[n];
 190:         if(t>0 && playee[t]==1){
 191:         playee[0]++;
 192:         playee[t]--;
 193:         }
 194:     }
 195: }
 196: piececount(player,startrow,endrow)
 197: int *player,startrow,endrow;
 198: {
 199:     int sum;
 200:     sum=0;
 201:     while(startrow<=endrow)
 202:     sum=+player[startrow++];
 203:     return(sum);
 204: }
 205: /*
 206: prtmovs()
 207: {
 208: 	int i1,i2;
 209: 	printf( "possible moves are\n");
 210: 	for(i1=0;i1<imoves;i1++){
 211: 		printf( "\n%d",i1);
 212: 		for(i2=0;i2<4;i2++){
 213: 			if(moves[i1].pos[i2]==NIL)break;
 214: 			printf( "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]);
 215: 		}
 216: 	}
 217: 	printf( "\n");
 218: }
 219: */
 220: 
 221: roll()
 222: {
 223:     extern int die1,die2;
 224:     die1=(rand()>>8)%6+1;
 225:     die2=(rand()>>8)%6+1;
 226: }
 227: 
 228: movegen(mover,movee)
 229: int *mover,*movee;
 230: {
 231:     extern int i,j,l,m,count;
 232:     extern int die1,die2;
 233:     int k;
 234:     for(i=0;i<=24;i++){
 235:         count=0;
 236:         if(mover[i]==0)continue;
 237:         if((k=25-i-die1)>0&&movee[k]>=2)
 238:             if(mover[0]>0)break;
 239:             else continue;
 240:         if(k<=0){
 241:             if(piececount(mover,0,18)!=0)break;
 242:             if((i+die1)!=25&&
 243:                 piececount(mover,19,24-die1)!=0)break;
 244:         }
 245:         mover[i]--;
 246:         mover[i+die1]++;
 247:         count=1;
 248:         for(j=0;j<=24;j++){
 249:             if(mover[j]==0)continue;
 250:             if((k=25-j-die2)>0&&movee[k]>=2)
 251:                 if(mover[0]>0)break;
 252:                 else continue;
 253:             if(k<=0){
 254:                 if(piececount(mover,0,18)!=0)break;
 255:                 if((j+die2)!=25&&
 256:                     piececount(mover,19,24-die2)!=0)break;
 257:             }
 258:             mover[j]--;
 259:             mover[j+die2]++;
 260:             count=2;
 261:             if(die1!=die2){
 262:                 moverecord(mover);
 263:                 if(mover[0]>0)break;
 264:                 else continue;
 265:             }
 266:             for(l=0;l<=24;l++){
 267:                 if(mover[l]==0)continue;
 268:                 if((k=25-l-die1)>0&&movee[k]>=2)
 269:                 if(mover[0]>0)break;
 270:                 else continue;
 271:                 if(k<=0){
 272:                 if(piececount(mover,0,18)!=0)break;
 273:                 if((l+die2)!=25&&
 274:                     piececount(mover,19,24-die1)!=0)break;
 275:                 }
 276:                 mover[l]--;
 277:                 mover[l+die1]++;
 278:                 count=3;
 279:                 for(m=0;m<=24;m++){
 280:                 if(mover[m]==0)continue;
 281:                 if((k=25-m-die1)>=0&&movee[k]>=2)
 282:                     if(mover[0]>0)break;
 283:                     else continue;
 284:                 if(k<=0){
 285:                     if(piececount(mover,0,18)!=0)break;
 286:                     if((m+die2)!=25&&
 287:                         piececount(mover,19,24-die1)!=0)break;
 288:                 }
 289:                 count=4;
 290:                 moverecord(mover);
 291:                 if(mover[0]>0)break;
 292:                 }
 293:                 if(count==3)moverecord(mover);
 294:                 else{
 295:                 mover[l]++;
 296:                 mover[l+die1]--;
 297:                 }
 298:                 if(mover[0]>0)break;
 299:             }
 300:             if(count==2)moverecord(mover);
 301:             else{
 302:                 mover[j]++;
 303:                 mover[j+die1]--;
 304:             }
 305:             if(mover[0]>0)break;
 306:         }
 307:         if(count==1)moverecord(mover);
 308:         else{
 309:             mover[i]++;
 310:             mover[i+die1]--;
 311:         }
 312:         if(mover[0]>0)break;
 313:     }
 314: }
 315: moverecord(mover)
 316: int *mover;
 317: {
 318:     extern int i,j,l,m,imoves,count;
 319:     int t;
 320:     if(imoves>=MAXIMOVES)goto undo;;
 321:     for(t=0;t<=3;t++)
 322:         moves[imoves].pos[t]= NIL;
 323:     switch(count){
 324: case 4:
 325:         moves[imoves].pos[3]=m;
 326:         moves[imoves].mov[3]=die1;
 327: case 3:
 328:         moves[imoves].pos[2]=l;
 329:         moves[imoves].mov[2]=die1;
 330: case 2:
 331:         moves[imoves].pos[1]=j;
 332:         moves[imoves].mov[1]=die2;
 333: case 1:
 334:         moves[imoves].pos[0]=i;
 335:         moves[imoves].mov[0]=die1;
 336:         imoves++;
 337:     }
 338: undo:
 339:     switch(count){
 340: case 4:
 341:         break;
 342: case 3:
 343:         mover[l]++;
 344:         mover[l+die1]--;
 345:         break;
 346: case 2:
 347:         mover[j]++;
 348:         mover[j+die2]--;
 349:         break;
 350: case 1:
 351:         mover[i]++;
 352:         mover[i+die1]--;
 353:     }
 354: }
 355: 
 356: 
 357: strategy(player,playee)
 358: int *player,*playee;
 359: {
 360:     extern char level;
 361:     int k,n,nn,bestval,moveval,prob;
 362:     n=0;
 363:     if(imoves==0)return(NIL);
 364:     goodmoves[0]=NIL;
 365:     bestval= -32000;
 366:     for(k=0;k<imoves;k++){
 367:         if((moveval=eval(player,playee,k,&prob))<bestval)continue;
 368:         if(moveval>bestval){
 369:         bestval=moveval;
 370:         n=0;
 371:         }
 372:         if(n<MAXGMOV){
 373:         goodmoves[n]=k;
 374:         probmoves[n++]=prob;
 375:         }
 376:     }
 377:     if(level=='e' && n>1){
 378:         nn=n;
 379:         n=0;
 380:         prob=32000;
 381:         for(k=0;k<nn;k++){
 382:         if((moveval=probmoves[k])>prob)continue;
 383:         if(moveval<prob){
 384:             prob=moveval;
 385:             n=0;
 386:         }
 387:         goodmoves[n]=goodmoves[k];
 388:         probmoves[n++]=probmoves[k];
 389:         }
 390:     }
 391:     return(goodmoves[(rand()>>4)%n]);
 392: }
 393: 
 394: eval(player,playee,k,prob)
 395: int *player,*playee,k,*prob;
 396: {
 397:     extern char level;
 398:     int newtry[31],newother[31],*r,*q,*p,n,sum,first;
 399:     int ii,lastwhite,lastred;
 400:     *prob=sum=0;
 401:     r=player+25;
 402:     p=newtry;
 403:     q=newother;
 404:     while(player<r){
 405:         *p++= *player++;
 406:         *q++= *playee++;
 407:     }
 408:     q=newtry+31;
 409:     for(p=newtry+25;p<q;) *p++ = 0; /*zero out spaces for hit pieces*/
 410:     for(n=0;n<4;n++){
 411:         if(moves[k].pos[n]==NIL)break;
 412:         newtry[moves[k].pos[n]]--;
 413:         newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++;
 414:         if(ii<25 && newother[25-ii]==1){
 415:         newother[25-ii]=0;
 416:         newother[0]++;
 417:         if(ii<=15 && level=='e')sum++;  /*hit if near other's home*/
 418:         }
 419:     }
 420:     for(lastred=0;newother[lastred]==0;lastred++);
 421:     for(lastwhite=0;newtry[lastwhite]==0;lastwhite++);
 422:     lastwhite=25-lastwhite;
 423:     if(lastwhite<=6 && lastwhite<lastred)sum=1000;
 424:     if(lastwhite<lastred && level=='e'
 425:         && lastwhite>6){            /*expert's running game.
 426: 						  First priority to get all
 427: 						  pieces into white's home*/
 428:         for(sum=1000;lastwhite>6;lastwhite--)
 429:         sum=sum-lastwhite*newtry[25-lastwhite];
 430:     }
 431:     for(first=0;first<25;first++)
 432:         if(newother[first]!=0)break;    /*find other's first piece*/
 433:     q=newtry+25;
 434:     for(p=newtry+1;p<q;)if(*p++ > 1)sum++;  /*blocked points are good*/
 435:     if(first>5){    /*only stress removing pieces if homeboard
 436: 			  cannot be hit
 437: 			*/
 438:         q=newtry+31;
 439:         p=newtry+25;
 440:         for(n=6;p<q;n--)
 441:         sum=+ *p++ * n; /*remove pieces, but just barely*/
 442:     }
 443:     if(level!='b'){
 444:         r=newtry+25-first;  /*singles past this point can't be hit*/
 445:         for(p=newtry+7;p<r;)
 446:         if(*p++ == 1)sum--; /*singles are bad after 1st 6 points
 447: 					  if they can be hit*/
 448:         q=newtry+3;
 449:         for(p=newtry;p<q;)sum=- *p++;  /*bad to be on 1st three points*/
 450:     }
 451: 
 452:     for(n=1;n<=4;n++)
 453:         *prob=+ n*getprob(newtry,newother,6*n-5,6*n);
 454:     return(sum);
 455: }
 456: instructions()
 457: {
 458:     printf( "To play backgammon, type the numbers of the points\n");
 459:     printf( "from which pieces are to be moved. Thus, if the\n");
 460:     printf( "roll is '3,5', typing '2 6' will move a piece\n");
 461:     printf( "from point 2 three spaces to point 5,\n");
 462:     printf( "and a piece from point 6 forward to\n");
 463:     printf( "point 11.  If the moves must be made in the\n");
 464:     printf( "opposite order, the first character typed must\n");
 465:     printf( "be a minus ('-'). Thus, typing\n");
 466:     printf( "'-2 6' moves the piece on point 2\n");
 467:     printf( "by 5, and the piece on point 6 by 3.\n");
 468:     printf( "If you want to move a single piece several times,\n");
 469:     printf( "the sequence of points from which it is to be\n");
 470:     printf( "moved must be typed. Thus '14 17' will move\n");
 471:     printf( "a piece from point 14 to point 17 and thence to\n");
 472:     printf( "to point 22.\n");
 473:     printf( "If a double is rolled, you should type four numbers.\n");
 474:     printf( "Red pieces that have been removed from the board by\n");
 475:     printf( "being hit by white are on point 0 and\n");
 476:     printf( "must be brought in before any other move can be made.\n");
 477:     printf( "White pieces that are hit are removed to point 25.\n");
 478:     printf( "You will not be allowed to make an illegal move, or\n");
 479:     printf( "to make too many moves. However, if you make too\n");
 480:     printf( "few moves, the program does not care. In particular\n");
 481:     printf( "you may skip your turn by typing a 'new-line'\n");
 482:     printf( "all by itself.\n\n");
 483: }
 484: 
 485: getprob(player,playee,start,finish)
 486: int *player,*playee,start,finish;
 487: {           /*returns the probability (times 102) that any
 488: 			  pieces belonging to 'player' and lying between
 489: 			  his points 'start' and 'finish' will be hit
 490: 			  by a piece belonging to playee
 491: 			*/
 492:     int k,n,sum;
 493:     sum=0;
 494:     for(;start<=finish;start++){
 495:         if(player[start]==1){
 496:         for(k=1;k<=12;k++){
 497:             if((n=25-start-k)<0)break;
 498:             if(playee[n]!=0)sum=+probability[k];
 499:         }
 500:         }
 501:     }
 502:     return(sum);
 503: }
 504: prtbrd()
 505: {
 506:     int k;
 507:     printf( "White's Home\n");
 508:     for(k=1;k<=6;k++)
 509:         printf( "%4d",k);
 510:     printf( "    ");
 511:     for(k=7;k<=12;k++)printf( "%4d",k);
 512:     putchar('\r' );
 513:     for(k=1;k<=54;k++)putchar('_' );
 514:     putchar('\n' );
 515:     numline(red,white,1,6);
 516:     printf( "    ");
 517:     numline(red,white,7,12);
 518:     putchar('\n' );
 519:     colorline(red,'R',white,'W',1,6);
 520:     printf( "    ");
 521:     colorline(red,'R',white,'W',7,12);
 522:     putchar('\n' );
 523:     if(white[0]!=0)printf( "%28dW\n",white[0]);
 524:     else putchar('\n' );
 525:     if(red[0]!=0)printf( "%28dR\n",red[0]);
 526:     else putchar('\n' );
 527:     colorline(white,'W',red,'R',1,6);
 528:     printf( "    ");
 529:     colorline(white,'W',red,'R',7,12);
 530:     putchar('\n' );
 531:     numline(white,red,1,6);
 532:     printf( "    ");
 533:     numline(white,red,7,12);
 534:     putchar('\r' );
 535:     for(k=1;k<=54;k++)putchar('_' );
 536:     putchar('\n' );
 537:     for(k=24;k>=19;k--)printf( "%4d",k);
 538:     printf( "    ");
 539:     for(k=18;k>=13;k--)printf( "%4d",k);
 540:     printf( "\nRed's Home\n\n\n\n\n");
 541: }
 542: numline(upcol,downcol,start,fin)
 543: int *upcol,*downcol,start,fin;
 544: {
 545:     int k,n;
 546:     for(k=start;k<=fin;k++){
 547:         if((n=upcol[k])!=0 || (n=downcol[25-k])!=0)printf( "%4d",n);
 548:         else printf( "    ");
 549:     }
 550: }
 551: colorline(upcol,c1,downcol,c2,start,fin)
 552: int *upcol,*downcol,start,fin;
 553: char c1,c2;
 554: {
 555:     int k;
 556:     char c;
 557:     for(k=start;k<=fin;k++){
 558:         c=' ';
 559:         if(upcol[k]!=0)c=c1;
 560:         if(downcol[25-k]!=0)c=c2;
 561:     printf( "   %c",c);
 562:     }
 563: }
 564: 
 565: int rrno 0;
 566: 
 567: srand(){
 568:     rrno = _look( 0x40000 );
 569:     _store( 0x40000, rrno+1 );
 570:     }
 571: 
 572: rand(){
 573:     rrno =* 0106273;
 574:     rrno =+ 020202;
 575:     return( rrno & 077777 );
 576:     }
 577: 
 578: _look(p) int *p; {
 579:     return( *p );
 580:     }
 581: 
 582: _store( p, numb ) int *p; {
 583:     *p = numb;
 584:     }

Defined functions

_look defined in line 578; used 1 times
_store defined in line 582; used 1 times
colorline defined in line 551; used 4 times
eval defined in line 394; used 1 times
getprob defined in line 485; used 1 times
getstr defined in line 99; used 4 times
instructions defined in line 456; used 1 times
  • in line 37
main defined in line 28; never used
movegen defined in line 228; used 2 times
moverecord defined in line 315; used 5 times
nextmove defined in line 149; used 1 times
  • in line 53
numline defined in line 542; used 4 times
piececount defined in line 196; used 12 times
play defined in line 106; used 1 times
  • in line 90
prtbrd defined in line 504; used 1 times
  • in line 60
prtmov defined in line 170; used 1 times
rand defined in line 572; used 8 times
roll defined in line 221; used 2 times
strategy defined in line 357; used 1 times
update defined in line 181; used 1 times

Defined variables

count defined in line 14; used 12 times
die1 defined in line 8; used 33 times
die2 defined in line 9; used 24 times
goodmoves defined in line 24; used 5 times
i defined in line 10; used 15 times
imoves defined in line 23; used 16 times
j defined in line 11; used 15 times
l defined in line 12; used 15 times
level defined in line 7; used 9 times
m defined in line 13; used 9 times
probability defined in line 21; used 1 times
probmoves defined in line 25; used 4 times
red defined in line 15; used 13 times
rrno defined in line 565; used 5 times
white defined in line 18; used 13 times

Defined macros

MAXGMOV defined in line 5; used 3 times
MAXIMOVES defined in line 6; used 2 times
NIL defined in line 4; used 14 times
Last modified: 1979-01-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1665
Valid CSS Valid XHTML 1.0 Strict