char level
; /*'b'=beginner, 'i'=intermediate, 'e'=expert*/
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,
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,
int probability
[]{0,11,12,13,14,15,16,
struct {int pos
[4],mov
[4];} moves
[MAXIMOVES
] ;
printf( "Do you want instructions? Type 'y' for yes,\n");
printf( "anything else means no.?? ");
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.?? ");
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.?? ");
if(*s
=='y')goto nowhmove
;
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( "Aren't you ashamed. You've been beaten by a computer.\n");
printf( "your roll is %d, %d\n",die1
,die2
);
printf( "your move, please?? ");
printf( "red's move skipped\n");
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");
if(0<=go
[k
] && go
[k
]<=24)continue;
printf( "move %d is illegal\n",go
[k
]);
if(play(red
,white
,go
))goto retry
;
if(piececount(red
,0,24)==0){
printf( "Congratulations! You have just defeated a dumb machine.\n");
while((*s
=getchar())!='\n')s
++;
int *player
,*playee
,pos
[];
for(k
=0;k
<player
[0];k
++){ /*blots on player[0] must be moved first*/
printf( "piece on position 0 must be moved first\n");
for(k
=0;(ipos
=pos
[k
])!=NIL
;k
++){
if(player
[ipos
]==0)goto badmove
;
if(n
>0&&playee
[n
]>=2)goto badmove
;
if(piececount(player
,0,18)!=0)goto badmove
;
piececount(player
,19,24-die
)!=0)goto badmove
;
for(k
=0;pos
[k
]!=NIL
;k
++){
printf( "Move %d is not legal.\n",ipos
);
printf( "roll was %d,%d; no white move possible\n",die1
,die2
);
k
=strategy(player
,playee
); /*select kth possible move*/
if(k
==NIL
)printf( "no move possible\n");
if(moves
[k
].pos
[n
]==NIL
)break;
printf( " %d, %d",25-moves
[k
].pos
[n
],moves
[k
].mov
[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
];
piececount(player
,startrow
,endrow
)
int *player
,startrow
,endrow
;
printf( "possible moves are\n");
for(i1=0;i1<imoves;i1++){
if(moves[i1].pos[i2]==NIL)break;
printf( "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]);
extern int i
,j
,l
,m
,count
;
if((k
=25-i
-die1
)>0&&movee
[k
]>=2)
if(piececount(mover
,0,18)!=0)break;
piececount(mover
,19,24-die1
)!=0)break;
if((k
=25-j
-die2
)>0&&movee
[k
]>=2)
if(piececount(mover
,0,18)!=0)break;
piececount(mover
,19,24-die2
)!=0)break;
if((k
=25-l
-die1
)>0&&movee
[k
]>=2)
if(piececount(mover
,0,18)!=0)break;
piececount(mover
,19,24-die1
)!=0)break;
if((k
=25-m
-die1
)>=0&&movee
[k
]>=2)
if(piececount(mover
,0,18)!=0)break;
piececount(mover
,19,24-die1
)!=0)break;
if(count
==3)moverecord(mover
);
if(count
==2)moverecord(mover
);
if(count
==1)moverecord(mover
);
extern int i
,j
,l
,m
,imoves
,count
;
if(imoves
>=MAXIMOVES
)goto undo
;;
moves
[imoves
].pos
[t
]= NIL
;
moves
[imoves
].mov
[3]=die1
;
moves
[imoves
].mov
[2]=die1
;
moves
[imoves
].mov
[1]=die2
;
moves
[imoves
].mov
[0]=die1
;
int k
,n
,nn
,bestval
,moveval
,prob
;
if(imoves
==0)return(NIL
);
if((moveval
=eval(player
,playee
,k
,&prob
))<bestval
)continue;
if((moveval
=probmoves
[k
])>prob
)continue;
goodmoves
[n
]=goodmoves
[k
];
probmoves
[n
++]=probmoves
[k
];
return(goodmoves
[(rand()>>4)%n
]);
eval(player
,playee
,k
,prob
)
int *player
,*playee
,k
,*prob
;
int newtry
[31],newother
[31],*r
,*q
,*p
,n
,sum
,first
;
int ii
,lastwhite
,lastred
;
for(p
=newtry
+25;p
<q
;) *p
++ = 0; /*zero out spaces for hit pieces*/
if(moves
[k
].pos
[n
]==NIL
)break;
newtry
[moves
[k
].pos
[n
]]--;
newtry
[ii
=moves
[k
].pos
[n
]+moves
[k
].mov
[n
]]++;
if(ii
<25 && newother
[25-ii
]==1){
if(ii
<=15 && level
=='e')sum
++; /*hit if near other's home*/
for(lastred
=0;newother
[lastred
]==0;lastred
++);
for(lastwhite
=0;newtry
[lastwhite
]==0;lastwhite
++);
if(lastwhite
<=6 && lastwhite
<lastred
)sum
=1000;
if(lastwhite
<lastred
&& level
=='e'
&& lastwhite
>6){ /*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*/
for(p
=newtry
+1;p
<q
;)if(*p
++ > 1)sum
++; /*blocked points are good*/
if(first
>5){ /*only stress removing pieces if homeboard
sum
=+ *p
++ * n
; /*remove pieces, but just barely*/
r
=newtry
+25-first
; /*singles past this point can't be hit*/
if(*p
++ == 1)sum
--; /*singles are bad after 1st 6 points
for(p
=newtry
;p
<q
;)sum
=- *p
++; /*bad to be on 1st three points*/
*prob
=+ n
*getprob(newtry
,newother
,6*n
-5,6*n
);
printf( "To play backgammon, type the numbers of the points\n");
printf( "from which pieces are to be moved. Thus, if the\n");
printf( "roll is '3,5', typing '2 6' will move a piece\n");
printf( "from point 2 three spaces to point 5,\n");
printf( "and a piece from point 6 forward to\n");
printf( "point 11. If the moves must be made in the\n");
printf( "opposite order, the first character typed must\n");
printf( "be a minus ('-'). Thus, typing\n");
printf( "'-2 6' moves the piece on point 2\n");
printf( "by 5, and the piece on point 6 by 3.\n");
printf( "If you want to move a single piece several times,\n");
printf( "the sequence of points from which it is to be\n");
printf( "moved must be typed. Thus '14 17' will move\n");
printf( "a piece from point 14 to point 17 and thence to\n");
printf( "to point 22.\n");
printf( "If a double is rolled, you should type four numbers.\n");
printf( "Red pieces that have been removed from the board by\n");
printf( "being hit by white are on point 0 and\n");
printf( "must be brought in before any other move can be made.\n");
printf( "White pieces that are hit are removed to point 25.\n");
printf( "You will not be allowed to make an illegal move, or\n");
printf( "to make too many moves. However, if you make too\n");
printf( "few moves, the program does not care. In particular\n");
printf( "you may skip your turn by typing a 'new-line'\n");
printf( "all by itself.\n\n");
getprob(player
,playee
,start
,finish
)
int *player
,*playee
,start
,finish
;
{ /*returns the probability (times 102) that any
pieces belonging to 'player' and lying between
his points 'start' and 'finish' will be hit
by a piece belonging to playee
for(;start
<=finish
;start
++){
if((n
=25-start
-k
)<0)break;
if(playee
[n
]!=0)sum
=+probability
[k
];
printf( "White's Home\n");
for(k
=7;k
<=12;k
++)printf( "%4d",k
);
for(k
=1;k
<=54;k
++)putchar('_' );
colorline(red
,'R',white
,'W',1,6);
colorline(red
,'R',white
,'W',7,12);
if(white
[0]!=0)printf( "%28dW\n",white
[0]);
if(red
[0]!=0)printf( "%28dR\n",red
[0]);
colorline(white
,'W',red
,'R',1,6);
colorline(white
,'W',red
,'R',7,12);
for(k
=1;k
<=54;k
++)putchar('_' );
for(k
=24;k
>=19;k
--)printf( "%4d",k
);
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
;
if((n
=upcol
[k
])!=0 || (n
=downcol
[25-k
])!=0)printf( "%4d",n
);
colorline(upcol
,c1
,downcol
,c2
,start
,fin
)
int *upcol
,*downcol
,start
,fin
;
if(downcol
[25-k
]!=0)c
=c2
;
_store( 0x40000, rrno
+1 );
_store( p
, numb
) int *p
; {