Annotation of researchv10no/games/back.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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