Annotation of researchv10no/games/back.c, revision 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.