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