1 /*        $NetBSD: table.c,v 1.13 2012/10/13 19:19:39 dholland Exp $  */
2 
3 /*
4  * Copyright (c) 1980, 1993
5  *        The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)table.c     8.1 (Berkeley) 5/31/93";
36 #else
37 __RCSID("$NetBSD: table.c,v 1.13 2012/10/13 19:19:39 dholland Exp $");
38 #endif
39 #endif /* not lint */
40 
41 #include "back.h"
42 
43 static 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 int mvl;                         /* working copy of move->mvlim */
57 
58 static const struct state atmata[] = {
59 
60           {'R', 1, 0},        {'?', 7, 0},        {'Q', 0, -3},       {'B', 8, 25},
61           {'9', 2, 25},       {'8', 2, 25},       {'7', 2, 25},       {'6', 2, 25},
62           {'5', 2, 25},       {'4', 2, 25},       {'3', 2, 25},       {'2', 2, 19},
63           {'1', 2, 15},       {'0', 2, 25},       {'.', 0, 0},        {'9', 2, 25},
64           {'8', 2, 25},       {'7', 2, 25},       {'6', 2, 25},       {'5', 2, 25},
65 
66           {'4', 2, 25},       {'3', 2, 25},       {'2', 2, 25},       {'1', 2, 25},
67           {'0', 2, 25},       {'/', 0, 32},       {'-', 0, 39},       {'.', 0, 0},
68           {'/', 5, 32},       {' ', 6, 3},        {',', 6, 3},        {'\n', 0, -1},
69           {'6', 3, 28},       {'5', 3, 28},       {'4', 3, 28},       {'3', 3, 28},
70           {'2', 3, 28},       {'1', 3, 28},       {'.', 0, 0},        {'H', 9, 61},
71 
72           {'9', 4, 61},       {'8', 4, 61},       {'7', 4, 61},       {'6', 4, 61},
73           {'5', 4, 61},       {'4', 4, 61},       {'3', 4, 61},       {'2', 4, 53},
74           {'1', 4, 51},       {'0', 4, 61},       {'.', 0, 0},        {'9', 4, 61},
75           {'8', 4, 61},       {'7', 4, 61},       {'6', 4, 61},       {'5', 4, 61},
76           {'4', 4, 61},       {'3', 4, 61},       {'2', 4, 61},       {'1', 4, 61},
77 
78           {'0', 4, 61},       {' ', 6, 3},        {',', 6, 3},        {'-', 5, 39},
79           {'\n', 0, -1},      {'.', 0, 0}
80 };
81 
82 static int dotable(struct move *, int, int);
83 static int rsetbrd(struct move *);
84 
85 int
checkmove(struct move * mm,int ist)86 checkmove(struct move *mm, int ist)
87 {
88           int     j, n;
89           char    c;
90 
91 domove:
92           if (ist == 0) {
93                     if (tflag)
94                               curmove(curr, 32);
95                     else
96                               writel("\t\t");
97                     writel("Move:  ");
98           }
99           ist = mvl = ncin = 0;
100           for (j = 0; j < 5; j++)
101                     mm->p[j] = mm->g[j] = -1;
102 
103 dochar:
104           c = readc();
105 
106           if (c == 'S') {
107                     raflag = 0;
108                     save(mm, 1);
109                     if (tflag) {
110                               curmove(cturn == -1 ? 18 : 19, 39);
111                               ist = -1;
112                               goto domove;
113                     } else {
114                               proll(mm);
115                               ist = 0;
116                               goto domove;
117                     }
118           }
119           if (c == old.c_cc[VERASE] && ncin > 0) {
120                     if (tflag)
121                               curmove(curr, curc - 1);
122                     else {
123                               if (old.c_cc[VERASE] == '\010')
124                                         writel("\010 \010");
125                               else
126                                         writec(cin[ncin - 1]);
127                     }
128                     ncin--;
129                     n = rsetbrd(mm);
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           if (c == old.c_cc[VKILL] && ncin > 0) {
140                     if (tflag) {
141                               refresh();
142                               curmove(curr, 39);
143                               ist = -1;
144                               goto domove;
145                     } else
146                               if (old.c_cc[VERASE] == '\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(mm);
155                                         ist = 0;
156                                         goto domove;
157                               }
158           }
159           n = dotable(mm, c, ist);
160           if (n >= 0) {
161                     cin[ncin++] = c;
162                     if (n > 2)
163                               if ((!tflag) || c != '\n')
164                                         writec(c);
165                     ist = n;
166                     if (n)
167                               goto dochar;
168                     else
169                               goto domove;
170           }
171           if (n == -1 && mvl >= mm->mvlim)
172                     return (0);
173           if (n == -1 && mvl < mm->mvlim - 1)
174                     return (-4);
175 
176           if (n == -6) {
177                     if (!tflag) {
178                               if (movokay(mm, mvl + 1)) {
179                                         wrboard();
180                                         movback(mm, mvl + 1);
181                               }
182                               proll(mm);
183                               writel("\t\tMove:  ");
184                               for (j = 0; j < ncin;)
185                                         writec(cin[j++]);
186                     } else {
187                               if (movokay(mm, mvl + 1)) {
188                                         refresh();
189                                         movback(mm, mvl + 1);
190                               } else
191                                         curmove(cturn == -1 ? 18 : 19, ncin + 39);
192                     }
193                     ist = n = rsetbrd(mm);
194                     goto dochar;
195           }
196           if (n != -5)
197                     return (n);
198           writec('\007');
199           goto dochar;
200 }
201 
202 static int
dotable(struct move * mm,int c,int i)203 dotable(struct move *mm, int c, int i)
204 {
205           int     a;
206           int     test;
207 
208           test = (c == 'R');
209 
210           while ((a = atmata[i].ch) != '.') {
211                     if (a == c || (test && a == '\n')) {
212                               switch (atmata[i].fcode) {
213 
214                               case 1:
215                                         wrboard();
216                                         if (tflag) {
217                                                   curmove(cturn == -1 ? 18 : 19, 0);
218                                                   proll(mm);
219                                                   writel("\t\t");
220                                         } else
221                                                   proll(mm);
222                                         break;
223 
224                               case 2:
225                                         if (mm->p[mvl] == -1)
226                                                   mm->p[mvl] = c - '0';
227                                         else
228                                                   mm->p[mvl] = mm->p[mvl] * 10 + c - '0';
229                                         break;
230 
231                               case 3:
232                                         if (mm->g[mvl] != -1) {
233                                                   if (mvl < mm->mvlim)
234                                                             mvl++;
235                                                   mm->p[mvl] = mm->p[mvl - 1];
236                                         }
237                                         mm->g[mvl] = mm->p[mvl] + cturn * (c - '0');
238                                         if (mm->g[mvl] < 0)
239                                                   mm->g[mvl] = 0;
240                                         if (mm->g[mvl] > 25)
241                                                   mm->g[mvl] = 25;
242                                         break;
243 
244                               case 4:
245                                         if (mm->g[mvl] == -1)
246                                                   mm->g[mvl] = c - '0';
247                                         else
248                                                   mm->g[mvl] = mm->g[mvl] * 10 + c - '0';
249                                         break;
250 
251                               case 5:
252                                         if (mvl < mm->mvlim)
253                                                   mvl++;
254                                         mm->p[mvl] = mm->g[mvl - 1];
255                                         break;
256 
257                               case 6:
258                                         if (mvl < mm->mvlim)
259                                                   mvl++;
260                                         break;
261 
262                               case 7:
263                                         if (tflag)
264                                                   curmove(20, 0);
265                                         else
266                                                   writec('\n');
267                                         (void) wrtext(help2);
268                                         if (tflag) {
269                                                   curmove(cturn == -1 ? 18 : 19, 39);
270                                         } else {
271                                                   writec('\n');
272                                                   proll(mm);
273                                                   writel("\t\tMove:  ");
274                                         }
275                                         break;
276 
277                               case 8:
278                                         mm->p[mvl] = bar;
279                                         break;
280 
281                               case 9:
282                                         mm->g[mvl] = home;
283                               }
284 
285                               if (!test || a != '\n')
286                                         return (atmata[i].newst);
287                               else
288                                         return (-6);
289                     }
290                     i++;
291           }
292 
293           return (-5);
294 }
295 
296 static int
rsetbrd(struct move * mm)297 rsetbrd(struct move *mm)
298 {
299           int     i, j, n;
300 
301           n = 0;
302           mvl = 0;
303           for (i = 0; i < 4; i++)
304                     mm->p[i] = mm->g[i] = -1;
305           for (j = 0; j < ncin; j++)
306                     if ((n = dotable(mm, cin[j], n)) < 0)
307                               return n;
308           return (n);
309 }
310