xref: /csrg-svn/old/btlgammon/btlgammon.c (revision 32225)
132224Sbostic #ifndef lint
2*32225Sbostic static char sccsid[] = "@(#)btlgammon.c	1.2 (Berkeley) 09/20/87";
332224Sbostic #endif not lint
432224Sbostic 
532224Sbostic /*
632224Sbostic **	The game of Backgammon
732224Sbostic */
832224Sbostic 
932224Sbostic #include	<stdio.h>
1032224Sbostic 
1132224Sbostic #define	WHITE		0
1232224Sbostic #define	BROWN		1
1332224Sbostic #define	NIL		(-1)
1432224Sbostic #define	MAXGMOV		10
1532224Sbostic #define	MAXIMOVES	1000
1632224Sbostic #define	RULES		"/usr/games/lib/backrules"
1732224Sbostic 
1832224Sbostic char	level;		/*'b'=beginner, 'i'=intermediate, 'e'=expert*/
1932224Sbostic 
2032224Sbostic int	die1;
2132224Sbostic int	die2;
2232224Sbostic int	i;
2332224Sbostic int	j;
2432224Sbostic int	l;
2532224Sbostic int	m;
2632224Sbostic int	pflg = 1;
2732224Sbostic int	nobroll = 0;
2832224Sbostic int	count;
2932224Sbostic int	imoves;
3032224Sbostic int	goodmoves[MAXGMOV];
3132224Sbostic int	probmoves[MAXGMOV];
3232224Sbostic 
3332224Sbostic int	brown[] = {		/* brown position table */
3432224Sbostic 	0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
3532224Sbostic 	0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
3632224Sbostic 	0, 0, 0, 0, 0, 0
3732224Sbostic };
3832224Sbostic 
3932224Sbostic int	white[] = {		/* white position table */
4032224Sbostic 	0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
4132224Sbostic 	0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
4232224Sbostic 	0, 0, 0, 0, 0, 0
4332224Sbostic };
4432224Sbostic 
4532224Sbostic int	probability[] = {
4632224Sbostic 	0, 11, 12, 13, 14, 15, 16,
4732224Sbostic 	06, 05, 04, 03, 02, 01
4832224Sbostic };
4932224Sbostic 
5032224Sbostic struct	{
5132224Sbostic 	int	pos[4];
5232224Sbostic 	int	mov[4];
5332224Sbostic } moves[MAXIMOVES];
5432224Sbostic 
main()5532224Sbostic main()
5632224Sbostic {
5732224Sbostic 	int	go[5], tvec[2];
5832224Sbostic 	int	k, n, pid, ret, rpid, t;
5932224Sbostic 	char	s[100];
6032224Sbostic 
6132224Sbostic 	srand(time(0));
6232224Sbostic 	go[5] = NIL;
6332224Sbostic 	fprintf(stdout, "Instructions? ");
6432224Sbostic 	gets(s);
6532224Sbostic 	if(*s == 'y')
6632224Sbostic 		instructions();
6732224Sbostic 	putchar('\n');
6832224Sbostic 	fprintf(stdout, "Opponent's level: b - beginner,\n");
6932224Sbostic 	fprintf(stdout, "i - intermediate, e - expert? ");
7032224Sbostic 	level='e';
7132224Sbostic 	gets(s);
7232224Sbostic 	if(*s == 'b')
7332224Sbostic 		level = 'b';
7432224Sbostic 	else if(*s == 'i')
7532224Sbostic 		level = 'i';
7632224Sbostic 	putchar('\n');
7732224Sbostic 	fprintf(stdout, "You will play brown.\n\n");
7832224Sbostic 	fprintf(stdout, "Would you like to roll your own dice? ");
7932224Sbostic 	gets(s);
8032224Sbostic 	putchar('\n');
8132224Sbostic 	if(*s == 'y')
8232224Sbostic 		nobroll = 1;
8332224Sbostic 	fprintf(stdout, "Would you like to go first? ");
8432224Sbostic 	gets(s);
8532224Sbostic 	putchar('\n');
8632224Sbostic 	if(*s == 'y')
8732224Sbostic 		goto nowhmove;
8832224Sbostic whitesmv:
8932224Sbostic 	roll(WHITE);
9032224Sbostic 	fprintf(stdout, "white rolls %d, %d\n", die1, die2);
9132224Sbostic 	fprintf(stdout, "white's move is:");
9232224Sbostic 	if(nextmove(white, brown) == NIL)
9332224Sbostic 		goto nowhmove;
9432224Sbostic 	if(piececount(white, 0, 24) == 0){
9532224Sbostic 		fprintf(stdout, "White wins");
9632224Sbostic 		if(piececount(brown, 0, 6) != 0)
9732224Sbostic 			fprintf(stdout, " with a Backgammon!\n");
9832224Sbostic 		else if (piececount(brown, 0, 24) == 24)
9932224Sbostic 			fprintf(stdout, " with a Gammon.\n");
10032224Sbostic 		else
10132224Sbostic 			fprintf(stdout, ".\n");
10232224Sbostic 		exit(0);
10332224Sbostic 	}
10432224Sbostic nowhmove:
10532224Sbostic 	if(pflg)
10632224Sbostic 		prtbrd();
10732224Sbostic 	roll(BROWN);
10832224Sbostic retry:
10932224Sbostic 	fprintf(stdout, "\nYour roll is %d  %d\n", die1, die2);
11032224Sbostic 	fprintf(stdout, "Move? ");
11132224Sbostic 	gets(s);
11232224Sbostic 	switch(*s) {
11332224Sbostic 		case '\0':			/* empty line */
11432224Sbostic 			fprintf(stdout, "Brown's move skipped.\n");
11532224Sbostic 			goto whitesmv;
11632224Sbostic 
11732224Sbostic 		case 'b':			/* how many beared off? */
11832224Sbostic 			fprintf(stdout, "Brown:   %d\n", piececount(brown, 0, 24) - 15);
11932224Sbostic 			fprintf(stdout, "White:   %d\n", piececount(white, 0, 24) - 15);
12032224Sbostic 			goto retry;
12132224Sbostic 
12232224Sbostic 		case 'p':			/* print board */
12332224Sbostic 			prtbrd();
12432224Sbostic 			goto retry;
12532224Sbostic 
12632224Sbostic 		case 's':			/* stop auto printing of board */
12732224Sbostic 			pflg = 0;
12832224Sbostic 			goto retry;
12932224Sbostic 
13032224Sbostic 		case 'r':			/* resume auto printing */
13132224Sbostic 			pflg = 1;
13232224Sbostic 			goto retry;
13332224Sbostic 
13432224Sbostic 		case 'm':			/* print possible moves */
13532224Sbostic 			pmoves();
13632224Sbostic 			goto retry;
13732224Sbostic 
13832224Sbostic 		case 'q':			/* i give up */
13932224Sbostic 			exit(0);
14032224Sbostic 
14132224Sbostic 		case '!':			/* escape to Shell */
142*32225Sbostic #ifdef ADD_A_MAJOR_SECURITY_HOLE
14332224Sbostic 			if(s[1] != '\0')
14432224Sbostic 				system(s+1);
145*32225Sbostic 			else
146*32225Sbostic #endif
147*32225Sbostic 			if (!(pid = vfork()) == 0) {
148*32225Sbostic 				(void)setuid(getuid());
149*32225Sbostic 				(void)setgid(getgid());
15032224Sbostic 				execl("/bin/sh", "sh", "-", 0);
15132224Sbostic 				fprintf(stderr, "back: cannot exec /bin/sh!\n");
15232224Sbostic 				exit(2);
15332224Sbostic 			}
15432224Sbostic 			while((rpid = wait(&ret)) != pid && rpid != -1)
15532224Sbostic 				;
15632224Sbostic 			goto retry;
15732224Sbostic 
15832224Sbostic 		case '?':			/* well, what can i do? */
15932224Sbostic 			fprintf(stdout, "<newline>	skip this move\n");
16032224Sbostic 			fprintf(stdout, "b		number beared off\n");
16132224Sbostic 			fprintf(stdout, "p		print board\n");
16232224Sbostic 			fprintf(stdout, "q		quit\n");
16332224Sbostic 			fprintf(stdout, "r		resume auto print of board\n");
16432224Sbostic 			fprintf(stdout, "s		stop auto print of board\n");
16532224Sbostic 			fprintf(stdout, "!		escape to Shell\n");
16632224Sbostic 			goto retry;
16732224Sbostic 	}
16832224Sbostic 	n = sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]);
16932224Sbostic 	if((die1 != die2 && n > 2) || n > 4){
17032224Sbostic 		fprintf(stdout, "Too many moves.\n");
17132224Sbostic 		goto retry;
17232224Sbostic 	}
17332224Sbostic 	go[n] = NIL;
17432224Sbostic 	if(*s=='-'){
17532224Sbostic 		go[0]= -go[0];
17632224Sbostic 		t=die1;
17732224Sbostic 		die1=die2;
17832224Sbostic 		die2=t;
17932224Sbostic 	}
18032224Sbostic 	for(k = 0; k < n; k++){
18132224Sbostic 		if(0 <= go[k] && go[k] <= 24)
18232224Sbostic 			continue;
18332224Sbostic 		else{
18432224Sbostic 			fprintf(stdout, "Move %d illegal.\n", go[k]);
18532224Sbostic 			goto retry;
18632224Sbostic 		}
18732224Sbostic 	}
18832224Sbostic 	if(play(brown, white, go))
18932224Sbostic 		goto retry;
19032224Sbostic 	if(piececount(brown, 0, 24) == 0){
19132224Sbostic 		fprintf(stdout, "Brown wins");
19232224Sbostic 		if(piececount(white, 0, 6) != 0)
19332224Sbostic 			fprintf(stdout, " with a Backgammon.\n");
19432224Sbostic 		else if(piececount(white, 0, 24) == 24)
19532224Sbostic 			fprintf(stdout, " with a gammon.\n");
19632224Sbostic 		else
19732224Sbostic 			fprintf(stdout, ".\n");
19832224Sbostic 		exit(0);
19932224Sbostic 	}
20032224Sbostic 	goto whitesmv;
20132224Sbostic }
20232224Sbostic 
play(player,playee,pos)20332224Sbostic play(player,playee,pos)
20432224Sbostic int *player,*playee,pos[];
20532224Sbostic {
20632224Sbostic 	int	k, n, die, ipos;
20732224Sbostic 
20832224Sbostic 	for(k=0; k < player[0]; k++){  /*blots on player[0] must be moved first*/
20932224Sbostic 		if(pos[k] == NIL)
21032224Sbostic 			break;
21132224Sbostic 		if(pos[k] != 0){
21232224Sbostic 			fprintf(stdout, "Stone on bar must be moved first.\n");
21332224Sbostic 			return(NIL);
21432224Sbostic 		}
21532224Sbostic 	}
21632224Sbostic 	for(k = 0; (ipos=pos[k]) != NIL; k++){
21732224Sbostic 		die = k?die2:die1;
21832224Sbostic 		n = 25-ipos-die;
21932224Sbostic 		if(player[ipos] == 0)
22032224Sbostic 			goto badmove;
22132224Sbostic 		if(n > 0 && playee[n] >= 2)
22232224Sbostic 			goto badmove;
22332224Sbostic 		if(n <= 0){
22432224Sbostic 			if(piececount(player,0,18) != 0)
22532224Sbostic 				goto badmove;
22632224Sbostic 			if((ipos+die) != 25 && piececount(player,19,24-die)!=0)
22732224Sbostic 				goto badmove;
22832224Sbostic 		}
22932224Sbostic 		player[ipos]--;
23032224Sbostic 		player[ipos+die]++;
23132224Sbostic 	}
23232224Sbostic 	for(k = 0; pos[k] != NIL; k++){
23332224Sbostic 		die = k?die2:die1;
23432224Sbostic 		n = 25-pos[k]-die;
23532224Sbostic 		if(n>0 && playee[n]==1){
23632224Sbostic 			playee[n]=0;
23732224Sbostic 			playee[0]++;
23832224Sbostic 		}
23932224Sbostic 	}
24032224Sbostic 	return(0);
24132224Sbostic 
24232224Sbostic badmove:
24332224Sbostic 	fprintf(stdout, "Move %d illegal.\n", ipos);
24432224Sbostic 	while(k--){
24532224Sbostic 		die=k?die2:die1;
24632224Sbostic 		player[pos[k]]++;
24732224Sbostic 		player[pos[k]+die]--;
24832224Sbostic 	}
24932224Sbostic 	return(NIL);
25032224Sbostic }
nextmove(player,playee)25132224Sbostic nextmove(player,playee)
25232224Sbostic int *player,*playee;
25332224Sbostic {
25432224Sbostic 	int	k;
25532224Sbostic 
25632224Sbostic 	imoves=0;
25732224Sbostic 	movegen(player,playee);
25832224Sbostic 	if(die1!=die2){
25932224Sbostic 		k=die1;
26032224Sbostic 		die1=die2;
26132224Sbostic 		die2=k;
26232224Sbostic 		movegen(player,playee);
26332224Sbostic 	}
26432224Sbostic 	if(imoves==0){
26532224Sbostic 		fprintf(stdout, "no move possible.\n");
26632224Sbostic 		return(NIL);
26732224Sbostic 	}
26832224Sbostic 	k=strategy(player,playee);		/*select kth possible move*/
26932224Sbostic 	prtmov(k);
27032224Sbostic 	update(player,playee,k);
27132224Sbostic 	return(0);
27232224Sbostic }
prtmov(k)27332224Sbostic prtmov(k)
27432224Sbostic int k;
27532224Sbostic {
27632224Sbostic 	int	n;
27732224Sbostic 
27832224Sbostic 	if(k == NIL)
27932224Sbostic 		fprintf(stdout, "No move possible\n");
28032224Sbostic 	else for(n = 0; n < 4; n++){
28132224Sbostic 		if(moves[k].pos[n] == NIL)
28232224Sbostic 			break;
28332224Sbostic 		fprintf(stdout, "    %d, %d",25-moves[k].pos[n],moves[k].mov[n]);
28432224Sbostic 	}
28532224Sbostic 	fprintf(stdout, "\n");
28632224Sbostic }
update(player,playee,k)28732224Sbostic update(player,playee,k)
28832224Sbostic int *player,*playee,k;
28932224Sbostic {
29032224Sbostic 	int	n,t;
29132224Sbostic 
29232224Sbostic 	for(n = 0; n < 4; n++){
29332224Sbostic 		if(moves[k].pos[n] == NIL)
29432224Sbostic 			break;
29532224Sbostic 		player[moves[k].pos[n]]--;
29632224Sbostic 		player[moves[k].pos[n]+moves[k].mov[n]]++;
29732224Sbostic 		t=25-moves[k].pos[n]-moves[k].mov[n];
29832224Sbostic 		if(t>0 && playee[t]==1){
29932224Sbostic 			playee[0]++;
30032224Sbostic 			playee[t]--;
30132224Sbostic 		}
30232224Sbostic 	}
30332224Sbostic }
piececount(player,startrow,endrow)30432224Sbostic piececount(player,startrow,endrow)
30532224Sbostic int *player,startrow,endrow;
30632224Sbostic {
30732224Sbostic 	int	sum;
30832224Sbostic 
30932224Sbostic 	sum=0;
31032224Sbostic 	while(startrow <= endrow)
31132224Sbostic 		sum += player[startrow++];
31232224Sbostic 	return(sum);
31332224Sbostic }
pmoves()31432224Sbostic pmoves()
31532224Sbostic {
31632224Sbostic 	int	i1, i2;
31732224Sbostic 
31832224Sbostic 	fprintf(stdout, "Possible moves are:\n");
31932224Sbostic 	for(i1 = 0; i1 < imoves; i1++){
32032224Sbostic 		fprintf(stdout, "\n%d",i1);
32132224Sbostic 		 for (i2 = 0; i2<4; i2++){
32232224Sbostic 			if(moves[i1].pos[i2] == NIL)
32332224Sbostic 				break;
32432224Sbostic 			fprintf(stdout, "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]);
32532224Sbostic 		}
32632224Sbostic 	}
32732224Sbostic 	fprintf(stdout, "\n");
32832224Sbostic }
32932224Sbostic 
roll(who)33032224Sbostic roll(who)
33132224Sbostic {
33232224Sbostic 	register n;
33332224Sbostic 	char	 s[10];
33432224Sbostic 
33532224Sbostic 	if(who == BROWN && nobroll) {
33632224Sbostic 		fprintf(stdout, "Roll? ");
33732224Sbostic 		gets(s);
33832224Sbostic 		n = sscanf(s, "%d%d", &die1, &die2);
33932224Sbostic 		if(n != 2 || die1 < 1 || die1 > 6 || die2 < 1 || die2 > 6)
34032224Sbostic 			fprintf(stdout, "Illegal - I'll do it!\n");
34132224Sbostic 		else
34232224Sbostic 			return;
34332224Sbostic 	}
34432224Sbostic 	die1 = ((rand()>>8) % 6) + 1;
34532224Sbostic 	die2 = ((rand()>>8) % 6) + 1;
34632224Sbostic }
34732224Sbostic 
movegen(mover,movee)34832224Sbostic movegen(mover,movee)
34932224Sbostic int *mover,*movee;
35032224Sbostic {
35132224Sbostic 	int	k;
35232224Sbostic 
35332224Sbostic 	for(i = 0; i <= 24; i++){
35432224Sbostic 		count = 0;
35532224Sbostic 		if(mover[i] == 0)
35632224Sbostic 			continue;
35732224Sbostic 		if((k=25-i-die1) > 0 && movee[k] >= 2)
35832224Sbostic 			if(mover[0] > 0)
35932224Sbostic 				break;
36032224Sbostic 		else
36132224Sbostic 			continue;
36232224Sbostic 		if(k <= 0){
36332224Sbostic 			if(piececount(mover, 0, 18) != 0)
36432224Sbostic 				break;
36532224Sbostic 			if((i+die1) != 25 && piececount(mover,19,i-1) != 0)
36632224Sbostic 				break;
36732224Sbostic 		}
36832224Sbostic 		mover[i]--;
36932224Sbostic 		mover[i+die1]++;
37032224Sbostic 		count = 1;
37132224Sbostic 		for(j = 0; j <= 24; j++){
37232224Sbostic 			if(mover[j]==0)
37332224Sbostic 				continue;
37432224Sbostic 			if((k=25-j-die2) > 0 && movee[k] >= 2)
37532224Sbostic 				if(mover[0] > 0)
37632224Sbostic 					break;
37732224Sbostic 			else
37832224Sbostic 				continue;
37932224Sbostic 			if(k <= 0){
38032224Sbostic 				if(piececount(mover,0,18) != 0)
38132224Sbostic 					break;
38232224Sbostic 				if((j+die2) != 25 && piececount(mover,19,j-1) != 0)
38332224Sbostic 					break;
38432224Sbostic 			}
38532224Sbostic 			mover[j]--;
38632224Sbostic 			mover[j+die2]++;
38732224Sbostic 			count = 2;
38832224Sbostic 			if(die1 != die2){
38932224Sbostic 				moverecord(mover);
39032224Sbostic 				if(mover[0] > 0)
39132224Sbostic 					break;
39232224Sbostic 				else
39332224Sbostic 					continue;
39432224Sbostic 			}
39532224Sbostic 			for(l = 0; l <= 24; l++){
39632224Sbostic 				if(mover[l] == 0)
39732224Sbostic 					continue;
39832224Sbostic 				if((k=25-l-die1) > 0 && movee[k] >= 2)
39932224Sbostic 					if(mover[0] > 0)
40032224Sbostic 						break;
40132224Sbostic 				else
40232224Sbostic 					continue;
40332224Sbostic 				if(k <= 0){
40432224Sbostic 					if(piececount(mover, 0, 18) != 0)
40532224Sbostic 						break;
40632224Sbostic 					if((l+die2) != 25 && piececount(mover,19,l-1) != 0)
40732224Sbostic 						break;
40832224Sbostic 				}
40932224Sbostic 				mover[l]--;
41032224Sbostic 				mover[l+die1]++;
41132224Sbostic 				count=3;
41232224Sbostic 				for(m=0;m<=24;m++){
41332224Sbostic 					if(mover[m]==0)
41432224Sbostic 						continue;
41532224Sbostic 					if((k=25-m-die1) >= 0 && movee[k] >= 2)
41632224Sbostic 						if(mover[0] > 0)
41732224Sbostic 							break;
41832224Sbostic 					else
41932224Sbostic 						continue;
42032224Sbostic 					if(k <= 0){
42132224Sbostic 						if(piececount(mover,0,18) != 0)
42232224Sbostic 							break;
42332224Sbostic 						if((m+die2) != 25 && piececount(mover,19,m-1) != 0)
42432224Sbostic 							break;
42532224Sbostic 					}
42632224Sbostic 					count=4;
42732224Sbostic 					moverecord(mover);
42832224Sbostic 					if(mover[0] > 0)
42932224Sbostic 						break;
43032224Sbostic 				}
43132224Sbostic 				if(count == 3)
43232224Sbostic 					moverecord(mover);
43332224Sbostic 				else{
43432224Sbostic 					mover[l]++;
43532224Sbostic 					mover[l+die1]--;
43632224Sbostic 				}
43732224Sbostic 				if(mover[0] > 0)
43832224Sbostic 					break;
43932224Sbostic 			}
44032224Sbostic 			if(count == 2)
44132224Sbostic 				moverecord(mover);
44232224Sbostic 			else{
44332224Sbostic 				mover[j]++;
44432224Sbostic 				mover[j+die1]--;
44532224Sbostic 			}
44632224Sbostic 			if(mover[0] > 0)
44732224Sbostic 				break;
44832224Sbostic 		}
44932224Sbostic 		if(count == 1)
45032224Sbostic 			moverecord(mover);
45132224Sbostic 		else{
45232224Sbostic 			mover[i]++;
45332224Sbostic 			mover[i+die1]--;
45432224Sbostic 		}
45532224Sbostic 		if(mover[0] > 0)
45632224Sbostic 			break;
45732224Sbostic 	}
45832224Sbostic }
moverecord(mover)45932224Sbostic moverecord(mover)
46032224Sbostic int *mover;
46132224Sbostic {
46232224Sbostic 	int	t;
46332224Sbostic 
46432224Sbostic 	if(imoves < MAXIMOVES) {
46532224Sbostic 		for(t = 0; t <= 3; t++)
46632224Sbostic 			moves[imoves].pos[t] = NIL;
46732224Sbostic 		switch(count) {
46832224Sbostic 		case 4:
46932224Sbostic 			moves[imoves].pos[3]=m;
47032224Sbostic 			moves[imoves].mov[3]=die1;
47132224Sbostic 
47232224Sbostic 		case 3:
47332224Sbostic 			moves[imoves].pos[2]=l;
47432224Sbostic 			moves[imoves].mov[2]=die1;
47532224Sbostic 
47632224Sbostic 		case 2:
47732224Sbostic 			moves[imoves].pos[1]=j;
47832224Sbostic 			moves[imoves].mov[1]=die2;
47932224Sbostic 
48032224Sbostic 		case 1:
48132224Sbostic 			moves[imoves].pos[0]=i;
48232224Sbostic 			moves[imoves].mov[0]=die1;
48332224Sbostic 			imoves++;
48432224Sbostic 		}
48532224Sbostic 	}
48632224Sbostic 	switch(count) {
48732224Sbostic 	case 4:
48832224Sbostic 		break;
48932224Sbostic 
49032224Sbostic 	case 3:
49132224Sbostic 		mover[l]++;
49232224Sbostic 		mover[l+die1]--;
49332224Sbostic 		break;
49432224Sbostic 
49532224Sbostic 	case 2:
49632224Sbostic 		mover[j]++;
49732224Sbostic 		mover[j+die2]--;
49832224Sbostic 		break;
49932224Sbostic 
50032224Sbostic 	case 1:
50132224Sbostic 		mover[i]++;
50232224Sbostic 		mover[i+die1]--;
50332224Sbostic 	}
50432224Sbostic }
50532224Sbostic 
strategy(player,playee)50632224Sbostic strategy(player,playee)
50732224Sbostic int *player,*playee;
50832224Sbostic {
50932224Sbostic 	int	k, n, nn, bestval, moveval, prob;
51032224Sbostic 
51132224Sbostic 	n = 0;
51232224Sbostic 	if(imoves == 0)
51332224Sbostic 		return(NIL);
51432224Sbostic 	goodmoves[0] = NIL;
51532224Sbostic 	bestval = -32000;
51632224Sbostic 	for(k = 0; k < imoves; k++){
51732224Sbostic 		if((moveval=eval(player,playee,k,&prob)) < bestval)
51832224Sbostic 			continue;
51932224Sbostic 		if(moveval > bestval){
52032224Sbostic 			bestval = moveval;
52132224Sbostic 			n = 0;
52232224Sbostic 		}
52332224Sbostic 		if(n<MAXGMOV){
52432224Sbostic 			goodmoves[n]=k;
52532224Sbostic 			probmoves[n++]=prob;
52632224Sbostic 		}
52732224Sbostic 	}
52832224Sbostic 	if(level=='e' && n>1){
52932224Sbostic 		nn=n;
53032224Sbostic 		n=0;
53132224Sbostic 		prob=32000;
53232224Sbostic 		for(k = 0; k < nn; k++){
53332224Sbostic 			if((moveval=probmoves[k]) > prob)
53432224Sbostic 				continue;
53532224Sbostic 			if(moveval<prob){
53632224Sbostic 				prob=moveval;
53732224Sbostic 				n=0;
53832224Sbostic 			}
53932224Sbostic 			goodmoves[n]=goodmoves[k];
54032224Sbostic 			probmoves[n++]=probmoves[k];
54132224Sbostic 		}
54232224Sbostic 	}
54332224Sbostic 	return(goodmoves[(rand()>>4)%n]);
54432224Sbostic }
54532224Sbostic 
eval(player,playee,k,prob)54632224Sbostic eval(player,playee,k,prob)
54732224Sbostic int *player,*playee,k,*prob;
54832224Sbostic {
54932224Sbostic 	int	newtry[31], newother[31], *r, *q, *p, n, sum, first;
55032224Sbostic 	int	ii, lastwhite, lastbrown;
55132224Sbostic 
55232224Sbostic 	*prob = sum = 0;
55332224Sbostic 	r = player+25;
55432224Sbostic 	p = newtry;
55532224Sbostic 	q = newother;
55632224Sbostic 	while(player<r){
55732224Sbostic 		*p++= *player++;
55832224Sbostic 		*q++= *playee++;
55932224Sbostic 	}
56032224Sbostic 	q=newtry+31;
56132224Sbostic 	for(p = newtry+25; p < q; p++)		/* zero out spaces for hit pieces */
56232224Sbostic 		*p = 0;
56332224Sbostic 	for(n = 0; n < 4; n++){
56432224Sbostic 		if(moves[k].pos[n] == NIL)
56532224Sbostic 			break;
56632224Sbostic 		newtry[moves[k].pos[n]]--;
56732224Sbostic 		newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++;
56832224Sbostic 		if(ii<25 && newother[25-ii]==1){
56932224Sbostic 			newother[25-ii]=0;
57032224Sbostic 			newother[0]++;
57132224Sbostic 			if(ii<=15 && level=='e')		/* hit if near other's home */
57232224Sbostic 				sum++;
57332224Sbostic 		}
57432224Sbostic 	}
57532224Sbostic 	for(lastbrown = 0; newother[lastbrown] == 0; lastbrown++);
57632224Sbostic 		;
57732224Sbostic 	for(lastwhite = 0; newtry[lastwhite] == 0; lastwhite++)
57832224Sbostic 		;
57932224Sbostic 	lastwhite = 25-lastwhite;
58032224Sbostic 	if(lastwhite<=6 && lastwhite<lastbrown)
58132224Sbostic 		sum=1000;
58232224Sbostic 									/* experts running game. */
58332224Sbostic 									/* first priority is to */
58432224Sbostic 									/* get all pieces into */
58532224Sbostic 									/* white's home */
58632224Sbostic 	if(lastwhite<lastbrown && level=='e' && lastwhite>6) {
58732224Sbostic 		for(sum = 1000; lastwhite > 6; lastwhite--)
58832224Sbostic 			sum = sum-lastwhite*newtry[25-lastwhite];
58932224Sbostic 	}
59032224Sbostic 	for(first = 0; first < 25; first++)
59132224Sbostic 		if(newother[first] != 0)		/*find other's first piece*/
59232224Sbostic 			break;
59332224Sbostic 	q = newtry+25;
59432224Sbostic 	for(p = newtry+1; p < q;)			/* blocked points are good */
59532224Sbostic 		if(*p++ > 1)
59632224Sbostic 			sum++;
59732224Sbostic 	if(first > 5) {					/* only stress removing pieces if */
59832224Sbostic 							/* homeboard cannot be hit */
59932224Sbostic 		q = newtry+31;
60032224Sbostic 		p=newtry+25;
60132224Sbostic 		for(n = 6; p < q; n--)
60232224Sbostic 			sum += *p++ * n;			/*remove pieces, but just barely*/
60332224Sbostic 	}
60432224Sbostic 	if(level != 'b'){
60532224Sbostic 		r = newtry+25-first;	/*singles past this point can't be hit*/
60632224Sbostic 		for(p = newtry+7; p < r; )
60732224Sbostic 			if(*p++ == 1)		/*singles are bad after 1st 6 points if they can be hit*/
60832224Sbostic 				sum--;
60932224Sbostic 		q = newtry+3;
61032224Sbostic 		for(p = newtry; p < q; )	   /*bad to be on 1st three points*/
61132224Sbostic 			sum -= *p++;
61232224Sbostic 	}
61332224Sbostic 
61432224Sbostic 	for(n = 1; n <= 4; n++)
61532224Sbostic 		*prob += n*getprob(newtry,newother,6*n-5,6*n);
61632224Sbostic 	return(sum);
61732224Sbostic }
instructions()61832224Sbostic instructions()
61932224Sbostic {
62032224Sbostic 	register fd, r;
62132224Sbostic 	char	 buf[BUFSIZ];
62232224Sbostic 
62332224Sbostic 	if((fd = open(RULES, 0)) < 0) {
62432224Sbostic 		fprintf(stderr, "back: cannot open %s\n", RULES);
62532224Sbostic 		return;
62632224Sbostic 	}
62732224Sbostic 	while(r = read(fd, buf, BUFSIZ))
62832224Sbostic 		write(1, buf, r);
62932224Sbostic }
63032224Sbostic 
getprob(player,playee,start,finish)63132224Sbostic getprob(player,playee,start,finish)
63232224Sbostic int *player,*playee,start,finish;
63332224Sbostic {			/*returns the probability (times 102) that any
63432224Sbostic 			  pieces belonging to 'player' and lying between
63532224Sbostic 			  his points 'start' and 'finish' will be hit
63632224Sbostic 			  by a piece belonging to playee
63732224Sbostic 			*/
63832224Sbostic 	int	k, n, sum;
63932224Sbostic 
64032224Sbostic 	sum = 0;
64132224Sbostic 	for(; start <= finish; start++){
64232224Sbostic 		if(player[start] == 1){
64332224Sbostic 			for(k = 1; k <= 12; k++){
64432224Sbostic 				if((n=25-start-k) < 0)
64532224Sbostic 					break;
64632224Sbostic 				if(playee[n] != 0)
64732224Sbostic 					sum += probability[k];
64832224Sbostic 			}
64932224Sbostic 		}
65032224Sbostic 	}
65132224Sbostic 	return(sum);
65232224Sbostic }
prtbrd()65332224Sbostic prtbrd()
65432224Sbostic {
65532224Sbostic 	int	k;
65632224Sbostic 	static char undersc[]="______________________________________________________";
65732224Sbostic 
65832224Sbostic 	fprintf(stdout, "White's Home\n%s\r",undersc);
65932224Sbostic 	for(k = 1; k <= 6; k++)
66032224Sbostic 		fprintf(stdout, "%4d",k);
66132224Sbostic 	fprintf(stdout, "    ");
66232224Sbostic 	for(k = 7; k <= 12; k++)
66332224Sbostic 		fprintf(stdout, "%4d",k);
66432224Sbostic 	putchar('\n');
66532224Sbostic 	numline(brown, white, 1, 6);
66632224Sbostic 	fprintf(stdout, "    ");
66732224Sbostic 	numline(brown, white, 7, 12);
66832224Sbostic 	putchar('\n');
66932224Sbostic 	colorline(brown, 'B', white, 'W', 1, 6);
67032224Sbostic 	fprintf(stdout, "    ");
67132224Sbostic 	colorline(brown, 'B', white, 'W', 7, 12);
67232224Sbostic 	putchar('\n');
67332224Sbostic 	if(white[0] != 0)
67432224Sbostic 		fprintf(stdout, "%28dW\n",white[0]);
67532224Sbostic 	else
67632224Sbostic 		putchar('\n');
67732224Sbostic 	if(brown[0] != 0)
67832224Sbostic 		fprintf(stdout, "%28dB\n", brown[0]);
67932224Sbostic 	else
68032224Sbostic 		putchar('\n');
68132224Sbostic 	colorline(white, 'W', brown, 'B', 1, 6);
68232224Sbostic 	fprintf(stdout, "    ");
68332224Sbostic 	colorline(white, 'W', brown, 'B', 7, 12);
68432224Sbostic 	fprintf(stdout, "\n%s\r",undersc);
68532224Sbostic 	numline(white, brown, 1, 6);
68632224Sbostic 	fprintf(stdout, "    ");
68732224Sbostic 	numline(white, brown, 7, 12);
68832224Sbostic 	putchar('\n');
68932224Sbostic 	for(k = 24; k >= 19; k--)
69032224Sbostic 		fprintf(stdout, "%4d",k);
69132224Sbostic 	fprintf(stdout, "    ");
69232224Sbostic 	for(k = 18; k >= 13; k--)
69332224Sbostic 		fprintf(stdout, "%4d",k);
69432224Sbostic 	fprintf(stdout, "\nBrown's Home\n\n\n\n\n");
69532224Sbostic }
numline(upcol,downcol,start,fin)69632224Sbostic numline(upcol,downcol,start,fin)
69732224Sbostic int *upcol,*downcol,start,fin;
69832224Sbostic {
69932224Sbostic 	int	k, n;
70032224Sbostic 
70132224Sbostic 	for(k = start; k <= fin; k++){
70232224Sbostic 		if((n = upcol[k]) != 0 || (n = downcol[25-k]) != 0)
70332224Sbostic 			fprintf(stdout, "%4d", n);
70432224Sbostic 		else
70532224Sbostic 			fprintf(stdout, "    ");
70632224Sbostic 	}
70732224Sbostic }
colorline(upcol,c1,downcol,c2,start,fin)70832224Sbostic colorline(upcol,c1,downcol,c2,start,fin)
70932224Sbostic int *upcol,*downcol,start,fin;
71032224Sbostic char c1,c2;
71132224Sbostic {
71232224Sbostic 	int	k;
71332224Sbostic 	char 	c;
71432224Sbostic 
71532224Sbostic 	for(k = start; k <= fin; k++){
71632224Sbostic 		c = ' ';
71732224Sbostic 		if(upcol[k] != 0)
71832224Sbostic 			c = c1;
71932224Sbostic 		if(downcol[25-k] != 0)
72032224Sbostic 			c = c2;
72132224Sbostic 		fprintf(stdout, "   %c",c);
72232224Sbostic 	}
72332224Sbostic }
724