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