147852Sbostic /*-
2*60746Sbostic  * Copyright (c) 1991, 1993
3*60746Sbostic  *	The Regents of the University of California.  All rights reserved.
447852Sbostic  *
547852Sbostic  * %sccs.include.redist.c%
647852Sbostic  */
78853Smckusick 
847852Sbostic #ifndef lint
9*60746Sbostic static char sccsid[] = "@(#)backgammon.c	8.1 (Berkeley) 05/31/93";
1047852Sbostic #endif /* not lint */
118853Smckusick 
128853Smckusick /*
138853Smckusick **	The game of Backgammon
148853Smckusick */
158853Smckusick 
168853Smckusick #include	<stdio.h>
178853Smckusick 
188853Smckusick #define	WHITE		0
198853Smckusick #define	BROWN		1
208853Smckusick #define	NIL		(-1)
218853Smckusick #define	MAXGMOV		10
228853Smckusick #define	MAXIMOVES	1000
238853Smckusick #define	RULES		"/usr/games/lib/backrules"
248853Smckusick 
258853Smckusick char	level;		/*'b'=beginner, 'i'=intermediate, 'e'=expert*/
268853Smckusick 
278853Smckusick int	die1;
288853Smckusick int	die2;
298853Smckusick int	i;
308853Smckusick int	j;
318853Smckusick int	l;
328853Smckusick int	m;
338853Smckusick int	pflg = 1;
348853Smckusick int	nobroll = 0;
358853Smckusick int	count;
368853Smckusick int	imoves;
378853Smckusick int	goodmoves[MAXGMOV];
388853Smckusick int	probmoves[MAXGMOV];
398853Smckusick 
408853Smckusick int	brown[] = {		/* brown position table */
418853Smckusick 	0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
428853Smckusick 	0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
438853Smckusick 	0, 0, 0, 0, 0, 0
448853Smckusick };
458853Smckusick 
468853Smckusick int	white[] = {		/* white position table */
478853Smckusick 	0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
488853Smckusick 	0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
498853Smckusick 	0, 0, 0, 0, 0, 0
508853Smckusick };
518853Smckusick 
528853Smckusick int	probability[] = {
538853Smckusick 	0, 11, 12, 13, 14, 15, 16,
548853Smckusick 	06, 05, 04, 03, 02, 01
558853Smckusick };
568853Smckusick 
578853Smckusick struct	{
588853Smckusick 	int	pos[4];
598853Smckusick 	int	mov[4];
608853Smckusick } moves[MAXIMOVES];
618853Smckusick 
main()628853Smckusick main()
638853Smckusick {
648853Smckusick 	int	go[5], tvec[2];
658853Smckusick 	int	k, n, pid, ret, rpid, t;
668853Smckusick 	char	s[100];
678853Smckusick 
688853Smckusick 	srand(time(0));
698853Smckusick 	go[5] = NIL;
708853Smckusick 	fprintf(stdout, "Instructions? ");
718853Smckusick 	gets(s);
728853Smckusick 	if(*s == 'y')
738853Smckusick 		instructions();
748853Smckusick 	putchar('\n');
758853Smckusick 	fprintf(stdout, "Opponent's level: b - beginner,\n");
768853Smckusick 	fprintf(stdout, "i - intermediate, e - expert? ");
778853Smckusick 	level='e';
788853Smckusick 	gets(s);
798853Smckusick 	if(*s == 'b')
808853Smckusick 		level = 'b';
818853Smckusick 	else if(*s == 'i')
828853Smckusick 		level = 'i';
838853Smckusick 	putchar('\n');
848853Smckusick 	fprintf(stdout, "You will play brown.\n\n");
858853Smckusick 	fprintf(stdout, "Would you like to roll your own dice? ");
868853Smckusick 	gets(s);
878853Smckusick 	putchar('\n');
888853Smckusick 	if(*s == 'y')
898853Smckusick 		nobroll = 1;
908853Smckusick 	fprintf(stdout, "Would you like to go first? ");
918853Smckusick 	gets(s);
928853Smckusick 	putchar('\n');
938853Smckusick 	if(*s == 'y')
948853Smckusick 		goto nowhmove;
958853Smckusick whitesmv:
968853Smckusick 	roll(WHITE);
978853Smckusick 	fprintf(stdout, "white rolls %d, %d\n", die1, die2);
988853Smckusick 	fprintf(stdout, "white's move is:");
998853Smckusick 	if(nextmove(white, brown) == NIL)
1008853Smckusick 		goto nowhmove;
1018853Smckusick 	if(piececount(white, 0, 24) == 0){
1028853Smckusick 		fprintf(stdout, "White wins");
1038853Smckusick 		if(piececount(brown, 0, 6) != 0)
1048853Smckusick 			fprintf(stdout, " with a Backgammon!\n");
1058853Smckusick 		else if (piececount(brown, 0, 24) == 24)
1068853Smckusick 			fprintf(stdout, " with a Gammon.\n");
1078853Smckusick 		else
1088853Smckusick 			fprintf(stdout, ".\n");
1098853Smckusick 		exit(0);
1108853Smckusick 	}
1118853Smckusick nowhmove:
1128853Smckusick 	if(pflg)
1138853Smckusick 		prtbrd();
1148853Smckusick 	roll(BROWN);
1158853Smckusick retry:
1168853Smckusick 	fprintf(stdout, "\nYour roll is %d  %d\n", die1, die2);
1178853Smckusick 	fprintf(stdout, "Move? ");
1188853Smckusick 	gets(s);
1198853Smckusick 	switch(*s) {
1208853Smckusick 		case '\0':			/* empty line */
1218853Smckusick 			fprintf(stdout, "Brown's move skipped.\n");
1228853Smckusick 			goto whitesmv;
1238853Smckusick 
1248853Smckusick 		case 'b':			/* how many beared off? */
1258853Smckusick 			fprintf(stdout, "Brown:   %d\n", piececount(brown, 0, 24) - 15);
1268853Smckusick 			fprintf(stdout, "White:   %d\n", piececount(white, 0, 24) - 15);
1278853Smckusick 			goto retry;
1288853Smckusick 
1298853Smckusick 		case 'p':			/* print board */
1308853Smckusick 			prtbrd();
1318853Smckusick 			goto retry;
1328853Smckusick 
1338853Smckusick 		case 's':			/* stop auto printing of board */
1348853Smckusick 			pflg = 0;
1358853Smckusick 			goto retry;
1368853Smckusick 
1378853Smckusick 		case 'r':			/* resume auto printing */
1388853Smckusick 			pflg = 1;
1398853Smckusick 			goto retry;
1408853Smckusick 
1418853Smckusick 		case 'm':			/* print possible moves */
1428853Smckusick 			pmoves();
1438853Smckusick 			goto retry;
1448853Smckusick 
1458853Smckusick 		case 'q':			/* i give up */
1468853Smckusick 			exit(0);
1478853Smckusick 
1488853Smckusick 		case '!':			/* escape to Shell */
1498853Smckusick 			if(s[1] != '\0')
1508853Smckusick 				system(s+1);
1518853Smckusick 			else if((pid = fork()) == 0) {
1528853Smckusick 				execl("/bin/sh", "sh", "-", 0);
1538853Smckusick 				fprintf(stderr, "back: cannot exec /bin/sh!\n");
1548853Smckusick 				exit(2);
1558853Smckusick 			}
1568853Smckusick 			while((rpid = wait(&ret)) != pid && rpid != -1)
1578853Smckusick 				;
1588853Smckusick 			goto retry;
1598853Smckusick 
1608853Smckusick 		case '?':			/* well, what can i do? */
1618853Smckusick 			fprintf(stdout, "<newline>	skip this move\n");
1628853Smckusick 			fprintf(stdout, "b		number beared off\n");
1638853Smckusick 			fprintf(stdout, "p		print board\n");
1648853Smckusick 			fprintf(stdout, "q		quit\n");
1658853Smckusick 			fprintf(stdout, "r		resume auto print of board\n");
1668853Smckusick 			fprintf(stdout, "s		stop auto print of board\n");
1678853Smckusick 			fprintf(stdout, "!		escape to Shell\n");
1688853Smckusick 			goto retry;
1698853Smckusick 	}
1708853Smckusick 	n = sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]);
1718853Smckusick 	if((die1 != die2 && n > 2) || n > 4){
1728853Smckusick 		fprintf(stdout, "Too many moves.\n");
1738853Smckusick 		goto retry;
1748853Smckusick 	}
1758853Smckusick 	go[n] = NIL;
1768853Smckusick 	if(*s=='-'){
1778853Smckusick 		go[0]= -go[0];
1788853Smckusick 		t=die1;
1798853Smckusick 		die1=die2;
1808853Smckusick 		die2=t;
1818853Smckusick 	}
1828853Smckusick 	for(k = 0; k < n; k++){
1838853Smckusick 		if(0 <= go[k] && go[k] <= 24)
1848853Smckusick 			continue;
1858853Smckusick 		else{
1868853Smckusick 			fprintf(stdout, "Move %d illegal.\n", go[k]);
1878853Smckusick 			goto retry;
1888853Smckusick 		}
1898853Smckusick 	}
1908853Smckusick 	if(play(brown, white, go))
1918853Smckusick 		goto retry;
1928853Smckusick 	if(piececount(brown, 0, 24) == 0){
1938853Smckusick 		fprintf(stdout, "Brown wins");
1948853Smckusick 		if(piececount(white, 0, 6) != 0)
1958853Smckusick 			fprintf(stdout, " with a Backgammon.\n");
1968853Smckusick 		else if(piececount(white, 0, 24) == 24)
1978853Smckusick 			fprintf(stdout, " with a gammon.\n");
1988853Smckusick 		else
1998853Smckusick 			fprintf(stdout, ".\n");
2008853Smckusick 		exit(0);
2018853Smckusick 	}
2028853Smckusick 	goto whitesmv;
2038853Smckusick }
2048853Smckusick 
play(player,playee,pos)2058853Smckusick play(player,playee,pos)
2068853Smckusick int *player,*playee,pos[];
2078853Smckusick {
2088853Smckusick 	int	k, n, die, ipos;
2098853Smckusick 
2108853Smckusick 	for(k=0; k < player[0]; k++){  /*blots on player[0] must be moved first*/
2118853Smckusick 		if(pos[k] == NIL)
2128853Smckusick 			break;
2138853Smckusick 		if(pos[k] != 0){
2148853Smckusick 			fprintf(stdout, "Stone on bar must be moved first.\n");
2158853Smckusick 			return(NIL);
2168853Smckusick 		}
2178853Smckusick 	}
2188853Smckusick 	for(k = 0; (ipos=pos[k]) != NIL; k++){
2198853Smckusick 		die = k?die2:die1;
2208853Smckusick 		n = 25-ipos-die;
2218853Smckusick 		if(player[ipos] == 0)
2228853Smckusick 			goto badmove;
2238853Smckusick 		if(n > 0 && playee[n] >= 2)
2248853Smckusick 			goto badmove;
2258853Smckusick 		if(n <= 0){
2268853Smckusick 			if(piececount(player,0,18) != 0)
2278853Smckusick 				goto badmove;
2288853Smckusick 			if((ipos+die) != 25 && piececount(player,19,24-die)!=0)
2298853Smckusick 				goto badmove;
2308853Smckusick 		}
2318853Smckusick 		player[ipos]--;
2328853Smckusick 		player[ipos+die]++;
2338853Smckusick 	}
2348853Smckusick 	for(k = 0; pos[k] != NIL; k++){
2358853Smckusick 		die = k?die2:die1;
2368853Smckusick 		n = 25-pos[k]-die;
2378853Smckusick 		if(n>0 && playee[n]==1){
2388853Smckusick 			playee[n]=0;
2398853Smckusick 			playee[0]++;
2408853Smckusick 		}
2418853Smckusick 	}
2428853Smckusick 	return(0);
2438853Smckusick 
2448853Smckusick badmove:
2458853Smckusick 	fprintf(stdout, "Move %d illegal.\n", ipos);
2468853Smckusick 	while(k--){
2478853Smckusick 		die=k?die2:die1;
2488853Smckusick 		player[pos[k]]++;
2498853Smckusick 		player[pos[k]+die]--;
2508853Smckusick 	}
2518853Smckusick 	return(NIL);
2528853Smckusick }
nextmove(player,playee)2538853Smckusick nextmove(player,playee)
2548853Smckusick int *player,*playee;
2558853Smckusick {
2568853Smckusick 	int	k;
2578853Smckusick 
2588853Smckusick 	imoves=0;
2598853Smckusick 	movegen(player,playee);
2608853Smckusick 	if(die1!=die2){
2618853Smckusick 		k=die1;
2628853Smckusick 		die1=die2;
2638853Smckusick 		die2=k;
2648853Smckusick 		movegen(player,playee);
2658853Smckusick 	}
2668853Smckusick 	if(imoves==0){
2678853Smckusick 		fprintf(stdout, "no move possible.\n");
2688853Smckusick 		return(NIL);
2698853Smckusick 	}
2708853Smckusick 	k=strategy(player,playee);		/*select kth possible move*/
2718853Smckusick 	prtmov(k);
2728853Smckusick 	update(player,playee,k);
2738853Smckusick 	return(0);
2748853Smckusick }
prtmov(k)2758853Smckusick prtmov(k)
2768853Smckusick int k;
2778853Smckusick {
2788853Smckusick 	int	n;
2798853Smckusick 
2808853Smckusick 	if(k == NIL)
2818853Smckusick 		fprintf(stdout, "No move possible\n");
2828853Smckusick 	else for(n = 0; n < 4; n++){
2838853Smckusick 		if(moves[k].pos[n] == NIL)
2848853Smckusick 			break;
2858853Smckusick 		fprintf(stdout, "    %d, %d",25-moves[k].pos[n],moves[k].mov[n]);
2868853Smckusick 	}
2878853Smckusick 	fprintf(stdout, "\n");
2888853Smckusick }
update(player,playee,k)2898853Smckusick update(player,playee,k)
2908853Smckusick int *player,*playee,k;
2918853Smckusick {
2928853Smckusick 	int	n,t;
2938853Smckusick 
2948853Smckusick 	for(n = 0; n < 4; n++){
2958853Smckusick 		if(moves[k].pos[n] == NIL)
2968853Smckusick 			break;
2978853Smckusick 		player[moves[k].pos[n]]--;
2988853Smckusick 		player[moves[k].pos[n]+moves[k].mov[n]]++;
2998853Smckusick 		t=25-moves[k].pos[n]-moves[k].mov[n];
3008853Smckusick 		if(t>0 && playee[t]==1){
3018853Smckusick 			playee[0]++;
3028853Smckusick 			playee[t]--;
3038853Smckusick 		}
3048853Smckusick 	}
3058853Smckusick }
piececount(player,startrow,endrow)3068853Smckusick piececount(player,startrow,endrow)
3078853Smckusick int *player,startrow,endrow;
3088853Smckusick {
3098853Smckusick 	int	sum;
3108853Smckusick 
3118853Smckusick 	sum=0;
3128853Smckusick 	while(startrow <= endrow)
3138853Smckusick 		sum += player[startrow++];
3148853Smckusick 	return(sum);
3158853Smckusick }
pmoves()3168853Smckusick pmoves()
3178853Smckusick {
3188853Smckusick 	int	i1, i2;
3198853Smckusick 
3208853Smckusick 	fprintf(stdout, "Possible moves are:\n");
3218853Smckusick 	for(i1 = 0; i1 < imoves; i1++){
3228853Smckusick 		fprintf(stdout, "\n%d",i1);
3238853Smckusick 		 for (i2 = 0; i2<4; i2++){
3248853Smckusick 			if(moves[i1].pos[i2] == NIL)
3258853Smckusick 				break;
3268853Smckusick 			fprintf(stdout, "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]);
3278853Smckusick 		}
3288853Smckusick 	}
3298853Smckusick 	fprintf(stdout, "\n");
3308853Smckusick }
3318853Smckusick 
roll(who)3328853Smckusick roll(who)
3338853Smckusick {
3348853Smckusick 	register n;
3358853Smckusick 	char	 s[10];
3368853Smckusick 
3378853Smckusick 	if(who == BROWN && nobroll) {
3388853Smckusick 		fprintf(stdout, "Roll? ");
3398853Smckusick 		gets(s);
3408853Smckusick 		n = sscanf(s, "%d%d", &die1, &die2);
3418853Smckusick 		if(n != 2 || die1 < 1 || die1 > 6 || die2 < 1 || die2 > 6)
3428853Smckusick 			fprintf(stdout, "Illegal - I'll do it!\n");
3438853Smckusick 		else
3448853Smckusick 			return;
3458853Smckusick 	}
3468853Smckusick 	die1 = ((rand()>>8) % 6) + 1;
3478853Smckusick 	die2 = ((rand()>>8) % 6) + 1;
3488853Smckusick }
3498853Smckusick 
movegen(mover,movee)3508853Smckusick movegen(mover,movee)
3518853Smckusick int *mover,*movee;
3528853Smckusick {
3538853Smckusick 	int	k;
3548853Smckusick 
3558853Smckusick 	for(i = 0; i <= 24; i++){
3568853Smckusick 		count = 0;
3578853Smckusick 		if(mover[i] == 0)
3588853Smckusick 			continue;
3598853Smckusick 		if((k=25-i-die1) > 0 && movee[k] >= 2)
3608853Smckusick 			if(mover[0] > 0)
3618853Smckusick 				break;
3628853Smckusick 		else
3638853Smckusick 			continue;
3648853Smckusick 		if(k <= 0){
3658853Smckusick 			if(piececount(mover, 0, 18) != 0)
3668853Smckusick 				break;
3678853Smckusick 			if((i+die1) != 25 && piececount(mover,19,i-1) != 0)
3688853Smckusick 				break;
3698853Smckusick 		}
3708853Smckusick 		mover[i]--;
3718853Smckusick 		mover[i+die1]++;
3728853Smckusick 		count = 1;
3738853Smckusick 		for(j = 0; j <= 24; j++){
3748853Smckusick 			if(mover[j]==0)
3758853Smckusick 				continue;
3768853Smckusick 			if((k=25-j-die2) > 0 && movee[k] >= 2)
3778853Smckusick 				if(mover[0] > 0)
3788853Smckusick 					break;
3798853Smckusick 			else
3808853Smckusick 				continue;
3818853Smckusick 			if(k <= 0){
3828853Smckusick 				if(piececount(mover,0,18) != 0)
3838853Smckusick 					break;
3848853Smckusick 				if((j+die2) != 25 && piececount(mover,19,j-1) != 0)
3858853Smckusick 					break;
3868853Smckusick 			}
3878853Smckusick 			mover[j]--;
3888853Smckusick 			mover[j+die2]++;
3898853Smckusick 			count = 2;
3908853Smckusick 			if(die1 != die2){
3918853Smckusick 				moverecord(mover);
3928853Smckusick 				if(mover[0] > 0)
3938853Smckusick 					break;
3948853Smckusick 				else
3958853Smckusick 					continue;
3968853Smckusick 			}
3978853Smckusick 			for(l = 0; l <= 24; l++){
3988853Smckusick 				if(mover[l] == 0)
3998853Smckusick 					continue;
4008853Smckusick 				if((k=25-l-die1) > 0 && movee[k] >= 2)
4018853Smckusick 					if(mover[0] > 0)
4028853Smckusick 						break;
4038853Smckusick 				else
4048853Smckusick 					continue;
4058853Smckusick 				if(k <= 0){
4068853Smckusick 					if(piececount(mover, 0, 18) != 0)
4078853Smckusick 						break;
4088853Smckusick 					if((l+die2) != 25 && piececount(mover,19,l-1) != 0)
4098853Smckusick 						break;
4108853Smckusick 				}
4118853Smckusick 				mover[l]--;
4128853Smckusick 				mover[l+die1]++;
4138853Smckusick 				count=3;
4148853Smckusick 				for(m=0;m<=24;m++){
4158853Smckusick 					if(mover[m]==0)
4168853Smckusick 						continue;
4178853Smckusick 					if((k=25-m-die1) >= 0 && movee[k] >= 2)
4188853Smckusick 						if(mover[0] > 0)
4198853Smckusick 							break;
4208853Smckusick 					else
4218853Smckusick 						continue;
4228853Smckusick 					if(k <= 0){
4238853Smckusick 						if(piececount(mover,0,18) != 0)
4248853Smckusick 							break;
4258853Smckusick 						if((m+die2) != 25 && piececount(mover,19,m-1) != 0)
4268853Smckusick 							break;
4278853Smckusick 					}
4288853Smckusick 					count=4;
4298853Smckusick 					moverecord(mover);
4308853Smckusick 					if(mover[0] > 0)
4318853Smckusick 						break;
4328853Smckusick 				}
4338853Smckusick 				if(count == 3)
4348853Smckusick 					moverecord(mover);
4358853Smckusick 				else{
4368853Smckusick 					mover[l]++;
4378853Smckusick 					mover[l+die1]--;
4388853Smckusick 				}
4398853Smckusick 				if(mover[0] > 0)
4408853Smckusick 					break;
4418853Smckusick 			}
4428853Smckusick 			if(count == 2)
4438853Smckusick 				moverecord(mover);
4448853Smckusick 			else{
4458853Smckusick 				mover[j]++;
4468853Smckusick 				mover[j+die1]--;
4478853Smckusick 			}
4488853Smckusick 			if(mover[0] > 0)
4498853Smckusick 				break;
4508853Smckusick 		}
4518853Smckusick 		if(count == 1)
4528853Smckusick 			moverecord(mover);
4538853Smckusick 		else{
4548853Smckusick 			mover[i]++;
4558853Smckusick 			mover[i+die1]--;
4568853Smckusick 		}
4578853Smckusick 		if(mover[0] > 0)
4588853Smckusick 			break;
4598853Smckusick 	}
4608853Smckusick }
moverecord(mover)4618853Smckusick moverecord(mover)
4628853Smckusick int *mover;
4638853Smckusick {
4648853Smckusick 	int	t;
4658853Smckusick 
4668853Smckusick 	if(imoves < MAXIMOVES) {
4678853Smckusick 		for(t = 0; t <= 3; t++)
4688853Smckusick 			moves[imoves].pos[t] = NIL;
4698853Smckusick 		switch(count) {
4708853Smckusick 		case 4:
4718853Smckusick 			moves[imoves].pos[3]=m;
4728853Smckusick 			moves[imoves].mov[3]=die1;
4738853Smckusick 
4748853Smckusick 		case 3:
4758853Smckusick 			moves[imoves].pos[2]=l;
4768853Smckusick 			moves[imoves].mov[2]=die1;
4778853Smckusick 
4788853Smckusick 		case 2:
4798853Smckusick 			moves[imoves].pos[1]=j;
4808853Smckusick 			moves[imoves].mov[1]=die2;
4818853Smckusick 
4828853Smckusick 		case 1:
4838853Smckusick 			moves[imoves].pos[0]=i;
4848853Smckusick 			moves[imoves].mov[0]=die1;
4858853Smckusick 			imoves++;
4868853Smckusick 		}
4878853Smckusick 	}
4888853Smckusick 	switch(count) {
4898853Smckusick 	case 4:
4908853Smckusick 		break;
4918853Smckusick 
4928853Smckusick 	case 3:
4938853Smckusick 		mover[l]++;
4948853Smckusick 		mover[l+die1]--;
4958853Smckusick 		break;
4968853Smckusick 
4978853Smckusick 	case 2:
4988853Smckusick 		mover[j]++;
4998853Smckusick 		mover[j+die2]--;
5008853Smckusick 		break;
5018853Smckusick 
5028853Smckusick 	case 1:
5038853Smckusick 		mover[i]++;
5048853Smckusick 		mover[i+die1]--;
5058853Smckusick 	}
5068853Smckusick }
5078853Smckusick 
strategy(player,playee)5088853Smckusick strategy(player,playee)
5098853Smckusick int *player,*playee;
5108853Smckusick {
5118853Smckusick 	int	k, n, nn, bestval, moveval, prob;
5128853Smckusick 
5138853Smckusick 	n = 0;
5148853Smckusick 	if(imoves == 0)
5158853Smckusick 		return(NIL);
5168853Smckusick 	goodmoves[0] = NIL;
5178853Smckusick 	bestval = -32000;
5188853Smckusick 	for(k = 0; k < imoves; k++){
5198853Smckusick 		if((moveval=eval(player,playee,k,&prob)) < bestval)
5208853Smckusick 			continue;
5218853Smckusick 		if(moveval > bestval){
5228853Smckusick 			bestval = moveval;
5238853Smckusick 			n = 0;
5248853Smckusick 		}
5258853Smckusick 		if(n<MAXGMOV){
5268853Smckusick 			goodmoves[n]=k;
5278853Smckusick 			probmoves[n++]=prob;
5288853Smckusick 		}
5298853Smckusick 	}
5308853Smckusick 	if(level=='e' && n>1){
5318853Smckusick 		nn=n;
5328853Smckusick 		n=0;
5338853Smckusick 		prob=32000;
5348853Smckusick 		for(k = 0; k < nn; k++){
5358853Smckusick 			if((moveval=probmoves[k]) > prob)
5368853Smckusick 				continue;
5378853Smckusick 			if(moveval<prob){
5388853Smckusick 				prob=moveval;
5398853Smckusick 				n=0;
5408853Smckusick 			}
5418853Smckusick 			goodmoves[n]=goodmoves[k];
5428853Smckusick 			probmoves[n++]=probmoves[k];
5438853Smckusick 		}
5448853Smckusick 	}
5458853Smckusick 	return(goodmoves[(rand()>>4)%n]);
5468853Smckusick }
5478853Smckusick 
eval(player,playee,k,prob)5488853Smckusick eval(player,playee,k,prob)
5498853Smckusick int *player,*playee,k,*prob;
5508853Smckusick {
5518853Smckusick 	int	newtry[31], newother[31], *r, *q, *p, n, sum, first;
5528853Smckusick 	int	ii, lastwhite, lastbrown;
5538853Smckusick 
5548853Smckusick 	*prob = sum = 0;
5558853Smckusick 	r = player+25;
5568853Smckusick 	p = newtry;
5578853Smckusick 	q = newother;
5588853Smckusick 	while(player<r){
5598853Smckusick 		*p++= *player++;
5608853Smckusick 		*q++= *playee++;
5618853Smckusick 	}
5628853Smckusick 	q=newtry+31;
5638853Smckusick 	for(p = newtry+25; p < q; p++)		/* zero out spaces for hit pieces */
5648853Smckusick 		*p = 0;
5658853Smckusick 	for(n = 0; n < 4; n++){
5668853Smckusick 		if(moves[k].pos[n] == NIL)
5678853Smckusick 			break;
5688853Smckusick 		newtry[moves[k].pos[n]]--;
5698853Smckusick 		newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++;
5708853Smckusick 		if(ii<25 && newother[25-ii]==1){
5718853Smckusick 			newother[25-ii]=0;
5728853Smckusick 			newother[0]++;
5738853Smckusick 			if(ii<=15 && level=='e')		/* hit if near other's home */
5748853Smckusick 				sum++;
5758853Smckusick 		}
5768853Smckusick 	}
5778853Smckusick 	for(lastbrown = 0; newother[lastbrown] == 0; lastbrown++);
5788853Smckusick 		;
5798853Smckusick 	for(lastwhite = 0; newtry[lastwhite] == 0; lastwhite++)
5808853Smckusick 		;
5818853Smckusick 	lastwhite = 25-lastwhite;
5828853Smckusick 	if(lastwhite<=6 && lastwhite<lastbrown)
5838853Smckusick 		sum=1000;
5848853Smckusick 									/* experts running game. */
5858853Smckusick 									/* first priority is to */
5868853Smckusick 									/* get all pieces into */
5878853Smckusick 									/* white's home */
5888853Smckusick 	if(lastwhite<lastbrown && level=='e' && lastwhite>6) {
5898853Smckusick 		for(sum = 1000; lastwhite > 6; lastwhite--)
5908853Smckusick 			sum = sum-lastwhite*newtry[25-lastwhite];
5918853Smckusick 	}
5928853Smckusick 	for(first = 0; first < 25; first++)
5938853Smckusick 		if(newother[first] != 0)		/*find other's first piece*/
5948853Smckusick 			break;
5958853Smckusick 	q = newtry+25;
5968853Smckusick 	for(p = newtry+1; p < q;)			/* blocked points are good */
5978853Smckusick 		if(*p++ > 1)
5988853Smckusick 			sum++;
5998853Smckusick 	if(first > 5) {					/* only stress removing pieces if */
6008853Smckusick 							/* homeboard cannot be hit */
6018853Smckusick 		q = newtry+31;
6028853Smckusick 		p=newtry+25;
6038853Smckusick 		for(n = 6; p < q; n--)
6048853Smckusick 			sum += *p++ * n;			/*remove pieces, but just barely*/
6058853Smckusick 	}
6068853Smckusick 	if(level != 'b'){
6078853Smckusick 		r = newtry+25-first;	/*singles past this point can't be hit*/
6088853Smckusick 		for(p = newtry+7; p < r; )
6098853Smckusick 			if(*p++ == 1)		/*singles are bad after 1st 6 points if they can be hit*/
6108853Smckusick 				sum--;
6118853Smckusick 		q = newtry+3;
6128853Smckusick 		for(p = newtry; p < q; )	   /*bad to be on 1st three points*/
6138853Smckusick 			sum -= *p++;
6148853Smckusick 	}
6158853Smckusick 
6168853Smckusick 	for(n = 1; n <= 4; n++)
6178853Smckusick 		*prob += n*getprob(newtry,newother,6*n-5,6*n);
6188853Smckusick 	return(sum);
6198853Smckusick }
instructions()6208853Smckusick instructions()
6218853Smckusick {
6228853Smckusick 	register fd, r;
6238853Smckusick 	char	 buf[BUFSIZ];
6248853Smckusick 
6258853Smckusick 	if((fd = open(RULES, 0)) < 0) {
6268853Smckusick 		fprintf(stderr, "back: cannot open %s\n", RULES);
6278853Smckusick 		return;
6288853Smckusick 	}
6298853Smckusick 	while(r = read(fd, buf, BUFSIZ))
6308853Smckusick 		write(1, buf, r);
6318853Smckusick }
6328853Smckusick 
getprob(player,playee,start,finish)6338853Smckusick getprob(player,playee,start,finish)
6348853Smckusick int *player,*playee,start,finish;
6358853Smckusick {			/*returns the probability (times 102) that any
6368853Smckusick 			  pieces belonging to 'player' and lying between
6378853Smckusick 			  his points 'start' and 'finish' will be hit
6388853Smckusick 			  by a piece belonging to playee
6398853Smckusick 			*/
6408853Smckusick 	int	k, n, sum;
6418853Smckusick 
6428853Smckusick 	sum = 0;
6438853Smckusick 	for(; start <= finish; start++){
6448853Smckusick 		if(player[start] == 1){
6458853Smckusick 			for(k = 1; k <= 12; k++){
6468853Smckusick 				if((n=25-start-k) < 0)
6478853Smckusick 					break;
6488853Smckusick 				if(playee[n] != 0)
6498853Smckusick 					sum += probability[k];
6508853Smckusick 			}
6518853Smckusick 		}
6528853Smckusick 	}
6538853Smckusick 	return(sum);
6548853Smckusick }
prtbrd()6558853Smckusick prtbrd()
6568853Smckusick {
6578853Smckusick 	int	k;
6588853Smckusick 	static char undersc[]="______________________________________________________";
6598853Smckusick 
6608853Smckusick 	fprintf(stdout, "White's Home\n%s\r",undersc);
6618853Smckusick 	for(k = 1; k <= 6; k++)
6628853Smckusick 		fprintf(stdout, "%4d",k);
6638853Smckusick 	fprintf(stdout, "    ");
6648853Smckusick 	for(k = 7; k <= 12; k++)
6658853Smckusick 		fprintf(stdout, "%4d",k);
6668853Smckusick 	putchar('\n');
6678853Smckusick 	numline(brown, white, 1, 6);
6688853Smckusick 	fprintf(stdout, "    ");
6698853Smckusick 	numline(brown, white, 7, 12);
6708853Smckusick 	putchar('\n');
6718853Smckusick 	colorline(brown, 'B', white, 'W', 1, 6);
6728853Smckusick 	fprintf(stdout, "    ");
6738853Smckusick 	colorline(brown, 'B', white, 'W', 7, 12);
6748853Smckusick 	putchar('\n');
6758853Smckusick 	if(white[0] != 0)
6768853Smckusick 		fprintf(stdout, "%28dW\n",white[0]);
6778853Smckusick 	else
6788853Smckusick 		putchar('\n');
6798853Smckusick 	if(brown[0] != 0)
6808853Smckusick 		fprintf(stdout, "%28dB\n", brown[0]);
6818853Smckusick 	else
6828853Smckusick 		putchar('\n');
6838853Smckusick 	colorline(white, 'W', brown, 'B', 1, 6);
6848853Smckusick 	fprintf(stdout, "    ");
6858853Smckusick 	colorline(white, 'W', brown, 'B', 7, 12);
6868853Smckusick 	fprintf(stdout, "\n%s\r",undersc);
6878853Smckusick 	numline(white, brown, 1, 6);
6888853Smckusick 	fprintf(stdout, "    ");
6898853Smckusick 	numline(white, brown, 7, 12);
6908853Smckusick 	putchar('\n');
6918853Smckusick 	for(k = 24; k >= 19; k--)
6928853Smckusick 		fprintf(stdout, "%4d",k);
6938853Smckusick 	fprintf(stdout, "    ");
6948853Smckusick 	for(k = 18; k >= 13; k--)
6958853Smckusick 		fprintf(stdout, "%4d",k);
6968853Smckusick 	fprintf(stdout, "\nBrown's Home\n\n\n\n\n");
6978853Smckusick }
numline(upcol,downcol,start,fin)6988853Smckusick numline(upcol,downcol,start,fin)
6998853Smckusick int *upcol,*downcol,start,fin;
7008853Smckusick {
7018853Smckusick 	int	k, n;
7028853Smckusick 
7038853Smckusick 	for(k = start; k <= fin; k++){
7048853Smckusick 		if((n = upcol[k]) != 0 || (n = downcol[25-k]) != 0)
7058853Smckusick 			fprintf(stdout, "%4d", n);
7068853Smckusick 		else
7078853Smckusick 			fprintf(stdout, "    ");
7088853Smckusick 	}
7098853Smckusick }
colorline(upcol,c1,downcol,c2,start,fin)7108853Smckusick colorline(upcol,c1,downcol,c2,start,fin)
7118853Smckusick int *upcol,*downcol,start,fin;
7128853Smckusick char c1,c2;
7138853Smckusick {
7148853Smckusick 	int	k;
7158853Smckusick 	char 	c;
7168853Smckusick 
7178853Smckusick 	for(k = start; k <= fin; k++){
7188853Smckusick 		c = ' ';
7198853Smckusick 		if(upcol[k] != 0)
7208853Smckusick 			c = c1;
7218853Smckusick 		if(downcol[25-k] != 0)
7228853Smckusick 			c = c2;
7238853Smckusick 		fprintf(stdout, "   %c",c);
7248853Smckusick 	}
7258853Smckusick }
726