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