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