1 /*
2  * Copyright (c) 1980, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)subs.c	8.1 (Berkeley) 05/31/93";
10 #endif /* not lint */
11 
12 #include <stdio.h>
13 #include "back.h"
14 
15 int	buffnum;
16 char	outbuff[BUFSIZ];
17 
18 static char	plred[] = "Player is red, computer is white.";
19 static char	plwhite[] = "Player is white, computer is red.";
20 static char	nocomp[] = "(No computer play.)";
21 
22 char  *descr[] = {
23 	"Usage:  backgammon [-] [n r w b pr pw pb t3a]\n",
24 	"\t-\tgets this list\n\tn\tdon't ask for rules or instructions",
25 	"\tr\tplayer is red (implies n)\n\tw\tplayer is white (implies n)",
26 	"\tb\ttwo players, red and white (implies n)",
27 	"\tpr\tprint the board before red's turn",
28 	"\tpw\tprint the board before white's turn",
29 	"\tpb\tprint the board before both player's turn",
30 	"\tterm\tterminal is a term",
31 	"\tsfile\trecover saved game from file",
32 	0
33 };
34 
35 errexit (s)
36 register char	*s;
37 {
38 	write (2,"\n",1);
39 	perror (s);
40 	getout();
41 }
42 
43 strset (s1,s2)
44 register char	*s1, *s2;
45 {
46 	while ( (*s1++ = *s2++) != '\0');
47 }
48 
49 addbuf (c)
50 register char	c;
51 
52 {
53 	buffnum++;
54 	if (buffnum == BUFSIZ)  {
55 		if (write(1,outbuff,BUFSIZ) != BUFSIZ)
56 			errexit ("addbuf (write):");
57 		buffnum = 0;
58 	}
59 	outbuff[buffnum] = c;
60 }
61 
62 buflush ()  {
63 	if (buffnum < 0)
64 		return;
65 	buffnum++;
66 	if (write (1,outbuff,buffnum) != buffnum)
67 		errexit ("buflush (write):");
68 	buffnum = -1;
69 }
70 
71 readc () {
72 	char	c;
73 
74 	if (tflag)  {
75 		cline();
76 		newpos();
77 	}
78 	buflush();
79 	if (read(0,&c,1) != 1)
80 		errexit ("readc");
81 #ifdef WHY_IS_THIS_HARDWIRED_IN_HERE
82 	if (c == '\177')
83 		getout();
84 #endif
85 	if (c == '\033' || c == '\015')
86 		return ('\n');
87 	if (cflag)
88 		return (c);
89 	if (c == '\014')
90 		return ('R');
91 	if (c >= 'a' && c <= 'z')
92 		return (c & 0137);
93 	return (c);
94 }
95 
96 writec (c)
97 char	c;
98 {
99 	if (tflag)
100 		fancyc (c);
101 	else
102 		addbuf (c);
103 }
104 
105 writel (l)
106 register char	*l;
107 {
108 #ifdef DEBUG
109 	register char	*s;
110 
111 	if (trace == NULL)
112 		trace = fopen ("bgtrace","w");
113 
114 	fprintf (trace,"writel: \"");
115 	for (s = l; *s; s++) {
116 		if (*s < ' ' || *s == '\177')
117 			fprintf (trace,"^%c",(*s)^0100);
118 		else
119 			putc (*s,trace);
120 	}
121 	fprintf (trace,"\"\n");
122 	fflush (trace);
123 #endif
124 
125 	while (*l)
126 		writec (*l++);
127 }
128 
129 proll ()   {
130 	if (d0)
131 		swap;
132 	if (cturn == 1)
133 		writel ("Red's roll:  ");
134 	else
135 		writel ("White's roll:  ");
136 	writec (D0+'0');
137 	writec ('\040');
138 	writec (D1+'0');
139 	if (tflag)
140 		cline();
141 }
142 
143 wrint (n)
144 int	n;
145 {
146 	register int	i, j, t;
147 
148 	for (i = 4; i > 0; i--)  {
149 		t = 1;
150 		for (j = 0; j<i; j++)
151 			t *= 10;
152 		if (n > t-1)
153 			writec ((n/t)%10+'0');
154 	}
155 	writec (n%10+'0');
156 }
157 
158 gwrite()  {
159 	register int	r, c;
160 
161 	if (tflag)  {
162 		r = curr;
163 		c = curc;
164 		curmove (16,0);
165 	}
166 
167 	if (gvalue > 1)  {
168 		writel ("Game value:  ");
169 		wrint (gvalue);
170 		writel (".  ");
171 		if (dlast == -1)
172 			writel (color[0]);
173 		else
174 			writel (color[1]);
175 		writel (" doubled last.");
176 	} else  {
177 		switch (pnum)  {
178 		case -1:			    /* player is red */
179 			writel (plred);
180 			break;
181 		case 0:				    /* player is both colors */
182 			writel (nocomp);
183 			break;
184 		case 1:				    /* player is white */
185 			writel (plwhite);
186 		}
187 	}
188 
189 	if (rscore || wscore)  {
190 		writel ("  ");
191 		wrscore();
192 	}
193 
194 	if (tflag)  {
195 		cline();
196 		curmove (r,c);
197 	}
198 }
199 
200 quit ()  {
201 	register int	i;
202 
203 	if (tflag)  {
204 		curmove (20,0);
205 		clend();
206 	} else
207 		writec ('\n');
208 	writel ("Are you sure you want to quit?");
209 	if (yorn (0))  {
210 		if (rfl)  {
211 			writel ("Would you like to save this game?");
212 			if (yorn(0))
213 				save(0);
214 		}
215 		cturn = 0;
216 		return (1);
217 	}
218 	return (0);
219 }
220 
221 yorn (special)
222 register char	special;			/* special response */
223 {
224 	register char	c;
225 	register int	i;
226 
227 	i = 1;
228 	while ( (c = readc()) != 'Y' && c != 'N')  {
229 		if (special && c == special)
230 			return (2);
231 		if (i)  {
232 			if (special)  {
233 				writel ("  (Y, N, or ");
234 				writec (special);
235 				writec (')');
236 			} else
237 				writel ("  (Y or N)");
238 			i = 0;
239 		} else
240 			writec ('\007');
241 	}
242 	if (c == 'Y')
243 		writel ("  Yes.\n");
244 	else
245 		writel ("  No.\n");
246 	if (tflag)
247 		buflush();
248 	return (c == 'Y');
249 }
250 
251 wrhit (i)
252 register int	i;
253 {
254 	writel ("Blot hit on ");
255 	wrint (i);
256 	writec ('.');
257 	writec ('\n');
258 }
259 
260 nexturn ()  {
261 	register int	c;
262 
263 	cturn = -cturn;
264 	c = cturn/abs(cturn);
265 	home = bar;
266 	bar = 25-bar;
267 	offptr += c;
268 	offopp -= c;
269 	inptr += c;
270 	inopp -= c;
271 	Colorptr += c;
272 	colorptr += c;
273 }
274 
275 getarg (arg)
276 register char	***arg;
277 
278 {
279 	register char	**s;
280 
281 	/* process arguments here.  dashes are ignored, nbrw are ignored
282 	   if the game is being recovered */
283 
284 	s = *arg;
285 	while (s[0][0] == '-') {
286 		switch (s[0][1])  {
287 
288 		/* don't ask if rules or instructions needed */
289 		case 'n':
290 			if (rflag)
291 				break;
292 			aflag = 0;
293 			args[acnt++] = 'n';
294 			break;
295 
296 		/* player is both read and white */
297 		case 'b':
298 			if (rflag)
299 				break;
300 			pnum = 0;
301 			aflag = 0;
302 			args[acnt++] = 'b';
303 			break;
304 
305 		/* player is red */
306 		case 'r':
307 			if (rflag)
308 				break;
309 			pnum = -1;
310 			aflag = 0;
311 			args[acnt++] = 'r';
312 			break;
313 
314 		/* player is white */
315 		case 'w':
316 			if (rflag)
317 				break;
318 			pnum = 1;
319 			aflag = 0;
320 			args[acnt++] = 'w';
321 			break;
322 
323 		/* print board after move according to following character */
324 		case 'p':
325 			if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b')
326 				break;
327 			args[acnt++] = 'p';
328 			args[acnt++] = s[0][2];
329 			if (s[0][2] == 'r')
330 				bflag = 1;
331 			if (s[0][2] == 'w')
332 				bflag = -1;
333 			if (s[0][2] == 'b')
334 				bflag = 0;
335 			break;
336 
337 		case 't':
338 			if (s[0][2] == '\0') {	/* get terminal caps */
339 				s++;
340 				tflag = getcaps (*s);
341 			} else
342 				tflag = getcaps (&s[0][2]);
343 			break;
344 
345 		case 's':
346 			s++;
347 			/* recover file */
348 			recover (s[0]);
349 			break;
350 		}
351 		s++;
352 	}
353 	if (s[0] != 0)
354 		recover(s[0]);
355 }
356 
357 init ()  {
358 	register int	i;
359 	for (i = 0; i < 26;)
360 		board[i++] = 0;
361 	board[1] = 2;
362 	board[6] = board[13] = -5;
363 	board[8] = -3;
364 	board[12] = board[19] = 5;
365 	board[17] = 3;
366 	board[24] = -2;
367 	off[0] = off[1] = -15;
368 	in[0] = in[1] = 5;
369 	gvalue = 1;
370 	dlast = 0;
371 }
372 
373 wrscore ()  {
374 	writel ("Score:  ");
375 	writel (color[1]);
376 	writec (' ');
377 	wrint (rscore);
378 	writel (", ");
379 	writel (color[0]);
380 	writec (' ');
381 	wrint (wscore);
382 }
383 
384 fixtty (mode)
385 int	mode;
386 {
387 	if (tflag)
388 		newpos();
389 	buflush();
390 	tty.sg_flags = mode;
391 	if (stty (0,&tty) < 0)
392 		errexit("fixtty");
393 }
394 
395 getout ()  {
396 	/* go to bottom of screen */
397 	if (tflag)  {
398 		curmove (23,0);
399 		cline();
400 	} else
401 		writec ('\n');
402 
403 	/* fix terminal status */
404 	fixtty (old);
405 	exit();
406 }
407 roll ()  {
408 	register char	c;
409 	register int	row;
410 	register int	col;
411 
412 	if (iroll)  {
413 		if (tflag)  {
414 			row = curr;
415 			col = curc;
416 			curmove (17,0);
417 		} else
418 			writec ('\n');
419 		writel ("ROLL: ");
420 		c = readc();
421 		if (c != '\n')  {
422 			while (c < '1' || c > '6')
423 				c = readc();
424 			D0 = c-'0';
425 			writec (' ');
426 			writec (c);
427 			c = readc();
428 			while (c < '1' || c > '6')
429 				c = readc();
430 			D1 = c-'0';
431 			writec (' ');
432 			writec (c);
433 			if (tflag)  {
434 				curmove (17,0);
435 				cline();
436 				curmove (row,col);
437 			} else
438 				writec ('\n');
439 			return;
440 		}
441 		if (tflag)  {
442 			curmove (17,0);
443 			cline();
444 			curmove (row,col);
445 		} else
446 			writec ('\n');
447 	}
448 	D0 = rnum(6)+1;
449 	D1 = rnum(6)+1;
450 	d0 = 0;
451 }
452