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