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