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