1 /* $NetBSD: subs.c,v 1.13 1999/10/04 23:26:59 lukem Exp $ */ 2 3 /* 4 * Copyright (c) 1980, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <sys/cdefs.h> 37 #ifndef lint 38 #if 0 39 static char sccsid[] = "@(#)subs.c 8.1 (Berkeley) 5/31/93"; 40 #else 41 __RCSID("$NetBSD: subs.c,v 1.13 1999/10/04 23:26:59 lukem Exp $"); 42 #endif 43 #endif /* not lint */ 44 45 #include "back.h" 46 47 int buffnum; 48 char outbuff[BUFSIZ]; 49 50 static const char plred[] = "Player is red, computer is white."; 51 static const char plwhite[] = "Player is white, computer is red."; 52 static const char nocomp[] = "(No computer play.)"; 53 54 const char *const descr[] = { 55 "Usage: backgammon [-] [n r w b pr pw pb t3a]\n", 56 "\t-\tgets this list\n\tn\tdon't ask for rules or instructions", 57 "\tr\tplayer is red (implies n)\n\tw\tplayer is white (implies n)", 58 "\tb\ttwo players, red and white (implies n)", 59 "\tpr\tprint the board before red's turn", 60 "\tpw\tprint the board before white's turn", 61 "\tpb\tprint the board before both player's turn", 62 "\tterm\tterminal is a term", 63 "\tsfile\trecover saved game from file", 64 0 65 }; 66 67 void 68 errexit(s) 69 const char *s; 70 { 71 write(2, "\n", 1); 72 perror(s); 73 getout(0); 74 } 75 76 int 77 addbuf(c) 78 int c; 79 { 80 buffnum++; 81 if (buffnum == BUFSIZ) { 82 if (write(1, outbuff, BUFSIZ) != BUFSIZ) 83 errexit("addbuf (write):"); 84 buffnum = 0; 85 } 86 outbuff[buffnum] = c; 87 return (0); 88 } 89 90 void 91 buflush() 92 { 93 if (buffnum < 0) 94 return; 95 buffnum++; 96 if (write(1, outbuff, buffnum) != buffnum) 97 errexit("buflush (write):"); 98 buffnum = -1; 99 } 100 101 int 102 readc() 103 { 104 char c; 105 106 if (tflag) { 107 cline(); 108 newpos(); 109 } 110 buflush(); 111 if (read(0, &c, 1) != 1) 112 errexit("readc"); 113 #ifdef WHY_IS_THIS_HARDWIRED_IN_HERE 114 if (c == '\177') 115 getout(0); 116 #endif 117 if (c == '\033' || c == '\015') 118 return ('\n'); 119 if (cflag) 120 return (c); 121 if (c == '\014') 122 return ('R'); 123 if (c >= 'a' && c <= 'z') 124 return (c & 0137); 125 return (c); 126 } 127 128 void 129 writec(c) 130 char c; 131 { 132 if (tflag) 133 fancyc(c); 134 else 135 addbuf(c); 136 } 137 138 void 139 writel(l) 140 const char *l; 141 { 142 #ifdef DEBUG 143 const char *s; 144 145 if (trace == NULL) 146 trace = fopen("bgtrace", "w"); 147 148 fprintf(trace, "writel: \""); 149 for (s = l; *s; s++) { 150 if (*s < ' ' || *s == '\177') 151 fprintf(trace, "^%c", (*s) ^ 0100); 152 else 153 putc(*s, trace); 154 } 155 fprintf(trace, "\"\n"); 156 fflush(trace); 157 #endif 158 159 while (*l) 160 writec(*l++); 161 } 162 163 void 164 proll() 165 { 166 if (d0) 167 swap; 168 if (cturn == 1) 169 writel("Red's roll: "); 170 else 171 writel("White's roll: "); 172 writec(D0 + '0'); 173 writec('\040'); 174 writec(D1 + '0'); 175 if (tflag) 176 cline(); 177 } 178 179 void 180 wrint(n) 181 int n; 182 { 183 int i, j, t; 184 185 for (i = 4; i > 0; i--) { 186 t = 1; 187 for (j = 0; j < i; j++) 188 t *= 10; 189 if (n > t - 1) 190 writec((n / t) % 10 + '0'); 191 } 192 writec(n % 10 + '0'); 193 } 194 195 void 196 gwrite() 197 { 198 int r, c; 199 200 r = c = 0; 201 if (tflag) { 202 r = curr; 203 c = curc; 204 curmove(16, 0); 205 } 206 if (gvalue > 1) { 207 writel("Game value: "); 208 wrint(gvalue); 209 writel(". "); 210 if (dlast == -1) 211 writel(color[0]); 212 else 213 writel(color[1]); 214 writel(" doubled last."); 215 } else { 216 switch (pnum) { 217 case -1: /* player is red */ 218 writel(plred); 219 break; 220 case 0: /* player is both colors */ 221 writel(nocomp); 222 break; 223 case 1: /* player is white */ 224 writel(plwhite); 225 } 226 } 227 228 if (rscore || wscore) { 229 writel(" "); 230 wrscore(); 231 } 232 if (tflag) { 233 cline(); 234 curmove(r, c); 235 } 236 } 237 238 int 239 quit() 240 { 241 242 if (tflag) { 243 curmove(20, 0); 244 clend(); 245 } else 246 writec('\n'); 247 writel("Are you sure you want to quit?"); 248 if (yorn(0)) { 249 if (rfl) { 250 writel("Would you like to save this game?"); 251 if (yorn(0)) 252 save(0); 253 } 254 cturn = 0; 255 return (1); 256 } 257 return (0); 258 } 259 260 int 261 yorn(special) 262 char special; /* special response */ 263 { 264 char c; 265 int i; 266 267 i = 1; 268 while ((c = readc()) != 'Y' && c != 'N') { 269 if (special && c == special) 270 return (2); 271 if (i) { 272 if (special) { 273 writel(" (Y, N, or "); 274 writec(special); 275 writec(')'); 276 } else 277 writel(" (Y or N)"); 278 i = 0; 279 } else 280 writec('\007'); 281 } 282 if (c == 'Y') 283 writel(" Yes.\n"); 284 else 285 writel(" No.\n"); 286 if (tflag) 287 buflush(); 288 return (c == 'Y'); 289 } 290 291 void 292 wrhit(i) 293 int i; 294 { 295 writel("Blot hit on "); 296 wrint(i); 297 writec('.'); 298 writec('\n'); 299 } 300 301 void 302 nexturn() 303 { 304 int c; 305 306 cturn = -cturn; 307 c = cturn / abs(cturn); 308 home = bar; 309 bar = 25 - bar; 310 offptr += c; 311 offopp -= c; 312 inptr += c; 313 inopp -= c; 314 Colorptr += c; 315 colorptr += c; 316 } 317 318 void 319 getarg(arg) 320 char ***arg; 321 { 322 char **s; 323 324 /* process arguments here. dashes are ignored, nbrw are ignored if 325 * the game is being recovered */ 326 327 s = *arg; 328 while (*s && s[0][0] == '-') { 329 switch (s[0][1]) { 330 331 /* don't ask if rules or instructions needed */ 332 case 'n': 333 if (rflag) 334 break; 335 aflag = 0; 336 args[acnt++] = 'n'; 337 break; 338 339 /* player is both red and white */ 340 case 'b': 341 if (rflag) 342 break; 343 pnum = 0; 344 aflag = 0; 345 args[acnt++] = 'b'; 346 break; 347 348 /* player is red */ 349 case 'r': 350 if (rflag) 351 break; 352 pnum = -1; 353 aflag = 0; 354 args[acnt++] = 'r'; 355 break; 356 357 /* player is white */ 358 case 'w': 359 if (rflag) 360 break; 361 pnum = 1; 362 aflag = 0; 363 args[acnt++] = 'w'; 364 break; 365 366 /* print board after move according to following 367 * character */ 368 case 'p': 369 if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b') 370 break; 371 args[acnt++] = 'p'; 372 args[acnt++] = s[0][2]; 373 if (s[0][2] == 'r') 374 bflag = 1; 375 if (s[0][2] == 'w') 376 bflag = -1; 377 if (s[0][2] == 'b') 378 bflag = 0; 379 break; 380 381 case 't': 382 if (s[0][2] == '\0') { /* get terminal caps */ 383 s++; 384 tflag = getcaps(*s); 385 } else 386 tflag = getcaps(&s[0][2]); 387 break; 388 389 case 's': 390 s++; 391 /* recover file */ 392 if (s[0] == NULL) { 393 writel("No save file named\n"); 394 getout(0); 395 } else 396 recover(s[0]); 397 break; 398 } 399 s++; 400 } 401 if (s[0] != 0) 402 recover(s[0]); 403 } 404 405 void 406 init() 407 { 408 int i; 409 410 for (i = 0; i < 26;) 411 board[i++] = 0; 412 board[1] = 2; 413 board[6] = board[13] = -5; 414 board[8] = -3; 415 board[12] = board[19] = 5; 416 board[17] = 3; 417 board[24] = -2; 418 off[0] = off[1] = -15; 419 in[0] = in[1] = 5; 420 gvalue = 1; 421 dlast = 0; 422 } 423 424 void 425 wrscore() 426 { 427 writel("Score: "); 428 writel(color[1]); 429 writec(' '); 430 wrint(rscore); 431 writel(", "); 432 writel(color[0]); 433 writec(' '); 434 wrint(wscore); 435 } 436 437 void 438 fixtty(t) 439 struct termios *t; 440 { 441 if (tflag) 442 newpos(); 443 buflush(); 444 if (tcsetattr(0, TCSADRAIN, t) < 0) 445 errexit("fixtty"); 446 } 447 448 void 449 getout(dummy) 450 int dummy __attribute__((__unused__)); 451 { 452 /* go to bottom of screen */ 453 if (tflag) { 454 curmove(23, 0); 455 cline(); 456 } else 457 writec('\n'); 458 459 /* fix terminal status */ 460 fixtty(&old); 461 exit(0); 462 } 463 464 void 465 roll() 466 { 467 char c; 468 int row; 469 int col; 470 471 row = col = 0; 472 if (iroll) { 473 if (tflag) { 474 row = curr; 475 col = curc; 476 curmove(17, 0); 477 } else 478 writec('\n'); 479 writel("ROLL: "); 480 c = readc(); 481 if (c != '\n') { 482 while (c < '1' || c > '6') 483 c = readc(); 484 D0 = c - '0'; 485 writec(' '); 486 writec(c); 487 c = readc(); 488 while (c < '1' || c > '6') 489 c = readc(); 490 D1 = c - '0'; 491 writec(' '); 492 writec(c); 493 if (tflag) { 494 curmove(17, 0); 495 cline(); 496 curmove(row, col); 497 } else 498 writec('\n'); 499 return; 500 } 501 if (tflag) { 502 curmove(17, 0); 503 cline(); 504 curmove(row, col); 505 } else 506 writec('\n'); 507 } 508 D0 = rnum(6) + 1; 509 D1 = rnum(6) + 1; 510 d0 = 0; 511 } 512