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