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