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 * @(#)subs.c 8.1 (Berkeley) 5/31/93 30 * $FreeBSD: src/games/backgammon/common_source/subs.c,v 1.12 1999/11/30 03:48:27 billf Exp $ 31 * $DragonFly: src/games/backgammon/common_source/subs.c,v 1.3 2006/08/08 16:36:11 pavalos Exp $ 32 */ 33 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include "back.h" 38 39 int buffnum; 40 char outbuff[BUFSIZ]; 41 42 static const char plred[] = "Player is red, computer is white."; 43 static const char plwhite[] = "Player is white, computer is red."; 44 static const char nocomp[] = "(No computer play.)"; 45 46 const char *const descr[] = { 47 "Usage: backgammon [-h n r w b pr pw pb tterm sfile]\n", 48 "\t-h\tgets this list\n\t-n\tdon't ask for rules or instructions", 49 "\t-r\tplayer is red (implies -n)\n\t-w\tplayer is white (implies -n)", 50 "\t-b\ttwo players, red and white (implies -n)", 51 "\t-pr\tprint the board before red's turn", 52 "\t-pw\tprint the board before white's turn", 53 "\t-pb\tprint the board before both player's turn", 54 "\t-tterm\tterminal is a term", 55 "\t-sfile\trecover saved game from file", 56 0 57 }; 58 59 void 60 errexit(const char *s) 61 { 62 write(2, "\n", 1); 63 perror(s); 64 getout(); 65 } 66 67 int 68 addbuf(int c) 69 { 70 buffnum++; 71 if (buffnum == BUFSIZ) { 72 if (write(1, outbuff, BUFSIZ) != BUFSIZ) 73 errexit("addbuf (write):"); 74 buffnum = 0; 75 } 76 outbuff[buffnum] = c; 77 return (0); 78 } 79 80 void 81 buflush(void) 82 { 83 if (buffnum < 0) 84 return; 85 buffnum++; 86 if (write(1, outbuff, buffnum) != buffnum) 87 errexit("buflush (write):"); 88 buffnum = -1; 89 } 90 91 char 92 readc(void) 93 { 94 char c; 95 96 if (tflag) { 97 cline(); 98 newpos(); 99 } 100 buflush(); 101 if (read(0, &c, 1) != 1) 102 errexit("readc"); 103 #ifdef WHY_IS_THIS_HARDWIRED_IN_HERE 104 if (c == '\177') 105 getout(); 106 #endif 107 if (c == '\033' || c == '\015') 108 return ('\n'); 109 if (cflag) 110 return (c); 111 if (c == '\014') 112 return ('R'); 113 if (c >= 'a' && c <= 'z') 114 return (c & 0137); 115 return (c); 116 } 117 118 void 119 writec(char c) 120 { 121 if (tflag) 122 fancyc(c); 123 else 124 addbuf(c); 125 } 126 127 void 128 writel(const char *l) 129 { 130 #ifdef DEBUG 131 const char *s; 132 133 if (trace == NULL) 134 trace = fopen("bgtrace", "w"); 135 136 fprintf(trace, "writel: \""); 137 for (s = l; *s; s++) { 138 if (*s < ' ' || *s == '\177') 139 fprintf(trace, "^%c", (*s) ^ 0100); 140 else 141 putc(*s, trace); 142 } 143 fprintf(trace, "\"\n"); 144 fflush(trace); 145 #endif 146 147 while (*l) 148 writec(*l++); 149 } 150 151 void 152 proll(void) 153 { 154 if (d0) 155 swap; 156 if (cturn == 1) 157 writel("Red's roll: "); 158 else 159 writel("White's roll: "); 160 writec(D0 + '0'); 161 writec('\040'); 162 writec(D1 + '0'); 163 if (tflag) 164 cline(); 165 } 166 167 void 168 wrint(int n) 169 { 170 int i, j, t; 171 172 for (i = 4; i > 0; i--) { 173 t = 1; 174 for (j = 0; j < i; j++) 175 t *= 10; 176 if (n > t - 1) 177 writec((n / t) % 10 + '0'); 178 } 179 writec(n % 10 + '0'); 180 } 181 182 void 183 gwrite(void) 184 { 185 int r, c; 186 187 r = curr; 188 c = curc; 189 190 if (tflag) 191 curmove(16, 0); 192 193 if (gvalue > 1) { 194 writel("Game value: "); 195 wrint(gvalue); 196 writel(". "); 197 if (dlast == -1) 198 writel(color[0]); 199 else 200 writel(color[1]); 201 writel(" doubled last."); 202 } else { 203 switch (pnum) { 204 case -1: /* player is red */ 205 writel(plred); 206 break; 207 case 0: /* player is both colors */ 208 writel(nocomp); 209 break; 210 case 1: /* player is white */ 211 writel(plwhite); 212 } 213 } 214 215 if (rscore || wscore) { 216 writel(" "); 217 wrscore(); 218 } 219 if (tflag) { 220 cline(); 221 curmove(r, c); 222 } 223 } 224 225 int 226 quit(void) 227 { 228 if (tflag) { 229 curmove(20, 0); 230 clend(); 231 } else 232 writec('\n'); 233 writel("Are you sure you want to quit?"); 234 if (yorn(0)) { 235 if (rfl) { 236 writel("Would you like to save this game?"); 237 if (yorn(0)) 238 save(0); 239 } 240 cturn = 0; 241 return (1); 242 } 243 return (0); 244 } 245 246 int 247 yorn(char special) 248 { 249 char c; 250 int i; 251 252 i = 1; 253 while ((c = readc()) != 'Y' && c != 'N') { 254 if (special && c == special) 255 return (2); 256 if (i) { 257 if (special) { 258 writel(" (Y, N, or "); 259 writec(special); 260 writec(')'); 261 } else 262 writel(" (Y or N)"); 263 i = 0; 264 } else 265 writec('\007'); 266 } 267 if (c == 'Y') 268 writel(" Yes.\n"); 269 else 270 writel(" No.\n"); 271 if (tflag) 272 buflush(); 273 return (c == 'Y'); 274 } 275 276 void 277 wrhit(int i) 278 { 279 writel("Blot hit on "); 280 wrint(i); 281 writec('.'); 282 writec('\n'); 283 } 284 285 void 286 nexturn(void) 287 { 288 int c; 289 290 cturn = -cturn; 291 c = cturn / abs(cturn); 292 home = bar; 293 bar = 25 - bar; 294 offptr += c; 295 offopp -= c; 296 inptr += c; 297 inopp -= c; 298 Colorptr += c; 299 colorptr += c; 300 } 301 302 void 303 getarg(int argc, char **argv) 304 { 305 char ch; 306 int i; 307 308 /* process arguments here. dashes are ignored, nbrw are ignored if 309 * the game is being recovered */ 310 311 while ((ch = getopt(argc, argv, "nbrwp:t:s:h")) != -1) { 312 switch (ch) { 313 /* don't ask if rules or instructions needed */ 314 case 'n': 315 if (rflag) 316 break; 317 aflag = 0; 318 args[acnt++] = strdup("-n"); 319 break; 320 321 /* player is both red and white */ 322 case 'b': 323 if (rflag) 324 break; 325 pnum = 0; 326 aflag = 0; 327 args[acnt++] = strdup("-b"); 328 break; 329 330 /* player is red */ 331 case 'r': 332 if (rflag) 333 break; 334 pnum = -1; 335 aflag = 0; 336 args[acnt++] = strdup("-r"); 337 break; 338 339 /* player is white */ 340 case 'w': 341 if (rflag) 342 break; 343 pnum = 1; 344 aflag = 0; 345 args[acnt++] = strdup("-w"); 346 break; 347 348 /* print board after move according to following character */ 349 case 'p': 350 if (optarg[0] != 'r' && optarg[0] != 'w' && 351 optarg[0] != 'b') 352 break; 353 args[acnt] = strdup("-p "); 354 args[acnt++][2] = optarg[0]; 355 if (optarg[0] == 'r') 356 bflag = 1; 357 if (optarg[0] == 'w') 358 bflag = -1; 359 if (optarg[0] == 'b') 360 bflag = 0; 361 break; 362 363 case 't': 364 tflag = getcaps(optarg); 365 break; 366 367 case 's': 368 /* recover file */ 369 recover(optarg); 370 break; 371 case 'h': 372 for (i = 0; descr[i] != 0; i++) 373 puts(descr[i]); 374 getout(); 375 } 376 } 377 argc -= optind; 378 argv += optind; 379 if (argc && argv[0][0] != '\0') 380 recover(argv[0]); 381 } 382 383 void 384 init(void) 385 { 386 int i; 387 388 for (i = 0; i < 26; ) 389 board[i++] = 0; 390 board[1] = 2; 391 board[6] = board[13] = -5; 392 board[8] = -3; 393 board[12] = board[19] = 5; 394 board[17] = 3; 395 board[24] = -2; 396 off[0] = off[1] = -15; 397 in[0] = in[1] = 5; 398 gvalue = 1; 399 dlast = 0; 400 } 401 402 void 403 wrscore(void) 404 { 405 writel("Score: "); 406 writel(color[1]); 407 writec(' '); 408 wrint(rscore); 409 writel(", "); 410 writel(color[0]); 411 writec(' '); 412 wrint(wscore); 413 } 414 415 void 416 fixtty(int mode) 417 { 418 if (tflag) 419 newpos(); 420 buflush(); 421 tty.c_lflag = mode; 422 if (tcsetattr(0, TCSANOW, &tty) < 0) 423 errexit("fixtty"); 424 } 425 426 void 427 getout(void) 428 { 429 /* go to bottom of screen */ 430 if (tflag) { 431 curmove(23, 0); 432 cline(); 433 } else 434 writec('\n'); 435 436 /* fix terminal status */ 437 fixtty(old); 438 exit(0); 439 } 440 441 void 442 roll(void) 443 { 444 char c; 445 int row; 446 int col; 447 448 if (iroll) { 449 row = curr; 450 col = curc; 451 if (tflag) 452 curmove(17, 0); 453 else 454 writec('\n'); 455 writel("ROLL: "); 456 c = readc(); 457 if (c != '\n') { 458 while (c < '1' || c > '6') 459 c = readc(); 460 D0 = c - '0'; 461 writec(' '); 462 writec(c); 463 c = readc(); 464 while (c < '1' || c > '6') 465 c = readc(); 466 D1 = c - '0'; 467 writec(' '); 468 writec(c); 469 if (tflag) { 470 curmove(17, 0); 471 cline(); 472 curmove(row, col); 473 } else 474 writec('\n'); 475 return; 476 } 477 if (tflag) { 478 curmove(17, 0); 479 cline(); 480 curmove(row, col); 481 } else 482 writec('\n'); 483 } 484 D0 = rnum(6) + 1; 485 D1 = rnum(6) + 1; 486 d0 = 0; 487 } 488