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