/* * Copyright (c) 1980 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */ #ifndef lint char copyright[] = "@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n"; #endif not lint #ifndef lint static char sccsid[] = "@(#)main.c 5.1 (Berkeley) 5/29/85"; #endif not lint #include #include "back.h" #define MVPAUSE 5 /* time to sleep when stuck */ #define MAXUSERS 35 /* maximum number of users */ char *instr[]; /* text of instructions */ char *message[]; /* update message */ char ospeed; /* tty output speed */ char *helpm[] = { /* help message */ "Enter a space or newline to roll, or", " R to reprint the board\tD to double", " S to save the game\tQ to quit", 0 }; char *contin[] = { /* pause message */ "(Type a newline to continue.)", "", 0 }; static char user1a[] = "Sorry, you cannot play backgammon when there are more than "; static char user1b[] = " users\non the system."; static char user2a[] = "\nThere are now more than "; static char user2b[] = " users on the system, so you cannot play\nanother game. "; static char rules[] = "\nDo you want the rules of the game?"; static char noteach[] = "Teachgammon not available!\n\007"; static char need[] = "Do you need instructions for this program?"; static char askcol[] = "Enter 'r' to play red, 'w' to play white, 'b' to play both:"; static char rollr[] = "Red rolls a "; static char rollw[] = ". White rolls a "; static char rstart[] = ". Red starts.\n"; static char wstart[] = ". White starts.\n"; static char toobad1[] = "Too bad, "; static char unable[] = " is unable to use that roll.\n"; static char toobad2[] = ". Too bad, "; static char cantmv[] = " can't move.\n"; static char bgammon[] = "Backgammon! "; static char gammon[] = "Gammon! "; static char again[] = ".\nWould you like to play again?"; static char svpromt[] = "Would you like to save this game?"; static char password[] = "losfurng"; static char pbuf[10]; main (argc,argv) int argc; char **argv; { register int i; /* non-descript index */ register int l; /* non-descript index */ register char c; /* non-descript character storage */ long t; /* time for random num generator */ /* initialization */ bflag = 2; /* default no board */ signal (2,getout); /* trap interrupts */ if (gtty (0,&tty) == -1) /* get old tty mode */ errexit ("backgammon(gtty)"); old = tty.sg_flags; #ifdef V7 raw = ((noech = old & ~ECHO) | CBREAK); /* set up modes */ #else raw = ((noech = old & ~ECHO) | RAW); /* set up modes */ #endif ospeed = old.sg_ospeed; /* for termlib */ /* check user count */ # ifdef CORY if (ucount() > MAXUSERS) { writel (user1a); wrint (MAXUSERS); writel (user1b); getout(); } # endif /* get terminal * capabilities, and * decide if it can * cursor address */ tflag = getcaps (getenv ("TERM")); /* use whole screen * for text */ if (tflag) begscr = 0; t = time(0); srandom(t); /* 'random' seed */ #ifdef V7 while (*++argv != 0) /* process arguments */ #else while (*++argv != -1) /* process arguments */ #endif getarg (&argv); args[acnt] = '\0'; if (tflag) { /* clear screen */ noech &= ~(CRMOD|XTABS); raw &= ~(CRMOD|XTABS); clear(); } fixtty (raw); /* go into raw mode */ /* check if restored * game and save flag * for later */ if (rfl = rflag) { text (message); /* print message */ text (contin); wrboard(); /* print board */ /* if new game, pretend * to be a non-restored * game */ if (cturn == 0) rflag = 0; } else { rscore = wscore = 0; /* zero score */ text (message); /* update message * without pausing */ if (aflag) { /* print rules */ writel (rules); if (yorn(0)) { fixtty (old); /* restore tty */ execl (TEACH,"backgammon",args,0); tflag = 0; /* error! */ writel (noteach); exit(); } else { /* if not rules, then * instructions */ writel (need); if (yorn(0)) { /* print instructions */ clear(); text (instr); } } } init(); /* initialize board */ if (pnum == 2) { /* ask for color(s) */ writec ('\n'); writel (askcol); while (pnum == 2) { c = readc(); switch (c) { case 'R': /* red */ pnum = -1; break; case 'W': /* white */ pnum = 1; break; case 'B': /* both */ pnum = 0; break; case 'P': if (iroll) break; if (tflag) curmove (curr,0); else writec ('\n'); writel ("Password:"); signal (14,getout); cflag = 1; alarm (10); for (i = 0; i < 10; i++) { pbuf[i] = readc(); if (pbuf[i] == '\n') break; } if (i == 10) while (readc() != '\n'); alarm (0); cflag = 0; if (i < 10) pbuf[i] = '\0'; for (i = 0; i < 9; i++) if (pbuf[i] != password[i]) getout(); iroll = 1; if (tflag) curmove (curr,0); else writec ('\n'); writel (askcol); break; default: /* error */ writec ('\007'); } } } else if (!aflag) /* pause to read * message */ text (contin); wrboard(); /* print board */ if (tflag) curmove (18,0); else writec ('\n'); } /* limit text to bottom * of screen */ if (tflag) begscr = 17; for (;;) { /* begin game! */ /* initial roll if * needed */ if ((! rflag) || raflag) roll(); /* perform ritual of * first roll */ if (! rflag) { if (tflag) curmove (17,0); while (D0 == D1) /* no doubles */ roll(); /* print rolls */ writel (rollr); writec (D0+'0'); writel (rollw); writec (D1+'0'); /* winner goes first */ if (D0 > D1) { writel (rstart); cturn = 1; } else { writel (wstart); cturn = -1; } } /* initalize variables * according to whose * turn it is */ if (cturn == 1) { /* red */ home = 25; bar = 0; inptr = &in[1]; inopp = &in[0]; offptr = &off[1]; offopp = &off[0]; Colorptr = &color[1]; colorptr = &color[3]; colen = 3; } else { /* white */ home = 0; bar = 25; inptr = &in[0]; inopp = &in[1]; offptr = &off[0]; offopp = &off[1]; Colorptr = &color[0]; colorptr = &color[2]; colen = 5; } /* do first move * (special case) */ if (! (rflag && raflag)) { if (cturn == pnum) /* computer's move */ move (0); else { /* player's move */ mvlim = movallow(); /* reprint roll */ if (tflag) curmove (cturn == -1? 18: 19,0); proll(); getmove(); /* get player's move */ } } if (tflag) { curmove (17,0); cline(); begscr = 18; } /* no longer any diff- * erence between normal * game and recovered * game. */ rflag = 0; /* move as long as it's * someone's turn */ while (cturn == 1 || cturn == -1) { /* board maintainence */ if (tflag) refresh(); /* fix board */ else /* redo board if -p */ if (cturn == bflag || bflag == 0) wrboard(); /* do computer's move */ if (cturn == pnum) { move (1); /* see if double * refused */ if (cturn == -2 || cturn == 2) break; /* check for winning * move */ if (*offopp == 15) { cturn *= -2; break; } continue; } /* (player's move) */ /* clean screen if * safe */ if (tflag && hflag) { curmove (20,0); clend (); hflag = 1; } /* if allowed, give him * a chance to double */ if (dlast != cturn && gvalue < 64) { if (tflag) curmove (cturn == -1? 18: 19,0); writel (*Colorptr); c = readc(); /* character cases */ switch (c) { /* reprint board */ case 'R': wrboard(); break; /* save game */ case 'S': raflag = 1; save (1); break; /* quit */ case 'Q': quit(); break; /* double */ case 'D': dble(); break; /* roll */ case ' ': case '\n': roll(); writel (" rolls "); writec (D0+'0'); writec (' '); writec (D1+'0'); writel (". "); /* see if he can move */ if ( (mvlim = movallow()) == 0) { /* can't move */ writel (toobad1); writel (*colorptr); writel (unable); if (tflag) { if (pnum) { buflush(); sleep (MVPAUSE); } } nexturn(); break; } /* get move */ getmove(); /* okay to clean * screen */ hflag = 1; break; /* invalid character */ default: /* print help message */ if (tflag) curmove (20,0); else writec ('\n'); text (helpm); if (tflag) curmove (cturn == -1? 18: 19,0); else writec ('\n'); /* don't erase */ hflag = 0; } } else { /* couldn't double */ /* print roll */ roll(); if (tflag) curmove (cturn == -1? 18: 19,0); proll (); /* can he move? */ if ((mvlim = movallow()) == 0) { /* he can't */ writel (toobad2); writel (*colorptr); writel (cantmv); buflush(); sleep (MVPAUSE); nexturn(); continue; } /* get move */ getmove(); } } /* don't worry about who * won if quit */ if (cturn == 0) break; /* fix cturn = winner */ cturn /= -2; /* final board pos. */ if (tflag) refresh(); /* backgammon? */ mflag = 0; l = bar+7*cturn; for (i = bar; i != l; i += cturn) if (board[i]*cturn) mflag++; /* compute game value */ if (tflag) curmove (20,0); if (*offopp == 15) { if (mflag) { writel (bgammon); gvalue *= 3; } else if (*offptr <= 0) { writel (gammon); gvalue *= 2; } } /* report situation */ if (cturn == -1) { writel ("Red wins "); rscore += gvalue; } else { writel ("White wins "); wscore += gvalue; } wrint (gvalue); writel (" point"); if (gvalue > 1) writec ('s'); writel (".\n"); /* write score */ wrscore(); /* check user count */ # ifdef CORY if (ucount() > MAXUSERS) { writel (user2a); wrint (MAXUSERS); writel (user2b); rfl = 1; break; } # endif /* see if he wants * another game */ writel (again); if ((i = yorn ('S')) == 0) break; init(); if (i == 2) { writel (" Save.\n"); cturn = 0; save (0); } /* yes, reset game */ wrboard(); } /* give him a chance to save if game was recovered */ if (rfl && cturn) { writel (svpromt); if (yorn (0)) { /* re-initialize for * recovery */ init(); cturn = 0; save(0); } } /* leave peacefully */ getout (); }