summaryrefslogtreecommitdiffstats
path: root/backgammon/backgammon/main.c
diff options
context:
space:
mode:
authorcgd <cgd@NetBSD.org>1993-03-21 09:45:37 +0000
committercgd <cgd@NetBSD.org>1993-03-21 09:45:37 +0000
commit77e3814f0c0e3dea4d0032e25666f77e6f83bfff (patch)
tree7eddfcbf3dd12089e71dc3fafb0a106c5c5766c7 /backgammon/backgammon/main.c
parente81d63576b2e46ab90da7d75fa155ea57ee4d32e (diff)
downloadbsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.tar.gz
bsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.tar.zst
bsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.zip
initial import of 386bsd-0.1 sources
Diffstat (limited to 'backgammon/backgammon/main.c')
-rw-r--r--backgammon/backgammon/main.c591
1 files changed, 591 insertions, 0 deletions
diff --git a/backgammon/backgammon/main.c b/backgammon/backgammon/main.c
new file mode 100644
index 00000000..82d496a1
--- /dev/null
+++ b/backgammon/backgammon/main.c
@@ -0,0 +1,591 @@
+/*
+ * Copyright (c) 1980 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
+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.6 (Berkeley) 6/1/90";
+#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 ();
+}