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.sg_erase && ncin > 0)  {
116 		if (tflag)
117 			curmove (curr,curc-1);
118 		else  {
119 			if (tty.sg_erase == '\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.sg_kill && ncin > 0)  {
137 		if (tflag)  {
138 			refresh();
139 			curmove (curr,39);
140 			ist = -1;
141 			goto domove;
142 		} else  if (tty.sg_erase == '\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 }
310