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