subs.c revision 1.14 1 /* $NetBSD: subs.c,v 1.14 2003/08/07 09:36:57 agc 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.14 2003/08/07 09:36:57 agc Exp $");
38 #endif
39 #endif /* not lint */
40
41 #include "back.h"
42
43 int buffnum;
44 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 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(s)
65 const char *s;
66 {
67 write(2, "\n", 1);
68 perror(s);
69 getout(0);
70 }
71
72 int
73 addbuf(c)
74 int c;
75 {
76 buffnum++;
77 if (buffnum == BUFSIZ) {
78 if (write(1, outbuff, BUFSIZ) != BUFSIZ)
79 errexit("addbuf (write):");
80 buffnum = 0;
81 }
82 outbuff[buffnum] = c;
83 return (0);
84 }
85
86 void
87 buflush()
88 {
89 if (buffnum < 0)
90 return;
91 buffnum++;
92 if (write(1, outbuff, buffnum) != buffnum)
93 errexit("buflush (write):");
94 buffnum = -1;
95 }
96
97 int
98 readc()
99 {
100 char c;
101
102 if (tflag) {
103 cline();
104 newpos();
105 }
106 buflush();
107 if (read(0, &c, 1) != 1)
108 errexit("readc");
109 #ifdef WHY_IS_THIS_HARDWIRED_IN_HERE
110 if (c == '\177')
111 getout(0);
112 #endif
113 if (c == '\033' || c == '\015')
114 return ('\n');
115 if (cflag)
116 return (c);
117 if (c == '\014')
118 return ('R');
119 if (c >= 'a' && c <= 'z')
120 return (c & 0137);
121 return (c);
122 }
123
124 void
125 writec(c)
126 char c;
127 {
128 if (tflag)
129 fancyc(c);
130 else
131 addbuf(c);
132 }
133
134 void
135 writel(l)
136 const char *l;
137 {
138 #ifdef DEBUG
139 const char *s;
140
141 if (trace == NULL)
142 trace = fopen("bgtrace", "w");
143
144 fprintf(trace, "writel: \"");
145 for (s = l; *s; s++) {
146 if (*s < ' ' || *s == '\177')
147 fprintf(trace, "^%c", (*s) ^ 0100);
148 else
149 putc(*s, trace);
150 }
151 fprintf(trace, "\"\n");
152 fflush(trace);
153 #endif
154
155 while (*l)
156 writec(*l++);
157 }
158
159 void
160 proll()
161 {
162 if (d0)
163 swap;
164 if (cturn == 1)
165 writel("Red's roll: ");
166 else
167 writel("White's roll: ");
168 writec(D0 + '0');
169 writec('\040');
170 writec(D1 + '0');
171 if (tflag)
172 cline();
173 }
174
175 void
176 wrint(n)
177 int n;
178 {
179 int i, j, t;
180
181 for (i = 4; i > 0; i--) {
182 t = 1;
183 for (j = 0; j < i; j++)
184 t *= 10;
185 if (n > t - 1)
186 writec((n / t) % 10 + '0');
187 }
188 writec(n % 10 + '0');
189 }
190
191 void
192 gwrite()
193 {
194 int r, c;
195
196 r = c = 0;
197 if (tflag) {
198 r = curr;
199 c = curc;
200 curmove(16, 0);
201 }
202 if (gvalue > 1) {
203 writel("Game value: ");
204 wrint(gvalue);
205 writel(". ");
206 if (dlast == -1)
207 writel(color[0]);
208 else
209 writel(color[1]);
210 writel(" doubled last.");
211 } else {
212 switch (pnum) {
213 case -1: /* player is red */
214 writel(plred);
215 break;
216 case 0: /* player is both colors */
217 writel(nocomp);
218 break;
219 case 1: /* player is white */
220 writel(plwhite);
221 }
222 }
223
224 if (rscore || wscore) {
225 writel(" ");
226 wrscore();
227 }
228 if (tflag) {
229 cline();
230 curmove(r, c);
231 }
232 }
233
234 int
235 quit()
236 {
237
238 if (tflag) {
239 curmove(20, 0);
240 clend();
241 } else
242 writec('\n');
243 writel("Are you sure you want to quit?");
244 if (yorn(0)) {
245 if (rfl) {
246 writel("Would you like to save this game?");
247 if (yorn(0))
248 save(0);
249 }
250 cturn = 0;
251 return (1);
252 }
253 return (0);
254 }
255
256 int
257 yorn(special)
258 char special; /* special response */
259 {
260 char c;
261 int i;
262
263 i = 1;
264 while ((c = readc()) != 'Y' && c != 'N') {
265 if (special && c == special)
266 return (2);
267 if (i) {
268 if (special) {
269 writel(" (Y, N, or ");
270 writec(special);
271 writec(')');
272 } else
273 writel(" (Y or N)");
274 i = 0;
275 } else
276 writec('\007');
277 }
278 if (c == 'Y')
279 writel(" Yes.\n");
280 else
281 writel(" No.\n");
282 if (tflag)
283 buflush();
284 return (c == 'Y');
285 }
286
287 void
288 wrhit(i)
289 int i;
290 {
291 writel("Blot hit on ");
292 wrint(i);
293 writec('.');
294 writec('\n');
295 }
296
297 void
298 nexturn()
299 {
300 int c;
301
302 cturn = -cturn;
303 c = cturn / abs(cturn);
304 home = bar;
305 bar = 25 - bar;
306 offptr += c;
307 offopp -= c;
308 inptr += c;
309 inopp -= c;
310 Colorptr += c;
311 colorptr += c;
312 }
313
314 void
315 getarg(arg)
316 char ***arg;
317 {
318 char **s;
319
320 /* process arguments here. dashes are ignored, nbrw are ignored if
321 * the game is being recovered */
322
323 s = *arg;
324 while (*s && s[0][0] == '-') {
325 switch (s[0][1]) {
326
327 /* don't ask if rules or instructions needed */
328 case 'n':
329 if (rflag)
330 break;
331 aflag = 0;
332 args[acnt++] = 'n';
333 break;
334
335 /* player is both red and white */
336 case 'b':
337 if (rflag)
338 break;
339 pnum = 0;
340 aflag = 0;
341 args[acnt++] = 'b';
342 break;
343
344 /* player is red */
345 case 'r':
346 if (rflag)
347 break;
348 pnum = -1;
349 aflag = 0;
350 args[acnt++] = 'r';
351 break;
352
353 /* player is white */
354 case 'w':
355 if (rflag)
356 break;
357 pnum = 1;
358 aflag = 0;
359 args[acnt++] = 'w';
360 break;
361
362 /* print board after move according to following
363 * character */
364 case 'p':
365 if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b')
366 break;
367 args[acnt++] = 'p';
368 args[acnt++] = s[0][2];
369 if (s[0][2] == 'r')
370 bflag = 1;
371 if (s[0][2] == 'w')
372 bflag = -1;
373 if (s[0][2] == 'b')
374 bflag = 0;
375 break;
376
377 case 't':
378 if (s[0][2] == '\0') { /* get terminal caps */
379 s++;
380 tflag = getcaps(*s);
381 } else
382 tflag = getcaps(&s[0][2]);
383 break;
384
385 case 's':
386 s++;
387 /* recover file */
388 if (s[0] == NULL) {
389 writel("No save file named\n");
390 getout(0);
391 } else
392 recover(s[0]);
393 break;
394 }
395 s++;
396 }
397 if (s[0] != 0)
398 recover(s[0]);
399 }
400
401 void
402 init()
403 {
404 int i;
405
406 for (i = 0; i < 26;)
407 board[i++] = 0;
408 board[1] = 2;
409 board[6] = board[13] = -5;
410 board[8] = -3;
411 board[12] = board[19] = 5;
412 board[17] = 3;
413 board[24] = -2;
414 off[0] = off[1] = -15;
415 in[0] = in[1] = 5;
416 gvalue = 1;
417 dlast = 0;
418 }
419
420 void
421 wrscore()
422 {
423 writel("Score: ");
424 writel(color[1]);
425 writec(' ');
426 wrint(rscore);
427 writel(", ");
428 writel(color[0]);
429 writec(' ');
430 wrint(wscore);
431 }
432
433 void
434 fixtty(t)
435 struct termios *t;
436 {
437 if (tflag)
438 newpos();
439 buflush();
440 if (tcsetattr(0, TCSADRAIN, t) < 0)
441 errexit("fixtty");
442 }
443
444 void
445 getout(dummy)
446 int dummy __attribute__((__unused__));
447 {
448 /* go to bottom of screen */
449 if (tflag) {
450 curmove(23, 0);
451 cline();
452 } else
453 writec('\n');
454
455 /* fix terminal status */
456 fixtty(&old);
457 exit(0);
458 }
459
460 void
461 roll()
462 {
463 char c;
464 int row;
465 int col;
466
467 row = col = 0;
468 if (iroll) {
469 if (tflag) {
470 row = curr;
471 col = curc;
472 curmove(17, 0);
473 } else
474 writec('\n');
475 writel("ROLL: ");
476 c = readc();
477 if (c != '\n') {
478 while (c < '1' || c > '6')
479 c = readc();
480 D0 = c - '0';
481 writec(' ');
482 writec(c);
483 c = readc();
484 while (c < '1' || c > '6')
485 c = readc();
486 D1 = c - '0';
487 writec(' ');
488 writec(c);
489 if (tflag) {
490 curmove(17, 0);
491 cline();
492 curmove(row, col);
493 } else
494 writec('\n');
495 return;
496 }
497 if (tflag) {
498 curmove(17, 0);
499 cline();
500 curmove(row, col);
501 } else
502 writec('\n');
503 }
504 D0 = rnum(6) + 1;
505 D1 = rnum(6) + 1;
506 d0 = 0;
507 }
508