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