1/*	$NetBSD: table.c,v 1.12 2012/10/13 18:44:15 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
35static char sccsid[] = "@(#)table.c	8.1 (Berkeley) 5/31/93";
36#else
37__RCSID("$NetBSD: table.c,v 1.12 2012/10/13 18:44:15 dholland Exp $");
38#endif
39#endif /* not lint */
40
41#include "back.h"
42
43static 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
50struct state {
51	char    ch;
52	int     fcode;
53	int     newst;
54};
55
56static int mvl;			/* working copy of move->mvlim */
57
58static 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
82static int dotable(struct move *, int, int);
83static int rsetbrd(struct move *);
84
85int
86checkmove(struct move *mm, int ist)
87{
88	int     j, n;
89	char    c;
90
91domove:
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
103dochar:
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
202static int
203dotable(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
296static int
297rsetbrd(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