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