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