Jordan K. Hubbard 554eb505f8 Bring in the 4.4 Lite games directory, modulo man page changes and segregation
of the x11 based games.  I'm not going to tag the originals with bsd_44_lite
and do this in two stages since it's just not worth it for this collection,
and I've got directory renames to deal with that way.  Bleah.
Submitted by:	jkh
1994-09-04 04:03:31 +00:00

592 lines
13 KiB
C

/*
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1980, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 5/31/93";
#endif /* not lint */
#include <stdio.h>
#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 = tty.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,"teachgammon",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 ();
}