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