xref: /netbsd-src/games/backgammon/common_source/table.c (revision aaf4ece63a859a04e37cf3a7229b5fab0157cc06)
1 /*	$NetBSD: table.c,v 1.8 2005/07/01 01:12:39 jmc 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.8 2005/07/01 01:12:39 jmc Exp $");
38 #endif
39 #endif /* not lint */
40 
41 #include "back.h"
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 	if (c == old.c_cc[VERASE] && ncin > 0) {
115 		if (tflag)
116 			curmove(curr, curc - 1);
117 		else {
118 			if (old.c_cc[VERASE] == '\010')
119 				writel("\010 \010");
120 			else
121 				writec(cin[ncin - 1]);
122 		}
123 		ncin--;
124 		n = rsetbrd();
125 		if (n == 0) {
126 			n = -1;
127 			if (tflag)
128 				refresh();
129 		}
130 		if ((ist = n) > 0)
131 			goto dochar;
132 		goto domove;
133 	}
134 	if (c == old.c_cc[VKILL] && ncin > 0) {
135 		if (tflag) {
136 			refresh();
137 			curmove(curr, 39);
138 			ist = -1;
139 			goto domove;
140 		} else
141 			if (old.c_cc[VERASE] == '\010') {
142 				for (j = 0; j < ncin; j++)
143 					writel("\010 \010");
144 				ist = -1;
145 				goto domove;
146 			} else {
147 				writec('\\');
148 				writec('\n');
149 				proll();
150 				ist = 0;
151 				goto domove;
152 			}
153 	}
154 	n = dotable(c, ist);
155 	if (n >= 0) {
156 		cin[ncin++] = c;
157 		if (n > 2)
158 			if ((!tflag) || c != '\n')
159 				writec(c);
160 		ist = n;
161 		if (n)
162 			goto dochar;
163 		else
164 			goto domove;
165 	}
166 	if (n == -1 && mvl >= mvlim)
167 		return (0);
168 	if (n == -1 && mvl < mvlim - 1)
169 		return (-4);
170 
171 	if (n == -6) {
172 		if (!tflag) {
173 			if (movokay(mvl + 1)) {
174 				wrboard();
175 				movback(mvl + 1);
176 			}
177 			proll();
178 			writel("\t\tMove:  ");
179 			for (j = 0; j < ncin;)
180 				writec(cin[j++]);
181 		} else {
182 			if (movokay(mvl + 1)) {
183 				refresh();
184 				movback(mvl + 1);
185 			} else
186 				curmove(cturn == -1 ? 18 : 19, ncin + 39);
187 		}
188 		ist = n = rsetbrd();
189 		goto dochar;
190 	}
191 	if (n != -5)
192 		return (n);
193 	writec('\007');
194 	goto dochar;
195 }
196 
197 int
198 dotable(int c, int i)
199 {
200 	int     a;
201 	int     test;
202 
203 	test = (c == 'R');
204 
205 	while ((a = atmata[i].ch) != '.') {
206 		if (a == c || (test && a == '\n')) {
207 			switch (atmata[i].fcode) {
208 
209 			case 1:
210 				wrboard();
211 				if (tflag) {
212 					curmove(cturn == -1 ? 18 : 19, 0);
213 					proll();
214 					writel("\t\t");
215 				} else
216 					proll();
217 				break;
218 
219 			case 2:
220 				if (p[mvl] == -1)
221 					p[mvl] = c - '0';
222 				else
223 					p[mvl] = p[mvl] * 10 + c - '0';
224 				break;
225 
226 			case 3:
227 				if (g[mvl] != -1) {
228 					if (mvl < mvlim)
229 						mvl++;
230 					p[mvl] = p[mvl - 1];
231 				}
232 				g[mvl] = p[mvl] + cturn * (c - '0');
233 				if (g[mvl] < 0)
234 					g[mvl] = 0;
235 				if (g[mvl] > 25)
236 					g[mvl] = 25;
237 				break;
238 
239 			case 4:
240 				if (g[mvl] == -1)
241 					g[mvl] = c - '0';
242 				else
243 					g[mvl] = g[mvl] * 10 + c - '0';
244 				break;
245 
246 			case 5:
247 				if (mvl < mvlim)
248 					mvl++;
249 				p[mvl] = g[mvl - 1];
250 				break;
251 
252 			case 6:
253 				if (mvl < mvlim)
254 					mvl++;
255 				break;
256 
257 			case 7:
258 				if (tflag)
259 					curmove(20, 0);
260 				else
261 					writec('\n');
262 				(void) text(help2);
263 				if (tflag) {
264 					curmove(cturn == -1 ? 18 : 19, 39);
265 				} else {
266 					writec('\n');
267 					proll();
268 					writel("\t\tMove:  ");
269 				}
270 				break;
271 
272 			case 8:
273 				p[mvl] = bar;
274 				break;
275 
276 			case 9:
277 				g[mvl] = home;
278 			}
279 
280 			if (!test || a != '\n')
281 				return (atmata[i].newst);
282 			else
283 				return (-6);
284 		}
285 		i++;
286 	}
287 
288 	return (-5);
289 }
290 
291 int
292 rsetbrd(void)
293 {
294 	int     i, j, n;
295 
296 	n = 0;
297 	mvl = 0;
298 	for (i = 0; i < 4; i++)
299 		p[i] = g[i] = -1;
300 	for (j = 0; j < ncin; j++)
301 		n = dotable(cin[j], n);
302 	return (n);
303 }
304