Initial import from FreeBSD RELENG_4:
[dragonfly.git] / games / backgammon / common_source / table.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[] = "@(#)table.c     8.1 (Berkeley) 5/31/93";
37 #endif
38 static const char rcsid[] =
39  "$FreeBSD: src/games/backgammon/common_source/table.c,v 1.5 1999/11/30 03:48:28 billf Exp $";
40 #endif /* not lint */
41
42 #include "back.h"
43
44 const char      *const help2[] = {
45         "   Enter moves as <s>-<f> or <s>/<r> where <s> is the starting",
46         "position, <f> is the finishing position, and <r> is the roll.",
47         "Remember, each die roll must be moved separately.",
48         0
49 };
50
51 struct state    {
52         char    ch;
53         int     fcode;
54         int     newst;
55 };
56
57 static const struct state       atmata[] = {
58
59         'R', 1, 0,      '?', 7, 0,      'Q', 0, -3,     'B', 8, 25,
60         '9', 2, 25,     '8', 2, 25,     '7', 2, 25,     '6', 2, 25,
61         '5', 2, 25,     '4', 2, 25,     '3', 2, 25,     '2', 2, 19,
62         '1', 2, 15,     '0', 2, 25,     '.', 0, 0,      '9', 2, 25,
63         '8', 2, 25,     '7', 2, 25,     '6', 2, 25,     '5', 2, 25,
64
65         '4', 2, 25,     '3', 2, 25,     '2', 2, 25,     '1', 2, 25,
66         '0', 2, 25,     '/', 0, 32,     '-', 0, 39,     '.', 0, 0,
67         '/', 5, 32,     ' ', 6, 3,      ',', 6, 3,      '\n', 0, -1,
68         '6', 3, 28,     '5', 3, 28,     '4', 3, 28,     '3', 3, 28,
69         '2', 3, 28,     '1', 3, 28,     '.', 0, 0,      'H', 9, 61,
70
71         '9', 4, 61,     '8', 4, 61,     '7', 4, 61,     '6', 4, 61,
72         '5', 4, 61,     '4', 4, 61,     '3', 4, 61,     '2', 4, 53,
73         '1', 4, 51,     '0', 4, 61,     '.', 0, 0,      '9', 4, 61,
74         '8', 4, 61,     '7', 4, 61,     '6', 4, 61,     '5', 4, 61,
75         '4', 4, 61,     '3', 4, 61,     '2', 4, 61,     '1', 4, 61,
76
77         '0', 4, 61,     ' ', 6, 3,      ',', 6, 3,      '-', 5, 39,
78         '\n', 0, -1,    '.', 0, 0
79 };
80
81 checkmove (ist)
82
83 int     ist;
84
85 {
86         int     j, n;
87         char    c;
88         char            a;
89
90 domove:
91         if (ist == 0)  {
92                 if (tflag)
93                         curmove (curr,32);
94                 else
95                         writel ("\t\t");
96                 writel ("Move:  ");
97         }
98         ist = mvl = ncin = 0;
99         for (j = 0; j < 5; j++)
100                 p[j] = g[j] = -1;
101
102 dochar:
103         c = readc();
104
105         if (c == 'S')  {
106                 raflag = 0;
107                 save (1);
108                 if (tflag)  {
109                         curmove (cturn == -1? 18: 19,39);
110                         ist = -1;
111                         goto domove;
112                 } else  {
113                         proll ();
114                         ist = 0;
115                         goto domove;
116                 }
117         }
118
119         if (c == tty.sg_erase && ncin > 0)  {
120                 if (tflag)
121                         curmove (curr,curc-1);
122                 else  {
123                         if (tty.sg_erase == '\010')
124                                 writel ("\010 \010");
125                         else
126                                 writec (cin[ncin-1]);
127                 }
128                 ncin--;
129                 n = rsetbrd();
130                 if (n == 0)  {
131                         n = -1;
132                         if (tflag)
133                                 refresh();
134                 }
135                 if ((ist = n) > 0)
136                         goto dochar;
137                 goto domove;
138         }
139
140         if (c == tty.sg_kill && ncin > 0)  {
141                 if (tflag)  {
142                         refresh();
143                         curmove (curr,39);
144                         ist = -1;
145                         goto domove;
146                 } else  if (tty.sg_erase == '\010')  {
147                         for (j = 0; j < ncin; j++)
148                                 writel ("\010 \010");
149                         ist = -1;
150                         goto domove;
151                 } else  {
152                         writec ('\\');
153                         writec ('\n');
154                         proll ();
155                         ist = 0;
156                         goto domove;
157                 }
158         }
159
160         n = dotable(c,ist);
161         if (n >= 0)  {
162                 cin[ncin++] = c;
163                 if (n > 2)
164                 if ((! tflag) || c != '\n')
165                         writec (c);
166                 ist = n;
167                 if (n)
168                         goto dochar;
169                 else
170                         goto domove;
171         }
172
173         if (n == -1 && mvl >= mvlim)
174                 return(0);
175         if (n == -1 && mvl < mvlim-1)
176                 return(-4);
177
178         if (n == -6)  {
179                 if (! tflag)  {
180                         if (movokay(mvl+1))  {
181                                 wrboard();
182                                 movback (mvl+1);
183                         }
184                         proll ();
185                         writel ("\t\tMove:  ");
186                         for (j = 0; j < ncin;)
187                                 writec (cin[j++]);
188                 } else  {
189                         if (movokay(mvl+1))  {
190                                 refresh();
191                                 movback (mvl+1);
192                         } else
193                                 curmove (cturn == -1? 18:19,ncin+39);
194                 }
195                 ist = n = rsetbrd();
196                 goto dochar;
197         }
198
199         if (n != -5)
200                 return(n);
201         writec ('\007');
202         goto dochar;
203 }
204 \f
205 dotable (c,i)
206 char            c;
207 int     i;
208
209 {
210         int     a, j;
211         int             test;
212
213         test = (c == 'R');
214
215         while ( (a = atmata[i].ch) != '.')  {
216                 if (a == c || (test && a == '\n'))  {
217                         switch  (atmata[i].fcode)  {
218
219                         case 1:
220                                 wrboard();
221                                 if (tflag)  {
222                                         curmove (cturn == -1? 18: 19,0);
223                                         proll ();
224                                         writel ("\t\t");
225                                 } else
226                                         proll ();
227                                 break;
228
229                         case 2:
230                                 if (p[mvl] == -1)
231                                         p[mvl] = c-'0';
232                                 else
233                                         p[mvl] = p[mvl]*10+c-'0';
234                                 break;
235
236                         case 3:
237                                 if (g[mvl] != -1)  {
238                                         if (mvl < mvlim)
239                                                 mvl++;
240                                         p[mvl] = p[mvl-1];
241                                 }
242                                 g[mvl] = p[mvl]+cturn*(c-'0');
243                                 if (g[mvl] < 0)
244                                         g[mvl] = 0;
245                                 if (g[mvl] > 25)
246                                         g[mvl] = 25;
247                                 break;
248
249                         case 4:
250                                 if (g[mvl] == -1)
251                                         g[mvl] = c-'0';
252                                 else
253                                         g[mvl] = g[mvl]*10+c-'0';
254                                 break;
255
256                         case 5:
257                                 if (mvl < mvlim)
258                                         mvl++;
259                                 p[mvl] = g[mvl-1];
260                                 break;
261
262                         case 6:
263                                 if (mvl < mvlim)
264                                         mvl++;
265                                 break;
266
267                         case 7:
268                                 if (tflag)
269                                         curmove (20,0);
270                                 else
271                                         writec ('\n');
272                                 text (help2);
273                                 if (tflag)  {
274                                         curmove (cturn == -1? 18: 19,39);
275                                 } else  {
276                                         writec ('\n');
277                                         proll();
278                                         writel ("\t\tMove:  ");
279                                 }
280                                 break;
281
282                         case 8:
283                                 p[mvl] = bar;
284                                 break;
285
286                         case 9:
287                                 g[mvl] = home;
288                         }
289
290                         if (! test || a != '\n')
291                                 return (atmata[i].newst);
292                         else
293                                 return (-6);
294                 }
295
296                 i++;
297         }
298
299         return (-5);
300 }
301 \f
302 rsetbrd ()  {
303         int     i, j, n;
304
305         n = 0;
306         mvl = 0;
307         for (i = 0; i < 4; i++)
308                 p[i] = g[i] = -1;
309         for (j = 0; j < ncin; j++)
310                 n = dotable (cin[j],n);
311         return (n);
312 }