1*9360Smckusick static char sccsid[] = "	subs.c	4.2	82/11/27	";
26766Srrh 
36766Srrh #include <stdio.h>
46766Srrh #include "back.h"
56766Srrh 
66766Srrh int	buffnum;
76766Srrh char	outbuff[BUFSIZ];
86766Srrh 
96766Srrh static char	plred[] = "Player is red, computer is white.";
106766Srrh static char	plwhite[] = "Player is white, computer is red.";
116766Srrh static char	nocomp[] = "(No computer play.)";
126766Srrh 
136766Srrh char  *descr[] = {
146766Srrh 	"Usage:  backgammon [-] [n r w b pr pw pb t3a]\n",
156766Srrh 	"\t-\tgets this list\n\tn\tdon't ask for rules or instructions",
166766Srrh 	"\tr\tplayer is red (implies n)\n\tw\tplayer is white (implies n)",
176766Srrh 	"\tb\ttwo players, red and white (implies n)",
186766Srrh 	"\tpr\tprint the board before red's turn",
196766Srrh 	"\tpw\tprint the board before white's turn",
206766Srrh 	"\tpb\tprint the board before both player's turn",
216766Srrh 	"\tterm\tterminal is a term",
226766Srrh 	"\tsfile\trecover saved game from file",
236766Srrh 	0
246766Srrh };
256766Srrh 
266766Srrh errexit (s)
276766Srrh register char	*s;
286766Srrh {
296766Srrh 	write (2,"\n",1);
306766Srrh 	perror (s);
316766Srrh 	getout();
326766Srrh }
336766Srrh 
346766Srrh strset (s1,s2)
356766Srrh register char	*s1, *s2;
366766Srrh {
376766Srrh 	while ( (*s1++ = *s2++) != '\0');
386766Srrh }
396766Srrh 
406766Srrh addbuf (c)
416766Srrh register char	c;
426766Srrh 
436766Srrh {
446766Srrh 	buffnum++;
456766Srrh 	if (buffnum == BUFSIZ)  {
466766Srrh 		if (write(1,outbuff,BUFSIZ) != BUFSIZ)
476766Srrh 			errexit ("addbuf (write):");
486766Srrh 		buffnum = 0;
496766Srrh 	}
506766Srrh 	outbuff[buffnum] = c;
516766Srrh }
526766Srrh 
536766Srrh buflush ()  {
546766Srrh 	if (buffnum < 0)
556766Srrh 		return;
566766Srrh 	buffnum++;
576766Srrh 	if (write (1,outbuff,buffnum) != buffnum)
586766Srrh 		errexit ("buflush (write):");
596766Srrh 	buffnum = -1;
606766Srrh }
616766Srrh 
626766Srrh readc () {
636766Srrh 	char	c;
646766Srrh 
656766Srrh 	if (tflag)  {
666766Srrh 		cline();
676766Srrh 		newpos();
686766Srrh 	}
696766Srrh 	buflush();
706766Srrh 	if (read(0,&c,1) != 1)
716766Srrh 		errexit ("readc");
726766Srrh 	if (c == '\177')
736766Srrh 		getout();
746766Srrh 	if (c == '\033' || c == '\015')
756766Srrh 		return ('\n');
766766Srrh 	if (cflag)
776766Srrh 		return (c);
786766Srrh 	if (c == '\014')
796766Srrh 		return ('R');
806766Srrh 	if (c >= 'a' && c <= 'z')
816766Srrh 		return (c & 0137);
826766Srrh 	return (c);
836766Srrh }
846766Srrh 
856766Srrh writec (c)
866766Srrh char	c;
876766Srrh {
886766Srrh 	if (tflag)
896766Srrh 		fancyc (c);
906766Srrh 	else
916766Srrh 		addbuf (c);
926766Srrh }
936766Srrh 
946766Srrh writel (l)
956766Srrh register char	*l;
966766Srrh {
976766Srrh #ifdef DEBUG
986766Srrh 	register char	*s;
996766Srrh 
1006766Srrh 	if (trace == NULL)
1016766Srrh 		trace = fopen ("bgtrace","w");
1026766Srrh 
1036766Srrh 	fprintf (trace,"writel: \"");
1046766Srrh 	for (s = l; *s; s++) {
1056766Srrh 		if (*s < ' ' || *s == '\177')
1066766Srrh 			fprintf (trace,"^%c",(*s)^0100);
1076766Srrh 		else
1086766Srrh 			putc (*s,trace);
1096766Srrh 	}
1106766Srrh 	fprintf (trace,"\"\n");
1116766Srrh 	fflush (trace);
1126766Srrh #endif
1136766Srrh 
1146766Srrh 	while (*l)
1156766Srrh 		writec (*l++);
1166766Srrh }
1176766Srrh 
1186766Srrh proll ()   {
1196766Srrh 	if (d0)
1206766Srrh 		swap;
1216766Srrh 	if (cturn == 1)
1226766Srrh 		writel ("Red's roll:  ");
1236766Srrh 	else
1246766Srrh 		writel ("White's roll:  ");
1256766Srrh 	writec (D0+'0');
1266766Srrh 	writec ('\040');
1276766Srrh 	writec (D1+'0');
1286766Srrh 	if (tflag)
1296766Srrh 		cline();
1306766Srrh }
1316766Srrh 
1326766Srrh wrint (n)
1336766Srrh int	n;
1346766Srrh {
1356766Srrh 	register int	i, j, t;
1366766Srrh 
1376766Srrh 	for (i = 4; i > 0; i--)  {
1386766Srrh 		t = 1;
1396766Srrh 		for (j = 0; j<i; j++)
1406766Srrh 			t *= 10;
1416766Srrh 		if (n > t-1)
1426766Srrh 			writec ((n/t)%10+'0');
1436766Srrh 	}
1446766Srrh 	writec (n%10+'0');
1456766Srrh }
1466766Srrh 
1476766Srrh gwrite()  {
1486766Srrh 	register int	r, c;
1496766Srrh 
1506766Srrh 	if (tflag)  {
1516766Srrh 		r = curr;
1526766Srrh 		c = curc;
1536766Srrh 		curmove (16,0);
1546766Srrh 	}
1556766Srrh 
1566766Srrh 	if (gvalue > 1)  {
1576766Srrh 		writel ("Game value:  ");
1586766Srrh 		wrint (gvalue);
1596766Srrh 		writel (".  ");
1606766Srrh 		if (dlast == -1)
1616766Srrh 			writel (color[0]);
1626766Srrh 		else
1636766Srrh 			writel (color[1]);
1646766Srrh 		writel (" doubled last.");
1656766Srrh 	} else  {
1666766Srrh 		switch (pnum)  {
1676766Srrh 		case -1:			    /* player is red */
1686766Srrh 			writel (plred);
1696766Srrh 			break;
1706766Srrh 		case 0:				    /* player is both colors */
1716766Srrh 			writel (nocomp);
1726766Srrh 			break;
1736766Srrh 		case 1:				    /* player is white */
1746766Srrh 			writel (plwhite);
1756766Srrh 		}
1766766Srrh 	}
1776766Srrh 
1786766Srrh 	if (rscore || wscore)  {
1796766Srrh 		writel ("  ");
1806766Srrh 		wrscore();
1816766Srrh 	}
1826766Srrh 
1836766Srrh 	if (tflag)  {
1846766Srrh 		cline();
1856766Srrh 		curmove (r,c);
1866766Srrh 	}
1876766Srrh }
1886766Srrh 
1896766Srrh quit ()  {
1906766Srrh 	register int	i;
1916766Srrh 
1926766Srrh 	if (tflag)  {
1936766Srrh 		curmove (20,0);
1946766Srrh 		clend();
1956766Srrh 	} else
1966766Srrh 		writec ('\n');
1976766Srrh 	writel ("Are you sure you want to quit?");
1986766Srrh 	if (yorn (0))  {
1996766Srrh 		if (rfl)  {
2006766Srrh 			writel ("Would you like to save this game?");
2016766Srrh 			if (yorn(0))
2026766Srrh 				save(0);
2036766Srrh 		}
2046766Srrh 		cturn = 0;
2056766Srrh 		return (1);
2066766Srrh 	}
2076766Srrh 	return (0);
2086766Srrh }
2096766Srrh 
2106766Srrh yorn (special)
2116766Srrh register char	special;			/* special response */
2126766Srrh {
2136766Srrh 	register char	c;
2146766Srrh 	register int	i;
2156766Srrh 
2166766Srrh 	i = 1;
2176766Srrh 	while ( (c = readc()) != 'Y' && c != 'N')  {
2186766Srrh 		if (special && c == special)
2196766Srrh 			return (2);
2206766Srrh 		if (i)  {
2216766Srrh 			if (special)  {
2226766Srrh 				writel ("  (Y, N, or ");
2236766Srrh 				writec (special);
2246766Srrh 				writec (')');
2256766Srrh 			} else
2266766Srrh 				writel ("  (Y or N)");
2276766Srrh 			i = 0;
2286766Srrh 		} else
2296766Srrh 			writec ('\007');
2306766Srrh 	}
2316766Srrh 	if (c == 'Y')
2326766Srrh 		writel ("  Yes.\n");
2336766Srrh 	else
2346766Srrh 		writel ("  No.\n");
2356766Srrh 	if (tflag)
2366766Srrh 		buflush();
2376766Srrh 	return (c == 'Y');
2386766Srrh }
2396766Srrh 
2406766Srrh wrhit (i)
2416766Srrh register int	i;
2426766Srrh {
2436766Srrh 	writel ("Blot hit on ");
2446766Srrh 	wrint (i);
2456766Srrh 	writec ('.');
2466766Srrh 	writec ('\n');
2476766Srrh }
2486766Srrh 
2496766Srrh nexturn ()  {
2506766Srrh 	register int	c;
2516766Srrh 
2526766Srrh 	cturn = -cturn;
2536766Srrh 	c = cturn/abs(cturn);
2546766Srrh 	home = bar;
2556766Srrh 	bar = 25-bar;
2566766Srrh 	offptr += c;
2576766Srrh 	offopp -= c;
2586766Srrh 	inptr += c;
2596766Srrh 	inopp -= c;
2606766Srrh 	Colorptr += c;
2616766Srrh 	colorptr += c;
2626766Srrh }
2636766Srrh 
2646766Srrh getarg (arg)
2656766Srrh register char	***arg;
2666766Srrh 
2676766Srrh {
268*9360Smckusick 	register char	**s;
2696766Srrh 
2706766Srrh 	/* process arguments here.  dashes are ignored, nbrw are ignored
2716766Srrh 	   if the game is being recovered */
2726766Srrh 
273*9360Smckusick 	s = *arg;
274*9360Smckusick 	while (s[0][0] == '-') {
275*9360Smckusick 		switch (s[0][1])  {
2766766Srrh 
2776766Srrh 		/* don't ask if rules or instructions needed */
2786766Srrh 		case 'n':
2796766Srrh 			if (rflag)
2806766Srrh 				break;
2816766Srrh 			aflag = 0;
282*9360Smckusick 			args[acnt++] = 'n';
2836766Srrh 			break;
2846766Srrh 
2856766Srrh 		/* player is both read and white */
2866766Srrh 		case 'b':
2876766Srrh 			if (rflag)
2886766Srrh 				break;
2896766Srrh 			pnum = 0;
2906766Srrh 			aflag = 0;
291*9360Smckusick 			args[acnt++] = 'b';
2926766Srrh 			break;
2936766Srrh 
2946766Srrh 		/* player is red */
2956766Srrh 		case 'r':
2966766Srrh 			if (rflag)
2976766Srrh 				break;
2986766Srrh 			pnum = -1;
2996766Srrh 			aflag = 0;
300*9360Smckusick 			args[acnt++] = 'r';
3016766Srrh 			break;
3026766Srrh 
3036766Srrh 		/* player is white */
3046766Srrh 		case 'w':
3056766Srrh 			if (rflag)
3066766Srrh 				break;
3076766Srrh 			pnum = 1;
3086766Srrh 			aflag = 0;
309*9360Smckusick 			args[acnt++] = 'w';
3106766Srrh 			break;
3116766Srrh 
3126766Srrh 		/* print board after move according to following character */
3136766Srrh 		case 'p':
314*9360Smckusick 			if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b')
3156766Srrh 				break;
3166766Srrh 			args[acnt++] = 'p';
317*9360Smckusick 			args[acnt++] = s[0][2];
318*9360Smckusick 			if (s[0][2] == 'r')
3196766Srrh 				bflag = 1;
320*9360Smckusick 			if (s[0][2] == 'w')
3216766Srrh 				bflag = -1;
322*9360Smckusick 			if (s[0][2] == 'b')
3236766Srrh 				bflag = 0;
3246766Srrh 			break;
3256766Srrh 
3266766Srrh 		case 't':
327*9360Smckusick 			if (s[0][2] == '\0') {	/* get terminal caps */
328*9360Smckusick 				s++;
329*9360Smckusick 				tflag = getcaps (*s);
330*9360Smckusick 			} else
331*9360Smckusick 				tflag = getcaps (&s[0][2]);
332*9360Smckusick 			break;
3336766Srrh 
3346766Srrh 		case 's':
335*9360Smckusick 			s++;
336*9360Smckusick 			/* recover file */
337*9360Smckusick 			recover (s[0]);
338*9360Smckusick 			break;
3396766Srrh 		}
340*9360Smckusick 		s++;
3416766Srrh 	}
342*9360Smckusick 	if (s[0] != 0)
343*9360Smckusick 		recover(s[0]);
3446766Srrh }
3456766Srrh 
3466766Srrh init ()  {
3476766Srrh 	register int	i;
3486766Srrh 	for (i = 0; i < 26;)
3496766Srrh 		board[i++] = 0;
3506766Srrh 	board[1] = 2;
3516766Srrh 	board[6] = board[13] = -5;
3526766Srrh 	board[8] = -3;
3536766Srrh 	board[12] = board[19] = 5;
3546766Srrh 	board[17] = 3;
3556766Srrh 	board[24] = -2;
3566766Srrh 	off[0] = off[1] = -15;
3576766Srrh 	in[0] = in[1] = 5;
3586766Srrh 	gvalue = 1;
3596766Srrh 	dlast = 0;
3606766Srrh }
3616766Srrh 
3626766Srrh wrscore ()  {
3636766Srrh 	writel ("Score:  ");
3646766Srrh 	writel (color[1]);
3656766Srrh 	writec (' ');
3666766Srrh 	wrint (rscore);
3676766Srrh 	writel (", ");
3686766Srrh 	writel (color[0]);
3696766Srrh 	writec (' ');
3706766Srrh 	wrint (wscore);
3716766Srrh }
3726766Srrh 
3736766Srrh fixtty (mode)
3746766Srrh int	mode;
3756766Srrh {
3766766Srrh 	if (tflag)
3776766Srrh 		newpos();
3786766Srrh 	buflush();
3796766Srrh 	tty.sg_flags = mode;
3806766Srrh 	if (stty (0,&tty) < 0)
3816766Srrh 		errexit("fixtty");
3826766Srrh }
3836766Srrh 
3846766Srrh getout ()  {
3856766Srrh 	/* go to bottom of screen */
3866766Srrh 	if (tflag)  {
3876766Srrh 		curmove (23,0);
3886766Srrh 		cline();
3896766Srrh 	} else
3906766Srrh 		writec ('\n');
3916766Srrh 
3926766Srrh 	/* fix terminal status */
3936766Srrh 	fixtty (old);
3946766Srrh 	exit();
3956766Srrh }
3966766Srrh roll ()  {
3976766Srrh 	register char	c;
3986766Srrh 	register int	row;
3996766Srrh 	register int	col;
4006766Srrh 
4016766Srrh 	if (iroll)  {
4026766Srrh 		if (tflag)  {
4036766Srrh 			row = curr;
4046766Srrh 			col = curc;
4056766Srrh 			curmove (17,0);
4066766Srrh 		} else
4076766Srrh 			writec ('\n');
4086766Srrh 		writel ("ROLL: ");
4096766Srrh 		c = readc();
4106766Srrh 		if (c != '\n')  {
4116766Srrh 			while (c < '1' || c > '6')
4126766Srrh 				c = readc();
4136766Srrh 			D0 = c-'0';
4146766Srrh 			writec (' ');
4156766Srrh 			writec (c);
4166766Srrh 			c = readc();
4176766Srrh 			while (c < '1' || c > '6')
4186766Srrh 				c = readc();
4196766Srrh 			D1 = c-'0';
4206766Srrh 			writec (' ');
4216766Srrh 			writec (c);
4226766Srrh 			if (tflag)  {
4236766Srrh 				curmove (17,0);
4246766Srrh 				cline();
4256766Srrh 				curmove (row,col);
4266766Srrh 			} else
4276766Srrh 				writec ('\n');
4286766Srrh 			return;
4296766Srrh 		}
4306766Srrh 		if (tflag)  {
4316766Srrh 			curmove (17,0);
4326766Srrh 			cline();
4336766Srrh 			curmove (row,col);
4346766Srrh 		} else
4356766Srrh 			writec ('\n');
4366766Srrh 	}
4376766Srrh 	D0 = rnum(6)+1;
4386766Srrh 	D1 = rnum(6)+1;
4396766Srrh 	d0 = 0;
4406766Srrh }
441