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