|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: char copyright[] = ! 20: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 21: All rights reserved.\n"; ! 22: #endif /* not lint */ ! 23: ! 24: #ifndef lint ! 25: static char sccsid[] = "@(#)main.c 5.5 (Berkeley) 6/18/88"; ! 26: #endif /* not lint */ ! 27: ! 28: #include <stdio.h> ! 29: #include "back.h" ! 30: ! 31: #define MVPAUSE 5 /* time to sleep when stuck */ ! 32: #define MAXUSERS 35 /* maximum number of users */ ! 33: ! 34: char *instr[]; /* text of instructions */ ! 35: char *message[]; /* update message */ ! 36: char ospeed; /* tty output speed */ ! 37: ! 38: char *helpm[] = { /* help message */ ! 39: "Enter a space or newline to roll, or", ! 40: " R to reprint the board\tD to double", ! 41: " S to save the game\tQ to quit", ! 42: 0 ! 43: }; ! 44: ! 45: char *contin[] = { /* pause message */ ! 46: "(Type a newline to continue.)", ! 47: "", ! 48: 0 ! 49: }; ! 50: ! 51: static char user1a[] = ! 52: "Sorry, you cannot play backgammon when there are more than "; ! 53: static char user1b[] = ! 54: " users\non the system."; ! 55: static char user2a[] = ! 56: "\nThere are now more than "; ! 57: static char user2b[] = ! 58: " users on the system, so you cannot play\nanother game. "; ! 59: static char rules[] = "\nDo you want the rules of the game?"; ! 60: static char noteach[] = "Teachgammon not available!\n\007"; ! 61: static char need[] = "Do you need instructions for this program?"; ! 62: static char askcol[] = ! 63: "Enter 'r' to play red, 'w' to play white, 'b' to play both:"; ! 64: static char rollr[] = "Red rolls a "; ! 65: static char rollw[] = ". White rolls a "; ! 66: static char rstart[] = ". Red starts.\n"; ! 67: static char wstart[] = ". White starts.\n"; ! 68: static char toobad1[] = "Too bad, "; ! 69: static char unable[] = " is unable to use that roll.\n"; ! 70: static char toobad2[] = ". Too bad, "; ! 71: static char cantmv[] = " can't move.\n"; ! 72: static char bgammon[] = "Backgammon! "; ! 73: static char gammon[] = "Gammon! "; ! 74: static char again[] = ".\nWould you like to play again?"; ! 75: static char svpromt[] = "Would you like to save this game?"; ! 76: ! 77: static char password[] = "losfurng"; ! 78: static char pbuf[10]; ! 79: ! 80: main (argc,argv) ! 81: int argc; ! 82: char **argv; ! 83: ! 84: { ! 85: register int i; /* non-descript index */ ! 86: register int l; /* non-descript index */ ! 87: register char c; /* non-descript character storage */ ! 88: long t; /* time for random num generator */ ! 89: ! 90: /* initialization */ ! 91: bflag = 2; /* default no board */ ! 92: signal (2,getout); /* trap interrupts */ ! 93: if (gtty (0,&tty) == -1) /* get old tty mode */ ! 94: errexit ("backgammon(gtty)"); ! 95: old = tty.sg_flags; ! 96: #ifdef V7 ! 97: raw = ((noech = old & ~ECHO) | CBREAK); /* set up modes */ ! 98: #else ! 99: raw = ((noech = old & ~ECHO) | RAW); /* set up modes */ ! 100: #endif ! 101: ospeed = tty.sg_ospeed; /* for termlib */ ! 102: ! 103: /* check user count */ ! 104: # ifdef CORY ! 105: if (ucount() > MAXUSERS) { ! 106: writel (user1a); ! 107: wrint (MAXUSERS); ! 108: writel (user1b); ! 109: getout(); ! 110: } ! 111: # endif ! 112: ! 113: /* get terminal ! 114: * capabilities, and ! 115: * decide if it can ! 116: * cursor address */ ! 117: tflag = getcaps (getenv ("TERM")); ! 118: /* use whole screen ! 119: * for text */ ! 120: if (tflag) ! 121: begscr = 0; ! 122: t = time(0); ! 123: srandom(t); /* 'random' seed */ ! 124: ! 125: #ifdef V7 ! 126: while (*++argv != 0) /* process arguments */ ! 127: #else ! 128: while (*++argv != -1) /* process arguments */ ! 129: #endif ! 130: getarg (&argv); ! 131: args[acnt] = '\0'; ! 132: if (tflag) { /* clear screen */ ! 133: noech &= ~(CRMOD|XTABS); ! 134: raw &= ~(CRMOD|XTABS); ! 135: clear(); ! 136: } ! 137: fixtty (raw); /* go into raw mode */ ! 138: ! 139: /* check if restored ! 140: * game and save flag ! 141: * for later */ ! 142: if (rfl = rflag) { ! 143: text (message); /* print message */ ! 144: text (contin); ! 145: wrboard(); /* print board */ ! 146: /* if new game, pretend ! 147: * to be a non-restored ! 148: * game */ ! 149: if (cturn == 0) ! 150: rflag = 0; ! 151: } else { ! 152: rscore = wscore = 0; /* zero score */ ! 153: text (message); /* update message ! 154: * without pausing */ ! 155: ! 156: if (aflag) { /* print rules */ ! 157: writel (rules); ! 158: if (yorn(0)) { ! 159: ! 160: fixtty (old); /* restore tty */ ! 161: execl (TEACH,"teachgammon",args,0); ! 162: ! 163: tflag = 0; /* error! */ ! 164: writel (noteach); ! 165: exit(); ! 166: } else { /* if not rules, then ! 167: * instructions */ ! 168: writel (need); ! 169: if (yorn(0)) { /* print instructions */ ! 170: clear(); ! 171: text (instr); ! 172: } ! 173: } ! 174: } ! 175: ! 176: init(); /* initialize board */ ! 177: ! 178: if (pnum == 2) { /* ask for color(s) */ ! 179: writec ('\n'); ! 180: writel (askcol); ! 181: while (pnum == 2) { ! 182: c = readc(); ! 183: switch (c) { ! 184: ! 185: case 'R': /* red */ ! 186: pnum = -1; ! 187: break; ! 188: ! 189: case 'W': /* white */ ! 190: pnum = 1; ! 191: break; ! 192: ! 193: case 'B': /* both */ ! 194: pnum = 0; ! 195: break; ! 196: ! 197: case 'P': ! 198: if (iroll) ! 199: break; ! 200: if (tflag) ! 201: curmove (curr,0); ! 202: else ! 203: writec ('\n'); ! 204: writel ("Password:"); ! 205: signal (14,getout); ! 206: cflag = 1; ! 207: alarm (10); ! 208: for (i = 0; i < 10; i++) { ! 209: pbuf[i] = readc(); ! 210: if (pbuf[i] == '\n') ! 211: break; ! 212: } ! 213: if (i == 10) ! 214: while (readc() != '\n'); ! 215: alarm (0); ! 216: cflag = 0; ! 217: if (i < 10) ! 218: pbuf[i] = '\0'; ! 219: for (i = 0; i < 9; i++) ! 220: if (pbuf[i] != password[i]) ! 221: getout(); ! 222: iroll = 1; ! 223: if (tflag) ! 224: curmove (curr,0); ! 225: else ! 226: writec ('\n'); ! 227: writel (askcol); ! 228: break; ! 229: ! 230: default: /* error */ ! 231: writec ('\007'); ! 232: } ! 233: } ! 234: } else if (!aflag) ! 235: /* pause to read ! 236: * message */ ! 237: text (contin); ! 238: ! 239: wrboard(); /* print board */ ! 240: ! 241: if (tflag) ! 242: curmove (18,0); ! 243: else ! 244: writec ('\n'); ! 245: } ! 246: /* limit text to bottom ! 247: * of screen */ ! 248: if (tflag) ! 249: begscr = 17; ! 250: ! 251: for (;;) { /* begin game! */ ! 252: /* initial roll if ! 253: * needed */ ! 254: if ((! rflag) || raflag) ! 255: roll(); ! 256: ! 257: /* perform ritual of ! 258: * first roll */ ! 259: if (! rflag) { ! 260: if (tflag) ! 261: curmove (17,0); ! 262: while (D0 == D1) /* no doubles */ ! 263: roll(); ! 264: ! 265: /* print rolls */ ! 266: writel (rollr); ! 267: writec (D0+'0'); ! 268: writel (rollw); ! 269: writec (D1+'0'); ! 270: ! 271: /* winner goes first */ ! 272: if (D0 > D1) { ! 273: writel (rstart); ! 274: cturn = 1; ! 275: } else { ! 276: writel (wstart); ! 277: cturn = -1; ! 278: } ! 279: } ! 280: ! 281: /* initalize variables ! 282: * according to whose ! 283: * turn it is */ ! 284: ! 285: if (cturn == 1) { /* red */ ! 286: home = 25; ! 287: bar = 0; ! 288: inptr = &in[1]; ! 289: inopp = &in[0]; ! 290: offptr = &off[1]; ! 291: offopp = &off[0]; ! 292: Colorptr = &color[1]; ! 293: colorptr = &color[3]; ! 294: colen = 3; ! 295: } else { /* white */ ! 296: home = 0; ! 297: bar = 25; ! 298: inptr = &in[0]; ! 299: inopp = &in[1]; ! 300: offptr = &off[0]; ! 301: offopp = &off[1]; ! 302: Colorptr = &color[0]; ! 303: colorptr = &color[2]; ! 304: colen = 5; ! 305: } ! 306: ! 307: /* do first move ! 308: * (special case) */ ! 309: if (! (rflag && raflag)) { ! 310: if (cturn == pnum) /* computer's move */ ! 311: move (0); ! 312: else { /* player's move */ ! 313: mvlim = movallow(); ! 314: /* reprint roll */ ! 315: if (tflag) ! 316: curmove (cturn == -1? 18: 19,0); ! 317: proll(); ! 318: getmove(); /* get player's move */ ! 319: } ! 320: } ! 321: if (tflag) { ! 322: curmove (17,0); ! 323: cline(); ! 324: begscr = 18; ! 325: } ! 326: ! 327: /* no longer any diff- ! 328: * erence between normal ! 329: * game and recovered ! 330: * game. */ ! 331: rflag = 0; ! 332: ! 333: /* move as long as it's ! 334: * someone's turn */ ! 335: while (cturn == 1 || cturn == -1) { ! 336: ! 337: /* board maintainence */ ! 338: if (tflag) ! 339: refresh(); /* fix board */ ! 340: else ! 341: /* redo board if -p */ ! 342: if (cturn == bflag || bflag == 0) ! 343: wrboard(); ! 344: ! 345: /* do computer's move */ ! 346: if (cturn == pnum) { ! 347: move (1); ! 348: ! 349: /* see if double ! 350: * refused */ ! 351: if (cturn == -2 || cturn == 2) ! 352: break; ! 353: ! 354: /* check for winning ! 355: * move */ ! 356: if (*offopp == 15) { ! 357: cturn *= -2; ! 358: break; ! 359: } ! 360: continue; ! 361: ! 362: } ! 363: ! 364: /* (player's move) */ ! 365: ! 366: /* clean screen if ! 367: * safe */ ! 368: if (tflag && hflag) { ! 369: curmove (20,0); ! 370: clend (); ! 371: hflag = 1; ! 372: } ! 373: ! 374: /* if allowed, give him ! 375: * a chance to double */ ! 376: if (dlast != cturn && gvalue < 64) { ! 377: if (tflag) ! 378: curmove (cturn == -1? 18: 19,0); ! 379: writel (*Colorptr); ! 380: c = readc(); ! 381: ! 382: /* character cases */ ! 383: switch (c) { ! 384: ! 385: /* reprint board */ ! 386: case 'R': ! 387: wrboard(); ! 388: break; ! 389: ! 390: /* save game */ ! 391: case 'S': ! 392: raflag = 1; ! 393: save (1); ! 394: break; ! 395: ! 396: /* quit */ ! 397: case 'Q': ! 398: quit(); ! 399: break; ! 400: ! 401: /* double */ ! 402: case 'D': ! 403: dble(); ! 404: break; ! 405: ! 406: /* roll */ ! 407: case ' ': ! 408: case '\n': ! 409: roll(); ! 410: writel (" rolls "); ! 411: writec (D0+'0'); ! 412: writec (' '); ! 413: writec (D1+'0'); ! 414: writel (". "); ! 415: ! 416: /* see if he can move */ ! 417: if ( (mvlim = movallow()) == 0) { ! 418: ! 419: /* can't move */ ! 420: writel (toobad1); ! 421: writel (*colorptr); ! 422: writel (unable); ! 423: if (tflag) { ! 424: if (pnum) { ! 425: buflush(); ! 426: sleep (MVPAUSE); ! 427: } ! 428: } ! 429: nexturn(); ! 430: break; ! 431: } ! 432: ! 433: /* get move */ ! 434: getmove(); ! 435: ! 436: /* okay to clean ! 437: * screen */ ! 438: hflag = 1; ! 439: break; ! 440: ! 441: /* invalid character */ ! 442: default: ! 443: ! 444: /* print help message */ ! 445: if (tflag) ! 446: curmove (20,0); ! 447: else ! 448: writec ('\n'); ! 449: text (helpm); ! 450: if (tflag) ! 451: curmove (cturn == -1? 18: 19,0); ! 452: else ! 453: writec ('\n'); ! 454: ! 455: /* don't erase */ ! 456: hflag = 0; ! 457: } ! 458: } else { /* couldn't double */ ! 459: ! 460: /* print roll */ ! 461: roll(); ! 462: if (tflag) ! 463: curmove (cturn == -1? 18: 19,0); ! 464: proll (); ! 465: ! 466: /* can he move? */ ! 467: if ((mvlim = movallow()) == 0) { ! 468: ! 469: /* he can't */ ! 470: writel (toobad2); ! 471: writel (*colorptr); ! 472: writel (cantmv); ! 473: buflush(); ! 474: sleep (MVPAUSE); ! 475: nexturn(); ! 476: continue; ! 477: } ! 478: ! 479: /* get move */ ! 480: getmove(); ! 481: } ! 482: } ! 483: ! 484: /* don't worry about who ! 485: * won if quit */ ! 486: if (cturn == 0) ! 487: break; ! 488: ! 489: /* fix cturn = winner */ ! 490: cturn /= -2; ! 491: ! 492: /* final board pos. */ ! 493: if (tflag) ! 494: refresh(); ! 495: ! 496: /* backgammon? */ ! 497: mflag = 0; ! 498: l = bar+7*cturn; ! 499: for (i = bar; i != l; i += cturn) ! 500: if (board[i]*cturn) mflag++; ! 501: ! 502: /* compute game value */ ! 503: if (tflag) ! 504: curmove (20,0); ! 505: if (*offopp == 15) { ! 506: if (mflag) { ! 507: writel (bgammon); ! 508: gvalue *= 3; ! 509: } ! 510: else if (*offptr <= 0) { ! 511: writel (gammon); ! 512: gvalue *= 2; ! 513: } ! 514: } ! 515: ! 516: /* report situation */ ! 517: if (cturn == -1) { ! 518: writel ("Red wins "); ! 519: rscore += gvalue; ! 520: } else { ! 521: writel ("White wins "); ! 522: wscore += gvalue; ! 523: } ! 524: wrint (gvalue); ! 525: writel (" point"); ! 526: if (gvalue > 1) ! 527: writec ('s'); ! 528: writel (".\n"); ! 529: ! 530: /* write score */ ! 531: wrscore(); ! 532: ! 533: /* check user count */ ! 534: # ifdef CORY ! 535: if (ucount() > MAXUSERS) { ! 536: writel (user2a); ! 537: wrint (MAXUSERS); ! 538: writel (user2b); ! 539: rfl = 1; ! 540: break; ! 541: } ! 542: # endif ! 543: ! 544: /* see if he wants ! 545: * another game */ ! 546: writel (again); ! 547: if ((i = yorn ('S')) == 0) ! 548: break; ! 549: ! 550: init(); ! 551: if (i == 2) { ! 552: writel (" Save.\n"); ! 553: cturn = 0; ! 554: save (0); ! 555: } ! 556: ! 557: /* yes, reset game */ ! 558: wrboard(); ! 559: } ! 560: ! 561: /* give him a chance to save if game was recovered */ ! 562: if (rfl && cturn) { ! 563: writel (svpromt); ! 564: if (yorn (0)) { ! 565: /* re-initialize for ! 566: * recovery */ ! 567: init(); ! 568: cturn = 0; ! 569: save(0); ! 570: } ! 571: } ! 572: ! 573: /* leave peacefully */ ! 574: getout (); ! 575: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.