#include #include # #define NIL (-1) #define MAXGMOV 10 #define MAXIMOVES 1000 char level; /*'b'=beginner, 'i'=intermediate, 'e'=expert*/ int die1; int die2; int i; int j; int l; int m; int count; int red[] = {0,2,0,0,0,0,0,0,0,0,0,0,5, 0,0,0,0,3,0,5,0,0,0,0,0, 0,0,0,0,0,0}; int white[] = {0,2,0,0,0,0,0,0,0,0,0,0,5, 0,0,0,0,3,0,5,0,0,0,0,0, 0,0,0,0,0,0}; int probability[] = {0,11,12,13,14,15,16, 06,05,04,03,02,01}; int imoves; int goodmoves[MAXGMOV] ; int probmoves[MAXGMOV] ; struct {int pos[4],mov[4];} moves[MAXIMOVES] ; int main(int argc, char *argv[]) { int t,k,n,go[5]; char s[100]; go[5]=NIL; srand(); printf( "Do you want instructions? Type 'y' for yes,\n"); printf( "anything else means no.?? "); getstr(s); if(*s=='y')instructions(); printf( "Choose the level of your oppponent.\n"); printf( "Type 'b' for beginner, or 'i' for intermediate.\n"); printf( "Anything else gets you an expert.?? "); level='e'; getstr(s); if(*s=='b')level='b'; else if(*s=='i')level='i'; printf( "You will play red. Do you wan't to move first?\n"); printf( "Type 'y' for yes, anything else means no.?? "); getstr(s); if(*s=='y')goto nowhmove; whitesmv: roll(); printf( "white rolls %d,%d\n",die1,die2); printf( "white's move is:"); if(nextmove(white,red)==NIL)goto nowhmove; if(piececount(white,0,24)==0){ printf( "White wins\n"); printf( "Aren't you ashamed. You've been beaten by a computer.\n"); exit(); } nowhmove: prtbrd(); roll(); retry: printf( "your roll is %d, %d\n",die1,die2); printf( "your move, please?? "); getstr(s); if(*s==0){ printf( "red's move skipped\n"); goto whitesmv; } n=sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]); if((die1!=die2&&n>2)||n>4){ printf( "you've made too many moves\n"); goto retry; } go[n]=NIL; if(*s=='-'){ go[0]= -go[0]; t=die1; die1=die2; die2=t; } for(k=0;k0&&playee[n]>=2)goto badmove; if(n<=0){ if(piececount(player,0,18)!=0)goto badmove; if((ipos+die)!=25&& piececount(player,19,24-die)!=0)goto badmove; } player[ipos]--; player[ipos+die]++; } for(k=0;pos[k]!=NIL;k++){ die=k?die2:die1; n=25-pos[k]-die; if(n>0 && playee[n]==1){ playee[n]=0; playee[0]++; } } return(0); badmove: printf( "Move %d is not legal.\n",ipos); while(k--){ die=k?die2:die1; player[pos[k]]++; player[pos[k]+die]--; } return(-1); } nextmove(player,playee) int *player,*playee; { int k; imoves=0; movegen(player,playee); if(die1!=die2){ k=die1; die1=die2; die2=k; movegen(player,playee); } if(imoves==0){ printf( "roll was %d,%d; no white move possible\n",die1,die2); return(NIL); } k=strategy(player,playee); /*select kth possible move*/ prtmov(k); update(player,playee,k); return(0); } prtmov(k) int k; { int n; if(k==NIL)printf( "no move possible\n"); else for(n=0;n<4;n++){ if(moves[k].pos[n]==NIL)break; printf( " %d, %d",25-moves[k].pos[n],moves[k].mov[n]); } printf( "\n"); } update(player,playee,k) int *player,*playee,k; { int n,t; for(n=0;n<4;n++){ if(moves[k].pos[n]==NIL)break; player[moves[k].pos[n]]--; player[moves[k].pos[n]+moves[k].mov[n]]++; t=25-moves[k].pos[n]-moves[k].mov[n]; if(t>0 && playee[t]==1){ playee[0]++; playee[t]--; } } } piececount(player,startrow,endrow) int *player,startrow,endrow; { int sum; sum=0; while(startrow<=endrow) sum=+player[startrow++]; return(sum); } /* prtmovs() { int i1,i2; printf( "possible moves are\n"); for(i1=0;i1>8)%6+1; die2=(rand()>>8)%6+1; } movegen(mover,movee) int *mover,*movee; { extern int i,j,l,m,count; extern int die1,die2; int k; for(i=0;i<=24;i++){ count=0; if(mover[i]==0)continue; if((k=25-i-die1)>0&&movee[k]>=2) if(mover[0]>0)break; else continue; if(k<=0){ if(piececount(mover,0,18)!=0)break; if((i+die1)!=25&& piececount(mover,19,24-die1)!=0)break; } mover[i]--; mover[i+die1]++; count=1; for(j=0;j<=24;j++){ if(mover[j]==0)continue; if((k=25-j-die2)>0&&movee[k]>=2) if(mover[0]>0)break; else continue; if(k<=0){ if(piececount(mover,0,18)!=0)break; if((j+die2)!=25&& piececount(mover,19,24-die2)!=0)break; } mover[j]--; mover[j+die2]++; count=2; if(die1!=die2){ moverecord(mover); if(mover[0]>0)break; else continue; } for(l=0;l<=24;l++){ if(mover[l]==0)continue; if((k=25-l-die1)>0&&movee[k]>=2) if(mover[0]>0)break; else continue; if(k<=0){ if(piececount(mover,0,18)!=0)break; if((l+die2)!=25&& piececount(mover,19,24-die1)!=0)break; } mover[l]--; mover[l+die1]++; count=3; for(m=0;m<=24;m++){ if(mover[m]==0)continue; if((k=25-m-die1)>=0&&movee[k]>=2) if(mover[0]>0)break; else continue; if(k<=0){ if(piececount(mover,0,18)!=0)break; if((m+die2)!=25&& piececount(mover,19,24-die1)!=0)break; } count=4; moverecord(mover); if(mover[0]>0)break; } if(count==3)moverecord(mover); else{ mover[l]++; mover[l+die1]--; } if(mover[0]>0)break; } if(count==2)moverecord(mover); else{ mover[j]++; mover[j+die1]--; } if(mover[0]>0)break; } if(count==1)moverecord(mover); else{ mover[i]++; mover[i+die1]--; } if(mover[0]>0)break; } } moverecord(mover) int *mover; { extern int i,j,l,m,imoves,count; int t; if(imoves>=MAXIMOVES)goto undo;; for(t=0;t<=3;t++) moves[imoves].pos[t]= NIL; switch(count){ case 4: moves[imoves].pos[3]=m; moves[imoves].mov[3]=die1; case 3: moves[imoves].pos[2]=l; moves[imoves].mov[2]=die1; case 2: moves[imoves].pos[1]=j; moves[imoves].mov[1]=die2; case 1: moves[imoves].pos[0]=i; moves[imoves].mov[0]=die1; imoves++; } undo: switch(count){ case 4: break; case 3: mover[l]++; mover[l+die1]--; break; case 2: mover[j]++; mover[j+die2]--; break; case 1: mover[i]++; mover[i+die1]--; } } strategy(player,playee) int *player,*playee; { extern char level; int k,n,nn,bestval,moveval,prob; n=0; if(imoves==0)return(NIL); goodmoves[0]=NIL; bestval= -32000; for(k=0;kbestval){ bestval=moveval; n=0; } if(n1){ nn=n; n=0; prob=32000; for(k=0;kprob)continue; if(moveval>4)%n]); } eval(player,playee,k,prob) int *player,*playee,k,*prob; { extern char level; int newtry[31],newother[31],*r,*q,*p,n,sum,first; int ii,lastwhite,lastred; *prob=sum=0; r=player+25; p=newtry; q=newother; while(player6){ /*expert's running game. First priority to get all pieces into white's home*/ for(sum=1000;lastwhite>6;lastwhite--) sum=sum-lastwhite*newtry[25-lastwhite]; } for(first=0;first<25;first++) if(newother[first]!=0)break; /*find other's first piece*/ q=newtry+25; for(p=newtry+1;p 1)sum++; /*blocked points are good*/ if(first>5){ /*only stress removing pieces if homeboard cannot be hit */ q=newtry+31; p=newtry+25; for(n=6;p=19;k--)printf( "%4d",k); printf( " "); for(k=18;k>=13;k--)printf( "%4d",k); printf( "\nRed's Home\n\n\n\n\n"); } numline(upcol,downcol,start,fin) int *upcol,*downcol,start,fin; { int k,n; for(k=start;k<=fin;k++){ if((n=upcol[k])!=0 || (n=downcol[25-k])!=0)printf( "%4d",n); else printf( " "); } } colorline(upcol,c1,downcol,c2,start,fin) int *upcol,*downcol,start,fin; char c1,c2; { int k; char c; for(k=start;k<=fin;k++){ c=' '; if(upcol[k]!=0)c=c1; if(downcol[25-k]!=0)c=c2; printf( " %c",c); } } int rrno = 0; srand(){ rrno = _look( 0x40000 ); _store( 0x40000, rrno+1 ); } rand(){ rrno *= 0106273; rrno += 020202; return( rrno & 077777 ); } _look(p) int *p; { return( *p ); } _store( p, numb ) int *p; { *p = numb; }