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