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