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