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