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