summaryrefslogtreecommitdiffstats
path: root/backgammon
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
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')
-rw-r--r--backgammon/Makefile5
-rw-r--r--backgammon/backgammon/Makefile14
-rw-r--r--backgammon/backgammon/backgammon.6205
-rw-r--r--backgammon/backgammon/extra.c253
-rw-r--r--backgammon/backgammon/main.c591
-rw-r--r--backgammon/backgammon/move.c551
-rw-r--r--backgammon/backgammon/text.c132
-rw-r--r--backgammon/backgammon/version.c41
-rw-r--r--backgammon/common_source/allow.c109
-rw-r--r--backgammon/common_source/back.h127
-rw-r--r--backgammon/common_source/backgammon.c751
-rw-r--r--backgammon/common_source/board.c176
-rw-r--r--backgammon/common_source/check.c158
-rw-r--r--backgammon/common_source/fancy.c748
-rw-r--r--backgammon/common_source/init.c65
-rw-r--r--backgammon/common_source/odds.c113
-rw-r--r--backgammon/common_source/one.c169
-rw-r--r--backgammon/common_source/save.c180
-rw-r--r--backgammon/common_source/subs.c477
-rw-r--r--backgammon/common_source/table.c308
-rw-r--r--backgammon/teachgammon/Makefile15
-rw-r--r--backgammon/teachgammon/data.c315
-rw-r--r--backgammon/teachgammon/teach.c166
-rw-r--r--backgammon/teachgammon/ttext1.c184
-rw-r--r--backgammon/teachgammon/ttext2.c193
-rw-r--r--backgammon/teachgammon/tutor.c155
-rw-r--r--backgammon/teachgammon/tutor.h45
27 files changed, 6246 insertions, 0 deletions
diff --git a/backgammon/Makefile b/backgammon/Makefile
new file mode 100644
index 00000000..01b2160a
--- /dev/null
+++ b/backgammon/Makefile
@@ -0,0 +1,5 @@
+# @(#)Makefile 5.1 (Berkeley) 6/17/90
+
+SUBDIR= backgammon teachgammon
+
+.include <bsd.subdir.mk>
diff --git a/backgammon/backgammon/Makefile b/backgammon/backgammon/Makefile
new file mode 100644
index 00000000..99f49252
--- /dev/null
+++ b/backgammon/backgammon/Makefile
@@ -0,0 +1,14 @@
+# @(#)Makefile 5.16 (Berkeley) 5/11/90
+
+PROG= backgammon
+CFLAGS+=-DV7 -I${.CURDIR}/../common_source
+SRCS= allow.c board.c check.c extra.c fancy.c init.c main.c move.c \
+ odds.c one.c save.c subs.c table.c text.c version.c
+MAN6= backgammon.0
+DPADD= ${LIBTERM} ${LIBCOMPAT}
+LDADD= -ltermcap -lcompat
+.PATH: ${.CURDIR}/../common_source
+HIDEGAME=hidegame
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/backgammon/backgammon/backgammon.6 b/backgammon/backgammon/backgammon.6
new file mode 100644
index 00000000..3718acb6
--- /dev/null
+++ b/backgammon/backgammon/backgammon.6
@@ -0,0 +1,205 @@
+.\" 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.
+.\"
+.\" @(#)backgammon.6 6.6 (Berkeley) 8/3/91
+.\"
+.TH BACKGAMMON 6 "August 3, 1991"
+.UC 5
+.SH NAME
+backgammon \- the game of backgammon
+.SH SYNOPSIS
+.B backgammon
+[ - ] [ n r w b pr pw pb t\c
+.I term
+s\c
+.I file
+]
+.SH DESCRIPTION
+This program lets you play backgammon against the computer
+or against a "friend".
+All commands only are one letter,
+so you don't need to type a carriage return,
+except at the end of a move.
+The program is mostly self documenting,
+so that a question mark (?) will usually get some help.
+If you answer `y' when the program asks if you want the rules,
+you will get text explaining the rules of the game,
+some hints on strategy,
+instruction on how to use the program,
+and a tutorial consisting of a practice game against the computer.
+A description of how to use the program can be
+obtained by answering `y' when it asks if you want instructions.
+.PP
+The possible arguments for backgammon
+(most are unnecessary but some are very convenient)
+consist of:
+.ne 11
+.PP
+.na
+.TP 8
+.B n
+don't ask for rules or instructions
+.TP 8
+.B r
+player is red (implies n)
+.TP 8
+.B w
+player is white (implies n)
+.TP 8
+.B b
+two players, red and white (implies n)
+.TP 8
+.B pr
+print the board before red's turn
+.TP 8
+.B pw
+print the board before white's turn
+.TP 8
+.B pb
+print the board before both player's turn
+.TP 8
+.B t\fIterm
+terminal is type
+.IR term ,
+uses /etc/termcap
+.TP 8
+.B s\fIfile
+recover previously saved game from
+.IR file .
+(This can also be done by executing the saved file,
+i.e., typing its name in as a command)
+.ad
+.PP
+Arguments may be optionally preceded by a `-'.
+Several arguments may be concatenated together,
+but not after `s' or `t' arguments,
+since they can be followed by an arbitrary string.
+Any unrecognized arguments are ignored.
+An argument of a lone `-' gets a description of possible arguments.
+.PP
+If
+.IR term
+has capabilities for direct cursor movement (see
+.IR termcap (5))
+.IR backgammon
+``fixes'' the board after each move,
+so the board does not need to be reprinted,
+unless the screen suffers some horrendous malady.
+Also, any `p' option will be ignored.
+(The `t' option is not necessary unless the terminal type does not match
+the entry in the /etc/termcap data base.)
+.SH QUICK\ REFERENCE
+When the program prompts by typing only your color,
+type a space or carriage return to roll, or
+.ne 5
+.PP
+.na
+.TP 8
+.B d
+to double
+.TP 8
+.B p
+to print the board
+.TP 8
+.B q
+to quit
+.TP 8
+.B s
+to save the game for later
+.PP
+.i0
+.ad
+When the program prompts with 'Move:', type
+.ne 4
+.PP
+.na
+.TP 8
+.B p
+to print the board
+.TP 8
+.B q
+to quit
+.TP 8
+.B s
+to save the game
+.ad
+.i0
+.PP
+or a
+.IR move ,
+which is a sequence of
+.ne 4
+.PP
+.na
+.TP 8
+.B s-f
+move from
+.BR s
+to
+.BR f
+.TP 8
+.B s/r
+move one man on
+.BR s
+the roll
+.BR r
+.ad
+.PP
+separated by commas or spaces and ending with a newline.
+Available abbreviations are
+.ne 4
+.PP
+.na
+.TP 10
+.B s-f1-f2
+means
+.BR s-f1,f1-f2
+.TP 10
+.B s/r1r2
+means
+.BR s/r1,s/r2
+.ad
+.PP
+Use `b' for bar and `h' for home,
+or 0 or 25 as appropriate.
+.SH AUTHOR
+Alan Char
+.SH FILES
+.TP 25
+/usr/games/teachgammon
+\- rules and tutorial
+.br
+.TP 25
+/etc/termcap
+\- terminal capabilities
+.SH BUGS
+.PP
+The program's strategy needs much work.
diff --git a/backgammon/backgammon/extra.c b/backgammon/backgammon/extra.c
new file mode 100644
index 00000000..36ca1dd5
--- /dev/null
+++ b/backgammon/backgammon/extra.c
@@ -0,0 +1,253 @@
+/*
+ * 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
+static char sccsid[] = "@(#)extra.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+FILE *trace;
+#endif
+
+/*
+ * dble()
+ * Have the current player double and ask opponent to accept.
+ */
+
+dble () {
+ register int resp; /* response to y/n */
+
+ for (;;) {
+ writel (" doubles."); /* indicate double */
+
+ if (cturn == -pnum) { /* see if computer accepts */
+ if (dblgood()) { /* guess not */
+ writel (" Declined.\n");
+ nexturn();
+ cturn *= -2; /* indicate loss */
+ return;
+ } else { /* computer accepts */
+ writel (" Accepted.\n");
+ gvalue *= 2; /* double game value */
+ dlast = cturn;
+ if (tflag)
+ gwrite();
+ return;
+ }
+ }
+
+ /* ask if player accepts */
+ writel (" Does ");
+ writel (cturn == 1? color[2]: color[3]);
+ writel (" accept?");
+
+ /* get response from yorn,
+ * a "2" means he said "p"
+ * for print board. */
+ if ((resp = yorn ('R')) == 2) {
+ writel (" Reprint.\n");
+ buflush();
+ wrboard();
+ writel (*Colorptr);
+ continue;
+ }
+
+ /* check response */
+ if (resp) {
+ /* accepted */
+ gvalue *= 2;
+ dlast = cturn;
+ if (tflag)
+ gwrite();
+ return;
+ }
+
+ nexturn (); /* declined */
+ cturn *= -2;
+ return;
+ }
+}
+
+/*
+ * dblgood ()
+ * Returns 1 if the computer would double in this position. This
+ * is not an exact science. The computer will decline a double that he
+ * would have made. Accumulated judgments are kept in the variable n,
+ * which is in "pips", i.e., the position of each man summed over all
+ * men, with opponent's totals negative. Thus, n should have a positive
+ * value of 7 for each move ahead, or a negative value of 7 for each one
+ * behind.
+ */
+
+dblgood () {
+ register int n; /* accumulated judgment */
+ register int OFFC = *offptr; /* no. of computer's men off */
+ register int OFFO = *offopp; /* no. of player's men off */
+
+#ifdef DEBUG
+ register int i;
+ if (trace == NULL)
+ trace = fopen ("bgtrace","w");
+#endif
+
+ /* get real pip value */
+ n = eval()*cturn;
+#ifdef DEBUG
+ fputs ("\nDoubles:\nBoard: ",trace);
+ for (i = 0; i < 26; i++)
+ fprintf (trace," %d",board[i]);
+ fprintf (trace,"\n\tpip = %d, ",n);
+#endif
+
+ /* below adjusts pip value
+ * according to position
+ * judgments */
+
+ /* check men moving off
+ * board */
+ if (OFFC > -15 || OFFO > -15) {
+ if (OFFC < 0 && OFFO < 0) {
+ OFFC += 15;
+ OFFO += 15;
+ n +=((OFFC-OFFO)*7)/2;
+ } else if (OFFC < 0) {
+ OFFC += 15;
+ n -= OFFO*7/2;
+ } else if (OFFO < 0) {
+ OFFO += 15;
+ n += OFFC*7/2;
+ }
+ if (OFFC < 8 && OFFO > 8)
+ n -= 7;
+ if (OFFC < 10 && OFFO > 10)
+ n -= 7;
+ if (OFFC < 12 && OFFO > 12)
+ n -= 7;
+ if (OFFO < 8 && OFFC > 8)
+ n += 7;
+ if (OFFO < 10 && OFFC > 10)
+ n += 7;
+ if (OFFO < 12 && OFFC > 12)
+ n += 7;
+ n += ((OFFC-OFFO)*7)/2;
+ }
+
+#ifdef DEBUG
+ fprintf (trace,"off = %d, ",n);
+#endif
+
+ /* see if men are trapped */
+ n -= freemen(bar);
+ n += freemen(home);
+ n += trapped(home,-cturn);
+ n -= trapped(bar,cturn);
+
+#ifdef DEBUG
+ fprintf (trace,"free = %d\n",n);
+ fprintf (trace,"\tOFFC = %d, OFFO = %d\n",OFFC,OFFO);
+ fflush (trace);
+#endif
+
+ /* double if 2-3 moves ahead */
+ if (n > 10+rnum(7))
+ return(1);
+ return (0);
+}
+
+freemen (b)
+int b;
+
+{
+ register int i, inc, lim;
+
+ odds(0,0,0);
+ if (board[b] == 0)
+ return (0);
+ inc = (b == 0? 1: -1);
+ lim = (b == 0? 7: 18);
+ for (i = b+inc; i != lim; i += inc)
+ if (board[i]*inc < -1)
+ odds(abs(b-i),0,abs(board[b]));
+ if (abs(board[b]) == 1)
+ return ((36-count())/5);
+ return (count()/5);
+}
+
+trapped (n,inc)
+int n, inc;
+
+{
+ register int i, j, k;
+ int c, l, ct;
+
+ ct = 0;
+ l = n+7*inc;
+ for (i = n+inc; i != l; i += inc) {
+ odds (0,0,0);
+ c = abs(i-l);
+ if (board[i]*inc > 0) {
+ for (j = c; j < 13; j++)
+ if (board[i+inc*j]*inc < -1) {
+ if (j < 7)
+ odds (j,0,1);
+ for (k = 1; k < 7 && k < j; k++)
+ if (j-k < 7)
+ odds (k,j-k,1);
+ }
+ ct += abs(board[i])*(36-count());
+ }
+ }
+ return (ct/5);
+}
+
+eval () {
+
+ register int i, j;
+
+ for (j = i = 0; i < 26; i++)
+ j += (board[i] >= 0 ? i*board[i] : (25-i)*board[i]);
+
+ if (off[1] >= 0)
+ j += 25*off[1];
+ else
+ j += 25*(off[1]+15);
+
+ if (off[0] >= 0)
+ j -= 25*off[0];
+ else
+ j -= 25*(off[0]+15);
+ return (j);
+}
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 ();
+}
diff --git a/backgammon/backgammon/move.c b/backgammon/backgammon/move.c
new file mode 100644
index 00000000..17a5dfde
--- /dev/null
+++ b/backgammon/backgammon/move.c
@@ -0,0 +1,551 @@
+/*
+ * 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
+static char sccsid[] = "@(#)move.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+FILE *trace;
+static char tests[20];
+#endif
+
+struct BOARD { /* structure of game position */
+ int b_board[26]; /* board position */
+ int b_in[2]; /* men in */
+ int b_off[2]; /* men off */
+ int b_st[4], b_fn[4]; /* moves */
+
+ struct BOARD *b_next; /* forward queue pointer */
+};
+
+struct BOARD *freeq = 0;
+struct BOARD *checkq = 0;
+struct BOARD *bsave();
+struct BOARD *nextfree();
+
+ /* these variables are values for the
+ * candidate move */
+static int ch; /* chance of being hit */
+static int op; /* computer's open men */
+static int pt; /* comp's protected points */
+static int em; /* farthest man back */
+static int frc; /* chance to free comp's men */
+static int frp; /* chance to free pl's men */
+
+ /* these values are the values for the
+ * move chosen (so far) */
+static int chance; /* chance of being hit */
+static int openmen; /* computer's open men */
+static int points; /* comp's protected points */
+static int endman; /* farthest man back */
+static int barmen; /* men on bar */
+static int menin; /* men in inner table */
+static int menoff; /* men off board */
+static int oldfrc; /* chance to free comp's men */
+static int oldfrp; /* chance to free pl's men */
+
+static int cp[5]; /* candidate start position */
+static int cg[5]; /* candidate finish position */
+
+static int race; /* game reduced to a race */
+
+move (okay)
+int okay; /* zero if first move */
+{
+ register int i; /* index */
+ register int l; /* last man */
+
+ if (okay) {
+ /* see if comp should double */
+ if (gvalue < 64 && dlast != cturn && dblgood()) {
+ writel (*Colorptr);
+ dble(); /* double */
+ /* return if declined */
+ if (cturn != 1 && cturn != -1)
+ return;
+ }
+ roll();
+ }
+
+ race = 0;
+ for (i = 0; i < 26; i++) {
+ if (board[i] < 0)
+ l = i;
+ }
+ for (i = 0; i < l; i++) {
+ if (board[i] > 0)
+ break;
+ }
+ if (i == l)
+ race = 1;
+
+ /* print roll */
+ if (tflag)
+ curmove (cturn == -1? 18: 19,0);
+ writel (*Colorptr);
+ writel (" rolls ");
+ writec (D0+'0');
+ writec (' ');
+ writec (D1+'0');
+ /* make tty interruptable
+ * while thinking */
+ if (tflag)
+ cline();
+ fixtty (noech);
+
+ /* find out how many moves */
+ mvlim = movallow();
+ if (mvlim == 0) {
+ writel (" but cannot use it.\n");
+ nexturn();
+ fixtty (raw);
+ return;
+ }
+
+ /* initialize */
+ for (i = 0; i < 4; i++)
+ cp[i] = cg[i] = 0;
+
+ /* strategize */
+ trymove (0,0);
+ pickmove();
+
+ /* print move */
+ writel (" and moves ");
+ for (i = 0; i < mvlim; i++) {
+ if (i > 0)
+ writec (',');
+ wrint (p[i] = cp[i]);
+ writec ('-');
+ wrint (g[i] = cg[i]);
+ makmove (i);
+ }
+ writec ('.');
+
+ /* print blots hit */
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ for (i = 0; i < mvlim; i++)
+ if (h[i])
+ wrhit(g[i]);
+ /* get ready for next move */
+ nexturn();
+ if (!okay) {
+ buflush();
+ sleep (3);
+ }
+ fixtty (raw); /* no more tty interrupt */
+}
+
+trymove (mvnum,swapped)
+register int mvnum; /* number of move (rel zero) */
+int swapped; /* see if swapped also tested */
+
+{
+ register int pos; /* position on board */
+ register int rval; /* value of roll */
+
+ /* if recursed through all dice
+ * values, compare move */
+ if (mvnum == mvlim) {
+ binsert (bsave());
+ return;
+ }
+
+ /* make sure dice in always
+ * same order */
+ if (d0 == swapped)
+ swap;
+ /* choose value for this move */
+ rval = dice[mvnum != 0];
+
+ /* find all legitimate moves */
+ for (pos = bar; pos != home; pos += cturn) {
+ /* fix order of dice */
+ if (d0 == swapped)
+ swap;
+ /* break if stuck on bar */
+ if (board[bar] != 0 && pos != bar)
+ break;
+ /* on to next if not occupied */
+ if (board[pos]*cturn <= 0)
+ continue;
+ /* set up arrays for move */
+ p[mvnum] = pos;
+ g[mvnum] = pos+rval*cturn;
+ if (g[mvnum]*cturn >= home) {
+ if (*offptr < 0)
+ break;
+ g[mvnum] = home;
+ }
+ /* try to move */
+ if (makmove (mvnum))
+ continue;
+ else
+ trymove (mvnum+1,2);
+ /* undo move to try another */
+ backone (mvnum);
+ }
+
+ /* swap dice and try again */
+ if ((!swapped) && D0 != D1)
+ trymove (0,1);
+}
+
+struct BOARD *
+bsave () {
+ register int i; /* index */
+ struct BOARD *now; /* current position */
+
+ now = nextfree (); /* get free BOARD */
+
+ /* store position */
+ for (i = 0; i < 26; i++)
+ now->b_board[i] = board[i];
+ now->b_in[0] = in[0];
+ now->b_in[1] = in[1];
+ now->b_off[0] = off[0];
+ now->b_off[1] = off[1];
+ for (i = 0; i < mvlim; i++) {
+ now->b_st[i] = p[i];
+ now->b_fn[i] = g[i];
+ }
+ return (now);
+}
+
+binsert (new)
+struct BOARD *new; /* item to insert */
+{
+ register struct BOARD *p = checkq; /* queue pointer */
+ register int result; /* comparison result */
+
+ if (p == 0) { /* check if queue empty */
+ checkq = p = new;
+ p->b_next = 0;
+ return;
+ }
+
+ result = bcomp (new,p); /* compare to first element */
+ if (result < 0) { /* insert in front */
+ new->b_next = p;
+ checkq = new;
+ return;
+ }
+ if (result == 0) { /* duplicate entry */
+ mvcheck (p,new);
+ makefree (new);
+ return;
+ }
+
+ while (p->b_next != 0) { /* traverse queue */
+ result = bcomp (new,p->b_next);
+ if (result < 0) { /* found place */
+ new->b_next = p->b_next;
+ p->b_next = new;
+ return;
+ }
+ if (result == 0) { /* duplicate entry */
+ mvcheck (p->b_next,new);
+ makefree (new);
+ return;
+ }
+ p = p->b_next;
+ }
+ /* place at end of queue */
+ p->b_next = new;
+ new->b_next = 0;
+}
+
+bcomp (a,b)
+struct BOARD *a;
+struct BOARD *b;
+{
+ register int *aloc = a->b_board; /* pointer to board a */
+ register int *bloc = b->b_board; /* pointer to board b */
+ register int i; /* index */
+ int result; /* comparison result */
+
+ for (i = 0; i < 26; i++) { /* compare boards */
+ result = cturn*(aloc[i]-bloc[i]);
+ if (result)
+ return (result); /* found inequality */
+ }
+ return (0); /* same position */
+}
+
+mvcheck (incumbent,candidate)
+register struct BOARD *incumbent;
+register struct BOARD *candidate;
+{
+ register int i;
+ register int result;
+
+ for (i = 0; i < mvlim; i++) {
+ result = cturn*(candidate->b_st[i]-incumbent->b_st[i]);
+ if (result > 0)
+ return;
+ if (result < 0)
+ break;
+ }
+ if (i == mvlim)
+ return;
+ for (i = 0; i < mvlim; i++) {
+ incumbent->b_st[i] = candidate->b_st[i];
+ incumbent->b_fn[i] = candidate->b_fn[i];
+ }
+}
+
+makefree (dead)
+struct BOARD *dead; /* dead position */
+{
+ dead->b_next = freeq; /* add to freeq */
+ freeq = dead;
+}
+
+struct BOARD *
+nextfree () {
+ struct BOARD *new;
+
+ if (freeq == 0) {
+ new = (struct BOARD *)calloc (1,sizeof (struct BOARD));
+ if (new == 0) {
+ writel ("\nOut of memory\n");
+ getout();
+ }
+ new->b_next = 0;
+ return (new);
+ }
+
+ new = freeq;
+ freeq = freeq->b_next;
+}
+
+pickmove () {
+ /* current game position */
+ register struct BOARD *now = bsave();
+ register struct BOARD *next; /* next move */
+
+#ifdef DEBUG
+ if (trace == NULL)
+ trace = fopen ("bgtrace","w");
+ fprintf (trace,"\nRoll: %d %d%s\n",D0,D1,race? " (race)": "");
+ fflush (trace);
+#endif
+ do { /* compare moves */
+ boardcopy (checkq);
+ next = checkq->b_next;
+ makefree (checkq);
+ checkq = next;
+ movcmp();
+ } while (checkq != 0);
+
+ boardcopy (now);
+}
+
+boardcopy (s)
+register struct BOARD *s; /* game situation */
+{
+ register int i; /* index */
+
+ for (i = 0; i < 26; i++)
+ board[i] = s->b_board[i];
+ for (i = 0; i < 2; i++) {
+ in[i] = s->b_in[i];
+ off[i] = s->b_off[i];
+ }
+ for (i = 0; i < mvlim; i++) {
+ p[i] = s->b_st[i];
+ g[i] = s->b_fn[i];
+ }
+}
+
+movcmp () {
+ register int i;
+ register int c;
+
+#ifdef DEBUG
+ if (trace == NULL)
+ trace = fopen ("bgtrace","w");
+#endif
+
+ odds (0,0,0);
+ if (!race) {
+ ch = op = pt = 0;
+ for (i = 1; i < 25; i++) {
+ if (board[i] == cturn)
+ ch = canhit (i,1);
+ op += abs (bar-i);
+ }
+ for (i = bar+cturn; i != home; i += cturn)
+ if (board[i]*cturn > 1)
+ pt += abs(bar-i);
+ frc = freemen (bar)+trapped (bar,cturn);
+ frp = freemen (home)+trapped (home,-cturn);
+ }
+ for (em = bar; em != home; em += cturn)
+ if (board[em]*cturn > 0)
+ break;
+ em = abs(home-em);
+#ifdef DEBUG
+ fputs ("Board: ",trace);
+ for (i = 0; i < 26; i++)
+ fprintf (trace, " %d",board[i]);
+ if (race)
+ fprintf (trace,"\n\tem = %d\n",em);
+ else
+ fprintf (trace,
+ "\n\tch = %d, pt = %d, em = %d, frc = %d, frp = %d\n",
+ ch,pt,em,frc,frp);
+ fputs ("\tMove: ",trace);
+ for (i = 0; i < mvlim; i++)
+ fprintf (trace," %d-%d",p[i],g[i]);
+ fputs ("\n",trace);
+ fflush (trace);
+ strcpy (tests,"");
+#endif
+ if ((cp[0] == 0 && cg[0] == 0) || movegood()) {
+#ifdef DEBUG
+ fprintf (trace,"\t[%s] ... wins.\n",tests);
+ fflush (trace);
+#endif
+ for (i = 0; i < mvlim; i++) {
+ cp[i] = p[i];
+ cg[i] = g[i];
+ }
+ if (!race) {
+ chance = ch;
+ openmen = op;
+ points = pt;
+ endman = em;
+ barmen = abs(board[home]);
+ oldfrc = frc;
+ oldfrp = frp;
+ }
+ menin = *inptr;
+ menoff = *offptr;
+ }
+#ifdef DEBUG
+ else {
+ fprintf (trace,"\t[%s] ... loses.\n",tests);
+ fflush (trace);
+ }
+#endif
+}
+
+movegood () {
+ register int n;
+
+ if (*offptr == 15)
+ return (1);
+ if (menoff == 15)
+ return (0);
+ if (race) {
+#ifdef DEBUG
+ strcat (tests,"o");
+#endif
+ if (*offptr-menoff)
+ return (*offptr > menoff);
+#ifdef DEBUG
+ strcat (tests,"e");
+#endif
+ if (endman-em)
+ return (endman > em);
+#ifdef DEBUG
+ strcat (tests,"i");
+#endif
+ if (menin == 15)
+ return (0);
+ if (*inptr == 15)
+ return (1);
+#ifdef DEBUG
+ strcat (tests,"i");
+#endif
+ if (*inptr-menin)
+ return (*inptr > menin);
+ return (rnum(2));
+ } else {
+ n = barmen-abs(board[home]);
+#ifdef DEBUG
+ strcat (tests,"c");
+#endif
+ if (abs(chance-ch)+25*n > rnum(150))
+ return (n? (n < 0): (ch < chance));
+#ifdef DEBUG
+ strcat (tests,"o");
+#endif
+ if (*offptr-menoff)
+ return (*offptr > menoff);
+#ifdef DEBUG
+ strcat (tests,"o");
+#endif
+ if (abs(openmen-op) > 7+rnum(12))
+ return (openmen > op);
+#ifdef DEBUG
+ strcat (tests,"b");
+#endif
+ if (n)
+ return (n < 0);
+#ifdef DEBUG
+ strcat (tests,"e");
+#endif
+ if (abs(endman-em) > rnum(2))
+ return (endman > em);
+#ifdef DEBUG
+ strcat (tests,"f");
+#endif
+ if (abs(frc-oldfrc) > rnum(2))
+ return (frc < oldfrc);
+#ifdef DEBUG
+ strcat (tests,"p");
+#endif
+ if (abs(n = pt-points) > rnum(4))
+ return (n > 0);
+#ifdef DEBUG
+ strcat (tests,"i");
+#endif
+ if (*inptr-menin)
+ return (*inptr > menin);
+#ifdef DEBUG
+ strcat (tests,"f");
+#endif
+ if (abs(frp-oldfrp) > rnum(2))
+ return (frp > oldfrp);
+ return (rnum(2));
+ }
+}
diff --git a/backgammon/backgammon/text.c b/backgammon/backgammon/text.c
new file mode 100644
index 00000000..1a390867
--- /dev/null
+++ b/backgammon/backgammon/text.c
@@ -0,0 +1,132 @@
+/*
+ * 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
+static char sccsid[] = "@(#)text.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *instr[] = {
+ " If you did not notice by now, this program reacts to things as",
+ "soon as you type them, without waiting for a newline. This means that",
+ "the special characters RUBOUT, ESC, and CONTROL-D, will not perform",
+ "their special functions during most of this program. The program",
+ "should usually stop when a RUBOUT is typed, but occasionally it will",
+ "ignore RUBOUTs until it is waiting for input.\n",
+ " These instructions are presented in small chunks designed not to",
+ "roll off the top of your screen. When the characters '-->' are print-",
+ "ed, no more data will be printed until a space or newline is typed.",
+ "In this way, you can finish one section before continuing to another.",
+ "Like this:",
+ "",
+ " The two sides are colored 'red' and 'white.' The computer may play",
+ "one side, or if there are two players, the computer can merely act as",
+ "a gamekeeper, letting the players make the moves. Once you tell the",
+ "computer what color(s) you want to play, the decision remains in ef-",
+ "fect until you quit the program, even if you play more than one game,",
+ "since the program keeps a running score.\n",
+ " The program will prompt for a move in one of two ways. If the",
+ "player has the opportunity to double, then merely his color will be",
+ "typed out. The player can now do one of several things. He can dou-",
+ "ble by typing a 'd', he can roll by typing a space (' ') or newline,",
+ "or if he is not sure, he can reprint the board by typing a 'r'.\n",
+ " If the player cannot double, his roll will be thrust in front of",
+ "him, followed by the request 'Move:', asking for a move but not giving",
+ "him the chance to double. He can still ask for the board by typing",
+ "'r'. In either of these two states, the player can quit by typing 'q'",
+ "or save the game by typing 's'. In either case, the player will be",
+ "asked to verify, in case there was some error. The program then ends",
+ "immediately, after first saving the file if so requested.",
+ "",
+ " A player can move one of his men using two forms of input. The",
+ "first form is <s>-<f>, where <s> is the starting position, and <f> is",
+ "the finishing position of the player's man. For example, if white",
+ "wanted to move a piece from position 13 to position 8, his move could",
+ "be entered as 13-8. The second form is <s>/<r> where <s> is the",
+ "starting position, an <r> is the roll actually made. Hence, white",
+ "could have entered as 13/5 instead of 13-8.\n",
+ " A player must move each roll of the dice separately. For example,",
+ "if a player rolled 4 3, and wanted to move from 13 to 6, he could",
+ "enter it as 13/4,9/3 or 13/3,10/4 or 13-10,10-6 or 13-9,9-6, but not",
+ "13-6. The last two entries can be shortened to 13-10-6 and 13-9-6.",
+ "If you want to move more than one piece from the same position, such",
+ "as 13-10,13-9, you can abbreviate this using the <s>/<r> format as by",
+ "entering more than one <r>, or 13/34. A player can use both forms for",
+ "the same roll, e.g. 13/3,13-9, and separates individual moves by ei-",
+ "ther a comma or a space. The letter 'b' represents the bar, and the",
+ "letter 'h' represents a player's home. You could also enter the",
+ "number that would be in the position of the bar, 25 or 0 as appropri-",
+ "ate. Use a newline at the end of your moves for a turn.",
+ "",
+ " As you type in your move, if a character does not make sense under",
+ "the above constrictions, a bell will sound instead of the character,",
+ "and it will be ignored. You may kill lines and erase characters as",
+ "you would normally, but don't be surprised if they look different than",
+ "usual. Also, if you have entered one or more of your rolls, and you",
+ "wish to see what the move looks like so far, type a 'r' to see what it",
+ "looks like. This cannot be done in the middle of a move (e.g., after",
+ "a '-' or '/'). After the printing board, the program will go back to",
+ "inputting your move and you can backspace or kill just as if you had",
+ "just typed in your input.\n",
+ " Now you should be ready to begin the game. Good luck!",
+ "",
+ 0};
+
+
+text (t)
+char **t;
+
+{
+ register int i;
+ register char *s, *a;
+
+ fixtty (noech);
+ while (*t != 0) {
+ s = a = *t;
+ for (i = 0; *a != '\0'; i--)
+ a++;
+ if (i) {
+ writel (s);
+ writec ('\n');
+ } else {
+ writel ("-->");
+ fixtty (raw);
+ while ((i = readc()) != ' ' && i != '\n');
+ fixtty (noech);
+ clear();
+ }
+ t++;
+ }
+ fixtty (raw);
+}
diff --git a/backgammon/backgammon/version.c b/backgammon/backgammon/version.c
new file mode 100644
index 00000000..a6e9db27
--- /dev/null
+++ b/backgammon/backgammon/version.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 1980, 1987 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 sccsid[] = "@(#)version.c 1.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+char *message[] = {
+ "Last updated on Saturday, January 11, 1986.",
+ 0
+};
diff --git a/backgammon/common_source/allow.c b/backgammon/common_source/allow.c
new file mode 100644
index 00000000..2a7c9e0d
--- /dev/null
+++ b/backgammon/common_source/allow.c
@@ -0,0 +1,109 @@
+/*
+ * 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
+static char sccsid[] = "@(#)allow.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+movallow () {
+
+ register int i, m, iold;
+ int r;
+
+ if (d0)
+ swap;
+ m = (D0 == D1? 4: 2);
+ for (i = 0; i < 4; i++)
+ p[i] = bar;
+ i = iold = 0;
+ while (i < m) {
+ if (*offptr == 15)
+ break;
+ h[i] = 0;
+ if (board[bar]) {
+ if (i == 1 || m == 4)
+ g[i] = bar+cturn*D1;
+ else
+ g[i] = bar+cturn*D0;
+ if (r = makmove(i)) {
+ if (d0 || m == 4)
+ break;
+ swap;
+ movback (i);
+ if (i > iold)
+ iold = i;
+ for (i = 0; i < 4; i++)
+ p[i] = bar;
+ i = 0;
+ } else
+ i++;
+ continue;
+ }
+ if ((p[i] += cturn) == home) {
+ if (i > iold)
+ iold = i;
+ if (m == 2 && i) {
+ movback(i);
+ p[i--] = bar;
+ if (p[i] != bar)
+ continue;
+ else
+ break;
+ }
+ if (d0 || m == 4)
+ break;
+ swap;
+ movback (i);
+ for (i = 0; i < 4; i++)
+ p[i] = bar;
+ i = 0;
+ continue;
+ }
+ if (i == 1 || m == 4)
+ g[i] = p[i]+cturn*D1;
+ else
+ g[i] = p[i]+cturn*D0;
+ if (g[i]*cturn > home) {
+ if (*offptr >= 0)
+ g[i] = home;
+ else
+ continue;
+ }
+ if (board[p[i]]*cturn > 0 && (r = makmove(i)) == 0)
+ i++;
+ }
+ movback (i);
+ return (iold > i? iold: i);
+}
diff --git a/backgammon/common_source/back.h b/backgammon/common_source/back.h
new file mode 100644
index 00000000..5bab6e55
--- /dev/null
+++ b/backgammon/common_source/back.h
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ *
+ * @(#)back.h 5.4 (Berkeley) 6/1/90
+ */
+
+#include <sgtty.h>
+
+#define rnum(r) (random()%r)
+#define D0 dice[0]
+#define D1 dice[1]
+#define swap {D0 ^= D1; D1 ^= D0; D0 ^= D1; d0 = 1-d0;}
+
+/*
+ *
+ * Some numerical conventions:
+ *
+ * Arrays have white's value in [0], red in [1].
+ * Numeric values which are one color or the other use
+ * -1 for white, 1 for red.
+ * Hence, white will be negative values, red positive one.
+ * This makes a lot of sense since white is going in decending
+ * order around the board, and red is ascending.
+ *
+ */
+
+char EXEC[]; /* object for main program */
+char TEACH[]; /* object for tutorial program */
+
+int pnum; /* color of player:
+ -1 = white
+ 1 = red
+ 0 = both
+ 2 = not yet init'ed */
+char args[100]; /* args passed to teachgammon and back */
+int acnt; /* length of args */
+int aflag; /* flag to ask for rules or instructions */
+int bflag; /* flag for automatic board printing */
+int cflag; /* case conversion flag */
+int hflag; /* flag for cleaning screen */
+int mflag; /* backgammon flag */
+int raflag; /* 'roll again' flag for recovered game */
+int rflag; /* recovered game flag */
+int tflag; /* cursor addressing flag */
+int rfl; /* saved value of rflag */
+int iroll; /* special flag for inputting rolls */
+int board[26]; /* board: negative values are white,
+ positive are red */
+int dice[2]; /* value of dice */
+int mvlim; /* 'move limit': max. number of moves */
+int mvl; /* working copy of mvlim */
+int p[5]; /* starting position of moves */
+int g[5]; /* ending position of moves (goals) */
+int h[4]; /* flag for each move if a man was hit */
+int cturn; /* whose turn it currently is:
+ -1 = white
+ 1 = red
+ 0 = just quitted
+ -2 = white just lost
+ 2 = red just lost */
+int d0; /* flag if dice have been reversed from
+ original position */
+int table[6][6]; /* odds table for possible rolls */
+int rscore; /* red's score */
+int wscore; /* white's score */
+int gvalue; /* value of game (64 max.) */
+int dlast; /* who doubled last (0 = neither) */
+int bar; /* position of bar for current player */
+int home; /* position of home for current player */
+int off[2]; /* number of men off board */
+int *offptr; /* pointer to off for current player */
+int *offopp; /* pointer to off for opponent */
+int in[2]; /* number of men in inner table */
+int *inptr; /* pointer to in for current player */
+int *inopp; /* pointer to in for opponent */
+
+int ncin; /* number of characters in cin */
+char cin[100]; /* input line of current move
+ (used for reconstructing input after
+ a backspace) */
+
+char *color[];
+ /* colors as strings */
+char **colorptr; /* color of current player */
+char **Colorptr; /* color of current player, capitalized */
+int colen; /* length of color of current player */
+
+struct sgttyb tty; /* tty information buffer */
+int old; /* original tty status */
+int noech; /* original tty status without echo */
+int raw; /* raw tty status, no echo */
+
+int curr; /* row position of cursor */
+int curc; /* column position of cursor */
+int begscr; /* 'beginning' of screen
+ (not including board) */
+
+int getout(); /* function to exit backgammon cleanly */
diff --git a/backgammon/common_source/backgammon.c b/backgammon/common_source/backgammon.c
new file mode 100644
index 00000000..036301f4
--- /dev/null
+++ b/backgammon/common_source/backgammon.c
@@ -0,0 +1,751 @@
+/*-
+ * Copyright (c) 1991 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 sccsid[] = "@(#)backgammon.c 5.1 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+/*
+** The game of Backgammon
+*/
+
+#include <stdio.h>
+
+#define WHITE 0
+#define BROWN 1
+#define NIL (-1)
+#define MAXGMOV 10
+#define MAXIMOVES 1000
+#define RULES "/usr/games/lib/backrules"
+
+char level; /*'b'=beginner, 'i'=intermediate, 'e'=expert*/
+
+int die1;
+int die2;
+int i;
+int j;
+int l;
+int m;
+int pflg = 1;
+int nobroll = 0;
+int count;
+int imoves;
+int goodmoves[MAXGMOV];
+int probmoves[MAXGMOV];
+
+int brown[] = { /* brown position table */
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+int white[] = { /* white position table */
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+int probability[] = {
+ 0, 11, 12, 13, 14, 15, 16,
+ 06, 05, 04, 03, 02, 01
+};
+
+struct {
+ int pos[4];
+ int mov[4];
+} moves[MAXIMOVES];
+
+main()
+{
+ int go[5], tvec[2];
+ int k, n, pid, ret, rpid, t;
+ char s[100];
+
+ srand(time(0));
+ go[5] = NIL;
+ fprintf(stdout, "Instructions? ");
+ gets(s);
+ if(*s == 'y')
+ instructions();
+ putchar('\n');
+ fprintf(stdout, "Opponent's level: b - beginner,\n");
+ fprintf(stdout, "i - intermediate, e - expert? ");
+ level='e';
+ gets(s);
+ if(*s == 'b')
+ level = 'b';
+ else if(*s == 'i')
+ level = 'i';
+ putchar('\n');
+ fprintf(stdout, "You will play brown.\n\n");
+ fprintf(stdout, "Would you like to roll your own dice? ");
+ gets(s);
+ putchar('\n');
+ if(*s == 'y')
+ nobroll = 1;
+ fprintf(stdout, "Would you like to go first? ");
+ gets(s);
+ putchar('\n');
+ if(*s == 'y')
+ goto nowhmove;
+whitesmv:
+ roll(WHITE);
+ fprintf(stdout, "white rolls %d, %d\n", die1, die2);
+ fprintf(stdout, "white's move is:");
+ if(nextmove(white, brown) == NIL)
+ goto nowhmove;
+ if(piececount(white, 0, 24) == 0){
+ fprintf(stdout, "White wins");
+ if(piececount(brown, 0, 6) != 0)
+ fprintf(stdout, " with a Backgammon!\n");
+ else if (piececount(brown, 0, 24) == 24)
+ fprintf(stdout, " with a Gammon.\n");
+ else
+ fprintf(stdout, ".\n");
+ exit(0);
+ }
+nowhmove:
+ if(pflg)
+ prtbrd();
+ roll(BROWN);
+retry:
+ fprintf(stdout, "\nYour roll is %d %d\n", die1, die2);
+ fprintf(stdout, "Move? ");
+ gets(s);
+ switch(*s) {
+ case '\0': /* empty line */
+ fprintf(stdout, "Brown's move skipped.\n");
+ goto whitesmv;
+
+ case 'b': /* how many beared off? */
+ fprintf(stdout, "Brown: %d\n", piececount(brown, 0, 24) - 15);
+ fprintf(stdout, "White: %d\n", piececount(white, 0, 24) - 15);
+ goto retry;
+
+ case 'p': /* print board */
+ prtbrd();
+ goto retry;
+
+ case 's': /* stop auto printing of board */
+ pflg = 0;
+ goto retry;
+
+ case 'r': /* resume auto printing */
+ pflg = 1;
+ goto retry;
+
+ case 'm': /* print possible moves */
+ pmoves();
+ goto retry;
+
+ case 'q': /* i give up */
+ exit(0);
+
+ case '!': /* escape to Shell */
+ if(s[1] != '\0')
+ system(s+1);
+ else if((pid = fork()) == 0) {
+ execl("/bin/sh", "sh", "-", 0);
+ fprintf(stderr, "back: cannot exec /bin/sh!\n");
+ exit(2);
+ }
+ while((rpid = wait(&ret)) != pid && rpid != -1)
+ ;
+ goto retry;
+
+ case '?': /* well, what can i do? */
+ fprintf(stdout, "<newline> skip this move\n");
+ fprintf(stdout, "b number beared off\n");
+ fprintf(stdout, "p print board\n");
+ fprintf(stdout, "q quit\n");
+ fprintf(stdout, "r resume auto print of board\n");
+ fprintf(stdout, "s stop auto print of board\n");
+ fprintf(stdout, "! escape to Shell\n");
+ goto retry;
+ }
+ n = sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]);
+ if((die1 != die2 && n > 2) || n > 4){
+ fprintf(stdout, "Too many moves.\n");
+ goto retry;
+ }
+ go[n] = NIL;
+ if(*s=='-'){
+ go[0]= -go[0];
+ t=die1;
+ die1=die2;
+ die2=t;
+ }
+ for(k = 0; k < n; k++){
+ if(0 <= go[k] && go[k] <= 24)
+ continue;
+ else{
+ fprintf(stdout, "Move %d illegal.\n", go[k]);
+ goto retry;
+ }
+ }
+ if(play(brown, white, go))
+ goto retry;
+ if(piececount(brown, 0, 24) == 0){
+ fprintf(stdout, "Brown wins");
+ if(piececount(white, 0, 6) != 0)
+ fprintf(stdout, " with a Backgammon.\n");
+ else if(piececount(white, 0, 24) == 24)
+ fprintf(stdout, " with a gammon.\n");
+ else
+ fprintf(stdout, ".\n");
+ exit(0);
+ }
+ goto whitesmv;
+}
+
+play(player,playee,pos)
+int *player,*playee,pos[];
+{
+ int k, n, die, ipos;
+
+ for(k=0; k < player[0]; k++){ /*blots on player[0] must be moved first*/
+ if(pos[k] == NIL)
+ break;
+ if(pos[k] != 0){
+ fprintf(stdout, "Stone on bar must be moved first.\n");
+ return(NIL);
+ }
+ }
+ for(k = 0; (ipos=pos[k]) != NIL; k++){
+ die = k?die2:die1;
+ n = 25-ipos-die;
+ if(player[ipos] == 0)
+ goto badmove;
+ if(n > 0 && playee[n] >= 2)
+ goto badmove;
+ if(n <= 0){
+ if(piececount(player,0,18) != 0)
+ goto badmove;
+ if((ipos+die) != 25 && piececount(player,19,24-die)!=0)
+ goto badmove;
+ }
+ player[ipos]--;
+ player[ipos+die]++;
+ }
+ for(k = 0; pos[k] != NIL; k++){
+ die = k?die2:die1;
+ n = 25-pos[k]-die;
+ if(n>0 && playee[n]==1){
+ playee[n]=0;
+ playee[0]++;
+ }
+ }
+ return(0);
+
+badmove:
+ fprintf(stdout, "Move %d illegal.\n", ipos);
+ while(k--){
+ die=k?die2:die1;
+ player[pos[k]]++;
+ player[pos[k]+die]--;
+ }
+ return(NIL);
+}
+nextmove(player,playee)
+int *player,*playee;
+{
+ int k;
+
+ imoves=0;
+ movegen(player,playee);
+ if(die1!=die2){
+ k=die1;
+ die1=die2;
+ die2=k;
+ movegen(player,playee);
+ }
+ if(imoves==0){
+ fprintf(stdout, "no move possible.\n");
+ return(NIL);
+ }
+ k=strategy(player,playee); /*select kth possible move*/
+ prtmov(k);
+ update(player,playee,k);
+ return(0);
+}
+prtmov(k)
+int k;
+{
+ int n;
+
+ if(k == NIL)
+ fprintf(stdout, "No move possible\n");
+ else for(n = 0; n < 4; n++){
+ if(moves[k].pos[n] == NIL)
+ break;
+ fprintf(stdout, " %d, %d",25-moves[k].pos[n],moves[k].mov[n]);
+ }
+ fprintf(stdout, "\n");
+}
+update(player,playee,k)
+int *player,*playee,k;
+{
+ int n,t;
+
+ for(n = 0; n < 4; n++){
+ if(moves[k].pos[n] == NIL)
+ break;
+ player[moves[k].pos[n]]--;
+ player[moves[k].pos[n]+moves[k].mov[n]]++;
+ t=25-moves[k].pos[n]-moves[k].mov[n];
+ if(t>0 && playee[t]==1){
+ playee[0]++;
+ playee[t]--;
+ }
+ }
+}
+piececount(player,startrow,endrow)
+int *player,startrow,endrow;
+{
+ int sum;
+
+ sum=0;
+ while(startrow <= endrow)
+ sum += player[startrow++];
+ return(sum);
+}
+pmoves()
+{
+ int i1, i2;
+
+ fprintf(stdout, "Possible moves are:\n");
+ for(i1 = 0; i1 < imoves; i1++){
+ fprintf(stdout, "\n%d",i1);
+ for (i2 = 0; i2<4; i2++){
+ if(moves[i1].pos[i2] == NIL)
+ break;
+ fprintf(stdout, "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]);
+ }
+ }
+ fprintf(stdout, "\n");
+}
+
+roll(who)
+{
+ register n;
+ char s[10];
+
+ if(who == BROWN && nobroll) {
+ fprintf(stdout, "Roll? ");
+ gets(s);
+ n = sscanf(s, "%d%d", &die1, &die2);
+ if(n != 2 || die1 < 1 || die1 > 6 || die2 < 1 || die2 > 6)
+ fprintf(stdout, "Illegal - I'll do it!\n");
+ else
+ return;
+ }
+ die1 = ((rand()>>8) % 6) + 1;
+ die2 = ((rand()>>8) % 6) + 1;
+}
+
+movegen(mover,movee)
+int *mover,*movee;
+{
+ int k;
+
+ for(i = 0; i <= 24; i++){
+ count = 0;
+ if(mover[i] == 0)
+ continue;
+ if((k=25-i-die1) > 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover, 0, 18) != 0)
+ break;
+ if((i+die1) != 25 && piececount(mover,19,i-1) != 0)
+ break;
+ }
+ mover[i]--;
+ mover[i+die1]++;
+ count = 1;
+ for(j = 0; j <= 24; j++){
+ if(mover[j]==0)
+ continue;
+ if((k=25-j-die2) > 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover,0,18) != 0)
+ break;
+ if((j+die2) != 25 && piececount(mover,19,j-1) != 0)
+ break;
+ }
+ mover[j]--;
+ mover[j+die2]++;
+ count = 2;
+ if(die1 != die2){
+ moverecord(mover);
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ }
+ for(l = 0; l <= 24; l++){
+ if(mover[l] == 0)
+ continue;
+ if((k=25-l-die1) > 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover, 0, 18) != 0)
+ break;
+ if((l+die2) != 25 && piececount(mover,19,l-1) != 0)
+ break;
+ }
+ mover[l]--;
+ mover[l+die1]++;
+ count=3;
+ for(m=0;m<=24;m++){
+ if(mover[m]==0)
+ continue;
+ if((k=25-m-die1) >= 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover,0,18) != 0)
+ break;
+ if((m+die2) != 25 && piececount(mover,19,m-1) != 0)
+ break;
+ }
+ count=4;
+ moverecord(mover);
+ if(mover[0] > 0)
+ break;
+ }
+ if(count == 3)
+ moverecord(mover);
+ else{
+ mover[l]++;
+ mover[l+die1]--;
+ }
+ if(mover[0] > 0)
+ break;
+ }
+ if(count == 2)
+ moverecord(mover);
+ else{
+ mover[j]++;
+ mover[j+die1]--;
+ }
+ if(mover[0] > 0)
+ break;
+ }
+ if(count == 1)
+ moverecord(mover);
+ else{
+ mover[i]++;
+ mover[i+die1]--;
+ }
+ if(mover[0] > 0)
+ break;
+ }
+}
+moverecord(mover)
+int *mover;
+{
+ int t;
+
+ if(imoves < MAXIMOVES) {
+ for(t = 0; t <= 3; t++)
+ moves[imoves].pos[t] = NIL;
+ switch(count) {
+ case 4:
+ moves[imoves].pos[3]=m;
+ moves[imoves].mov[3]=die1;
+
+ case 3:
+ moves[imoves].pos[2]=l;
+ moves[imoves].mov[2]=die1;
+
+ case 2:
+ moves[imoves].pos[1]=j;
+ moves[imoves].mov[1]=die2;
+
+ case 1:
+ moves[imoves].pos[0]=i;
+ moves[imoves].mov[0]=die1;
+ imoves++;
+ }
+ }
+ switch(count) {
+ case 4:
+ break;
+
+ case 3:
+ mover[l]++;
+ mover[l+die1]--;
+ break;
+
+ case 2:
+ mover[j]++;
+ mover[j+die2]--;
+ break;
+
+ case 1:
+ mover[i]++;
+ mover[i+die1]--;
+ }
+}
+
+strategy(player,playee)
+int *player,*playee;
+{
+ int k, n, nn, bestval, moveval, prob;
+
+ n = 0;
+ if(imoves == 0)
+ return(NIL);
+ goodmoves[0] = NIL;
+ bestval = -32000;
+ for(k = 0; k < imoves; k++){
+ if((moveval=eval(player,playee,k,&prob)) < bestval)
+ continue;
+ if(moveval > bestval){
+ bestval = moveval;
+ n = 0;
+ }
+ if(n<MAXGMOV){
+ goodmoves[n]=k;
+ probmoves[n++]=prob;
+ }
+ }
+ if(level=='e' && n>1){
+ nn=n;
+ n=0;
+ prob=32000;
+ for(k = 0; k < nn; k++){
+ if((moveval=probmoves[k]) > prob)
+ continue;
+ if(moveval<prob){
+ prob=moveval;
+ n=0;
+ }
+ goodmoves[n]=goodmoves[k];
+ probmoves[n++]=probmoves[k];
+ }
+ }
+ return(goodmoves[(rand()>>4)%n]);
+}
+
+eval(player,playee,k,prob)
+int *player,*playee,k,*prob;
+{
+ int newtry[31], newother[31], *r, *q, *p, n, sum, first;
+ int ii, lastwhite, lastbrown;
+
+ *prob = sum = 0;
+ r = player+25;
+ p = newtry;
+ q = newother;
+ while(player<r){
+ *p++= *player++;
+ *q++= *playee++;
+ }
+ q=newtry+31;
+ for(p = newtry+25; p < q; p++) /* zero out spaces for hit pieces */
+ *p = 0;
+ for(n = 0; n < 4; n++){
+ if(moves[k].pos[n] == NIL)
+ break;
+ newtry[moves[k].pos[n]]--;
+ newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++;
+ if(ii<25 && newother[25-ii]==1){
+ newother[25-ii]=0;
+ newother[0]++;
+ if(ii<=15 && level=='e') /* hit if near other's home */
+ sum++;
+ }
+ }
+ for(lastbrown = 0; newother[lastbrown] == 0; lastbrown++);
+ ;
+ for(lastwhite = 0; newtry[lastwhite] == 0; lastwhite++)
+ ;
+ lastwhite = 25-lastwhite;
+ if(lastwhite<=6 && lastwhite<lastbrown)
+ sum=1000;
+ /* experts running game. */
+ /* first priority is to */
+ /* get all pieces into */
+ /* white's home */
+ if(lastwhite<lastbrown && level=='e' && lastwhite>6) {
+ for(sum = 1000; lastwhite > 6; lastwhite--)
+ sum = sum-lastwhite*newtry[25-lastwhite];
+ }
+ for(first = 0; first < 25; first++)
+ if(newother[first] != 0) /*find other's first piece*/
+ break;
+ q = newtry+25;
+ for(p = newtry+1; p < q;) /* blocked points are good */
+ if(*p++ > 1)
+ sum++;
+ if(first > 5) { /* only stress removing pieces if */
+ /* homeboard cannot be hit */
+ q = newtry+31;
+ p=newtry+25;
+ for(n = 6; p < q; n--)
+ sum += *p++ * n; /*remove pieces, but just barely*/
+ }
+ if(level != 'b'){
+ r = newtry+25-first; /*singles past this point can't be hit*/
+ for(p = newtry+7; p < r; )
+ if(*p++ == 1) /*singles are bad after 1st 6 points if they can be hit*/
+ sum--;
+ q = newtry+3;
+ for(p = newtry; p < q; ) /*bad to be on 1st three points*/
+ sum -= *p++;
+ }
+
+ for(n = 1; n <= 4; n++)
+ *prob += n*getprob(newtry,newother,6*n-5,6*n);
+ return(sum);
+}
+instructions()
+{
+ register fd, r;
+ char buf[BUFSIZ];
+
+ if((fd = open(RULES, 0)) < 0) {
+ fprintf(stderr, "back: cannot open %s\n", RULES);
+ return;
+ }
+ while(r = read(fd, buf, BUFSIZ))
+ write(1, buf, r);
+}
+
+getprob(player,playee,start,finish)
+int *player,*playee,start,finish;
+{ /*returns the probability (times 102) that any
+ pieces belonging to 'player' and lying between
+ his points 'start' and 'finish' will be hit
+ by a piece belonging to playee
+ */
+ int k, n, sum;
+
+ sum = 0;
+ for(; start <= finish; start++){
+ if(player[start] == 1){
+ for(k = 1; k <= 12; k++){
+ if((n=25-start-k) < 0)
+ break;
+ if(playee[n] != 0)
+ sum += probability[k];
+ }
+ }
+ }
+ return(sum);
+}
+prtbrd()
+{
+ int k;
+ static char undersc[]="______________________________________________________";
+
+ fprintf(stdout, "White's Home\n%s\r",undersc);
+ for(k = 1; k <= 6; k++)
+ fprintf(stdout, "%4d",k);
+ fprintf(stdout, " ");
+ for(k = 7; k <= 12; k++)
+ fprintf(stdout, "%4d",k);
+ putchar('\n');
+ numline(brown, white, 1, 6);
+ fprintf(stdout, " ");
+ numline(brown, white, 7, 12);
+ putchar('\n');
+ colorline(brown, 'B', white, 'W', 1, 6);
+ fprintf(stdout, " ");
+ colorline(brown, 'B', white, 'W', 7, 12);
+ putchar('\n');
+ if(white[0] != 0)
+ fprintf(stdout, "%28dW\n",white[0]);
+ else
+ putchar('\n');
+ if(brown[0] != 0)
+ fprintf(stdout, "%28dB\n", brown[0]);
+ else
+ putchar('\n');
+ colorline(white, 'W', brown, 'B', 1, 6);
+ fprintf(stdout, " ");
+ colorline(white, 'W', brown, 'B', 7, 12);
+ fprintf(stdout, "\n%s\r",undersc);
+ numline(white, brown, 1, 6);
+ fprintf(stdout, " ");
+ numline(white, brown, 7, 12);
+ putchar('\n');
+ for(k = 24; k >= 19; k--)
+ fprintf(stdout, "%4d",k);
+ fprintf(stdout, " ");
+ for(k = 18; k >= 13; k--)
+ fprintf(stdout, "%4d",k);
+ fprintf(stdout, "\nBrown's Home\n\n\n\n\n");
+}
+numline(upcol,downcol,start,fin)
+int *upcol,*downcol,start,fin;
+{
+ int k, n;
+
+ for(k = start; k <= fin; k++){
+ if((n = upcol[k]) != 0 || (n = downcol[25-k]) != 0)
+ fprintf(stdout, "%4d", n);
+ else
+ fprintf(stdout, " ");
+ }
+}
+colorline(upcol,c1,downcol,c2,start,fin)
+int *upcol,*downcol,start,fin;
+char c1,c2;
+{
+ int k;
+ char c;
+
+ for(k = start; k <= fin; k++){
+ c = ' ';
+ if(upcol[k] != 0)
+ c = c1;
+ if(downcol[25-k] != 0)
+ c = c2;
+ fprintf(stdout, " %c",c);
+ }
+}
diff --git a/backgammon/common_source/board.c b/backgammon/common_source/board.c
new file mode 100644
index 00000000..d21d36a9
--- /dev/null
+++ b/backgammon/common_source/board.c
@@ -0,0 +1,176 @@
+/*
+ * 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
+static char sccsid[] = "@(#)board.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+static int i, j, k;
+static char ln[60];
+
+wrboard () {
+ register int l;
+ static char bl[] =
+ "| | | |\n";
+ static char sv[] =
+ "| | | | \n";
+
+ fixtty (noech);
+ clear();
+
+ if (tflag) {
+ fboard();
+ goto lastline;
+ }
+
+ writel ("_____________________________________________________\n");
+ writel (bl);
+ strcpy (ln,bl);
+ for (j = 1; j < 50; j += 4) {
+ k = j/4+(j > 24? 12: 13);
+ ln[j+1] = k%10+'0';
+ ln[j] = k/10+'0';
+ if (j == 21)
+ j += 4;
+ }
+ writel (ln);
+ for (i = 0; i < 5; i++) {
+ strcpy (ln,sv);
+ for (j = 1; j < 50; j += 4) {
+ k = j/4+(j > 24? 12: 13);
+ wrbsub ();
+ if (j == 21)
+ j += 4;
+ }
+ if (-board[25] > i)
+ ln[26] = 'w';
+ if (-board[25] > i+5)
+ ln[25] = 'w';
+ if (-board[25] > i+10)
+ ln[27] = 'w';
+ l = 53;
+ if (off[1] > i || (off[1] < 0 && off[1]+15 > i)) {
+ ln[54] = 'r';
+ l = 55;
+ }
+ if (off[1] > i+5 || (off[1] < 0 && off[1]+15 > i+5)) {
+ ln[55] = 'r';
+ l = 56;
+ }
+ if (off[1] > i+10 || (off[1] < 0 && off[1]+15 > i+10)) {
+ ln[56] = 'r';
+ l = 57;
+ }
+ ln[l++] = '\n';
+ ln[l] = '\0';
+ writel (ln);
+ }
+ strcpy (ln,bl);
+ ln[25] = 'B';
+ ln[26] = 'A';
+ ln[27] = 'R';
+ writel (ln);
+ strcpy (ln,sv);
+ for (i = 4; i > -1; i--) {
+ for (j = 1; j < 50; j += 4) {
+ k = ((j > 24? 53: 49)-j)/4;
+ wrbsub();
+ if (j == 21)
+ j += 4;
+ }
+ if (board[0] > i)
+ ln[26] = 'r';
+ if (board[0] > i+5)
+ ln[25] = 'r';
+ if (board[0] > i+10)
+ ln[27] = 'r';
+ l = 53;
+ if (off[0] > i || (off[0] < 0 && off[0]+15 > i)) {
+ ln[54] = 'w';
+ l = 55;
+ }
+ if (off[0] > i+5 || (off[0] < 0 && off[0]+15 > i+5)) {
+ ln[55] = 'w';
+ l = 56;
+ }
+ if (off[0] > i+10 || (off[0] < 0 && off[0]+15 > i+10)) {
+ ln[56] = 'w';
+ l = 57;
+ }
+ ln[l++] = '\n';
+ ln[l] = '\0';
+ writel (ln);
+ }
+ strcpy (ln,bl);
+ for (j = 1; j < 50; j += 4) {
+ k = ((j > 24? 53: 49)-j)/4;
+ ln[j+1] = k%10+'0';
+ if (k > 9)
+ ln[j] = k/10+'0';
+ if (j == 21)
+ j += 4;
+ }
+ writel (ln);
+ writel ("|_______________________|___|_______________________|\n");
+
+lastline:
+ gwrite ();
+ if (tflag)
+ curmove (18,0);
+ else {
+ writec ('\n');
+ writec ('\n');
+ }
+ fixtty(raw);
+}
+
+wrbsub () {
+ register int m;
+ register char d;
+
+ if (board[k] > 0) {
+ m = board[k];
+ d = 'r';
+ } else {
+ m = -board[k];
+ d = 'w';
+ }
+ if (m>i)
+ ln[j+1] = d;
+ if (m>i+5)
+ ln[j] = d;
+ if (m>i+10)
+ ln[j+2] = d;
+}
diff --git a/backgammon/common_source/check.c b/backgammon/common_source/check.c
new file mode 100644
index 00000000..5ef2eb2b
--- /dev/null
+++ b/backgammon/common_source/check.c
@@ -0,0 +1,158 @@
+/*
+ * 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
+static char sccsid[] = "@(#)check.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+getmove () {
+ register int i, c;
+
+ c = 0;
+ for (;;) {
+ i = checkmove(c);
+
+ switch (i) {
+ case -1:
+ if (movokay(mvlim)) {
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ for (i = 0; i < mvlim; i++)
+ if (h[i])
+ wrhit(g[i]);
+ nexturn();
+ if (*offopp == 15)
+ cturn *= -2;
+ if (tflag && pnum)
+ bflag = pnum;
+ return;
+ }
+
+ case -4:
+ case 0:
+ if (tflag)
+ refresh();
+ if (i != 0 && i != -4)
+ break;
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ writel (*Colorptr);
+ if (i == -4)
+ writel (" must make ");
+ else
+ writel (" can only make ");
+ writec (mvlim+'0');
+ writel (" move");
+ if (mvlim > 1)
+ writec ('s');
+ writec ('.');
+ writec ('\n');
+ break;
+
+ case -3:
+ if (quit())
+ return;
+ }
+
+ if (! tflag)
+ proll ();
+ else {
+ curmove (cturn == -1? 18: 19,39);
+ cline ();
+ c = -1;
+ }
+ }
+}
+
+movokay (mv)
+register int mv;
+
+{
+ register int i, m;
+
+ if (d0)
+ swap;
+
+ for (i = 0; i < mv; i++) {
+
+ if (p[i] == g[i]) {
+ moverr (i);
+ curmove (20,0);
+ writel ("Attempt to move to same location.\n");
+ return (0);
+ }
+
+ if (cturn*(g[i]-p[i]) < 0) {
+ moverr (i);
+ curmove (20,0);
+ writel ("Backwards move.\n");
+ return (0);
+ }
+
+ if (abs(board[bar]) && p[i] != bar) {
+ moverr (i);
+ curmove (20,0);
+ writel ("Men still on bar.\n");
+ return (0);
+ }
+
+ if ( (m = makmove(i)) ) {
+ moverr (i);
+ switch (m) {
+
+ case 1:
+ writel ("Move not rolled.\n");
+ break;
+
+ case 2:
+ writel ("Bad starting position.\n");
+ break;
+
+ case 3:
+ writel ("Destination occupied.\n");
+ break;
+
+ case 4:
+ writel ("Can't remove men yet.\n");
+ }
+ return (0);
+ }
+ }
+ return (1);
+}
diff --git a/backgammon/common_source/fancy.c b/backgammon/common_source/fancy.c
new file mode 100644
index 00000000..6afaa367
--- /dev/null
+++ b/backgammon/common_source/fancy.c
@@ -0,0 +1,748 @@
+/*
+ * 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
+static char sccsid[] = "@(#)fancy.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char PC; /* padding character */
+char *BC; /* backspace sequence */
+char *CD; /* clear to end of screen sequence */
+char *CE; /* clear to end of line sequence */
+char *CL; /* clear screen sequence */
+char *CM; /* cursor movement instructions */
+char *HO; /* home cursor sequence */
+char *MC; /* column cursor movement map */
+char *ML; /* row cursor movement map */
+char *ND; /* forward cursor sequence */
+char *UP; /* up cursor sequence */
+
+int lHO; /* length of HO */
+int lBC; /* length of BC */
+int lND; /* length of ND */
+int lUP; /* length of UP */
+int CO; /* number of columns */
+int LI; /* number of lines */
+int *linect; /* array of lengths of lines on screen
+ (the actual screen is not stored) */
+
+ /* two letter codes */
+char tcap[] = "bccdceclcmhomcmlndup";
+ /* corresponding strings */
+char **tstr[] = { &BC, &CD, &CE, &CL, &CM, &HO, &MC, &ML, &ND, &UP };
+
+int buffnum; /* pointer to output buffer */
+
+char tbuf[1024]; /* buffer for decoded termcap entries */
+
+int oldb[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+int oldr;
+int oldw;
+ /* "real" cursor positions, so
+ * it knows when to reposition.
+ * These are -1 if curr and curc
+ * are accurate */
+int realr;
+int realc;
+
+void addbuf();
+
+fboard () {
+ register int i, j, l;
+
+ curmove (0,0); /* do top line */
+ for (i = 0; i < 53; i++)
+ fancyc ('_');
+
+ curmove (15,0); /* do botttom line */
+ for (i = 0; i < 53; i++)
+ fancyc ('_');
+
+ l = 1; /* do vertical lines */
+ for (i = 52; i > -1; i -= 28) {
+ curmove ( (l == 1? 1: 15) ,i);
+ fancyc ('|');
+ for (j = 0; j < 14; j++) {
+ curmove (curr+l,curc-1);
+ fancyc ('|');
+ }
+ if (i == 24)
+ i += 32;
+ l = -l; /* alternate directions */
+ }
+
+ curmove (2,1); /* label positions 13-18 */
+ for (i = 13; i < 18; i++) {
+ fancyc ('1');
+ fancyc ((i % 10)+'0');
+ curmove (curr,curc+2);
+ }
+ fancyc ('1');
+ fancyc ('8');
+
+ curmove (2,29); /* label positions 19-24 */
+ fancyc ('1');
+ fancyc ('9');
+ for (i = 20; i < 25; i++) {
+ curmove (curr,curc+2);
+ fancyc ('2');
+ fancyc ((i % 10)+'0');
+ }
+
+ curmove (14,1); /* label positions 12-7 */
+ fancyc ('1');
+ fancyc ('2');
+ for (i = 11; i > 6; i--) {
+ curmove (curr,curc+2);
+ fancyc (i > 9? '1': ' ');
+ fancyc ((i % 10)+'0');
+ }
+
+ curmove (14,30); /* label positions 6-1 */
+ fancyc ('6');
+ for (i = 5; i > 0; i--) {
+ curmove (curr,curc+3);
+ fancyc (i+'0');
+ }
+
+ for (i = 12; i > 6; i--) /* print positions 12-7 */
+ if (board[i])
+ bsect (board[i],13,1+4*(12-i),-1);
+
+ if (board[0]) /* print red men on bar */
+ bsect (board[0],13,25,-1);
+
+ for (i = 6; i > 0; i--) /* print positions 6-1 */
+ if (board[i])
+ bsect (board[i],13,29+4*(6-i),-1);
+
+ l = (off[1] < 0? off[1]+15: off[1]); /* print white's home */
+ bsect (l,3,54,1);
+
+ curmove (8,25); /* print the word BAR */
+ fancyc ('B');
+ fancyc ('A');
+ fancyc ('R');
+
+ for (i = 13; i < 19; i++) /* print positions 13-18 */
+ if (board[i])
+ bsect (board[i],3,1+4*(i-13),1);
+
+ if (board[25]) /* print white's men on bar */
+ bsect (board[25],3,25,1);
+
+ for (i = 19; i < 25; i++) /* print positions 19-24 */
+ if (board[i])
+ bsect (board[i],3,29+4*(i-19),1);
+
+ l = (off[0] < 0? off[0]+15: off[0]); /* print red's home */
+ bsect (-l,13,54,-1);
+
+ for (i = 0; i < 26; i++) /* save board position
+ * for refresh later */
+ oldb[i] = board[i];
+ oldr = (off[1] < 0? off[1]+15: off[1]);
+ oldw = -(off[0] < 0? off[0]+15: off[0]);
+}
+
+/*
+ * bsect (b,rpos,cpos,cnext)
+ * Print the contents of a board position. "b" has the value of the
+ * position, "rpos" is the row to start printing, "cpos" is the column to
+ * start printing, and "cnext" is positive if the position starts at the top
+ * and negative if it starts at the bottom. The value of "cpos" is checked
+ * to see if the position is a player's home, since those are printed
+ * differently.
+ */
+
+bsect (b,rpos,cpos,cnext)
+int b; /* contents of position */
+int rpos; /* row of position */
+int cpos; /* column of position */
+int cnext; /* direction of position */
+
+{
+ register int j; /* index */
+ register int n; /* number of men on position */
+ register int bct; /* counter */
+ int k; /* index */
+ char pc; /* color of men on position */
+
+ n = abs(b); /* initialize n and pc */
+ pc = (b > 0? 'r': 'w');
+
+ if (n < 6 && cpos < 54) /* position cursor at start */
+ curmove (rpos,cpos+1);
+ else
+ curmove (rpos,cpos);
+
+ for (j = 0; j < 5; j++) { /* print position row by row */
+
+ for (k = 0; k < 15; k += 5) /* print men */
+ if (n > j+k)
+ fancyc (pc);
+
+ if (j < 4) { /* figure how far to
+ * back up for next
+ * row */
+ if (n < 6) { /* stop if none left */
+ if (j+1 == n)
+ break;
+ bct = 1; /* single column */
+ } else {
+ if (n < 11) { /* two columns */
+ if (cpos == 54) { /* home pos */
+ if (j+5 >= n)
+ bct = 1;
+ else
+ bct = 2;
+ }
+ if (cpos < 54) { /* not home */
+ if (j+6 >= n)
+ bct = 1;
+ else
+ bct = 2;
+ }
+ } else { /* three columns */
+ if (j+10 >= n)
+ bct = 2;
+ else
+ bct = 3;
+ }
+ }
+ curmove (curr+cnext,curc-bct); /* reposition cursor */
+ }
+ }
+}
+
+refresh() {
+ register int i, r, c;
+
+ r = curr; /* save current position */
+ c = curc;
+
+ for (i = 12; i > 6; i--) /* fix positions 12-7 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],13,1+(12-i)*4,-1);
+ oldb[i] = board[i];
+ }
+
+ if (board[0] != oldb[0]) { /* fix red men on bar */
+ fixpos (oldb[0],board[0],13,25,-1);
+ oldb[0] = board[0];
+ }
+
+ for (i = 6; i > 0; i--) /* fix positions 6-1 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],13,29+(6-i)*4,-1);
+ oldb[i] = board[i];
+ }
+
+ i = -(off[0] < 0? off[0]+15: off[0]); /* fix white's home */
+ if (oldw != i) {
+ fixpos (oldw,i,13,54,-1);
+ oldw = i;
+ }
+
+ for (i = 13; i < 19; i++) /* fix positions 13-18 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],3,1+(i-13)*4,1);
+ oldb[i] = board[i];
+ }
+
+ if (board[25] != oldb[25]) { /* fix white men on bar */
+ fixpos (oldb[25],board[25],3,25,1);
+ oldb[25] = board[25];
+ }
+
+ for (i = 19; i < 25; i++) /* fix positions 19-24 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],3,29+(i-19)*4,1);
+ oldb[i] = board[i];
+ }
+
+ i = (off[1] < 0? off[1]+15: off[1]); /* fix red's home */
+ if (oldr != i) {
+ fixpos (oldr,i,3,54,1);
+ oldr = i;
+ }
+
+ curmove (r,c); /* return to saved position */
+ newpos();
+ buflush();
+}
+
+fixpos (old,new,r,c,inc)
+int old, new, r, c, inc;
+
+{
+ register int o, n, nv;
+ int ov, nc;
+ char col;
+
+ if (old*new >= 0) {
+ ov = abs(old);
+ nv = abs(new);
+ col = (old+new > 0? 'r': 'w');
+ o = (ov-1)/5;
+ n = (nv-1)/5;
+ if (o == n) {
+ if (o == 2)
+ nc = c+2;
+ if (o == 1)
+ nc = c < 54? c: c+1;
+ if (o == 0)
+ nc = c < 54? c+1: c;
+ if (ov > nv)
+ fixcol (r+inc*(nv-n*5),nc,abs(ov-nv),' ',inc);
+ else
+ fixcol (r+inc*(ov-o*5),nc,abs(ov-nv),col,inc);
+ return;
+ } else {
+ if (c < 54) {
+ if (o+n == 1) {
+ if (n) {
+ fixcol (r,c,abs(nv-5),col,inc);
+ if (ov != 5)
+ fixcol (r+inc*ov,c+1,abs(ov-5),col,inc);
+ } else {
+ fixcol (r,c,abs(ov-5),' ',inc);
+ if (nv != 5)
+ fixcol (r+inc*nv,c+1,abs(nv-5),' ',inc);
+ }
+ return;
+ }
+ if (n == 2) {
+ if (ov != 10)
+ fixcol (r+inc*(ov-5),c,abs(ov-10),col,inc);
+ fixcol (r,c+2,abs(nv-10),col,inc);
+ } else {
+ if (nv != 10)
+ fixcol (r+inc*(nv-5),c,abs(nv-10),' ',inc);
+ fixcol (r,c+2,abs(ov-10),' ',inc);
+ }
+ return;
+ }
+ if (n > o) {
+ fixcol (r+inc*(ov%5),c+o,abs(5*n-ov),col,inc);
+ if (nv != 5*n)
+ fixcol (r,c+n,abs(5*n-nv),col,inc);
+ } else {
+ fixcol (r+inc*(nv%5),c+n,abs(5*n-nv),' ',inc);
+ if (ov != 5*o)
+ fixcol (r,c+o,abs(5*o-ov),' ',inc);
+ }
+ return;
+ }
+ }
+ nv = abs(new);
+ fixcol (r,c+1,nv,new > 0? 'r': 'w',inc);
+ if (abs(old) <= abs(new))
+ return;
+ fixcol (r+inc*new,c+1,abs(old+new),' ',inc);
+}
+
+fixcol (r,c,l,ch,inc)
+register int l, ch;
+int r, c, inc;
+
+{
+ register int i;
+
+ curmove (r,c);
+ fancyc (ch);
+ for (i = 1; i < l; i++) {
+ curmove (curr+inc,curc-1);
+ fancyc (ch);
+ }
+}
+
+curmove (r,c)
+register int r, c;
+
+{
+ if (curr == r && curc == c)
+ return;
+ if (realr == -1) {
+ realr = curr;
+ realc = curc;
+ }
+ curr = r;
+ curc = c;
+}
+
+newpos () {
+ register int r; /* destination row */
+ register int c; /* destination column */
+ register int mode = -1; /* mode of movement */
+
+ int count = 1000; /* character count */
+ int i; /* index */
+ int j; /* index */
+ int n; /* temporary variable */
+ char *m; /* string containing CM movement */
+
+
+ if (realr == -1) /* see if already there */
+ return;
+
+ r = curr; /* set current and dest. positions */
+ c = curc;
+ curr = realr;
+ curc = realc;
+
+ /* double check position */
+ if (curr == r && curc == c) {
+ realr = realc = -1;
+ return;
+ }
+
+ if (CM) { /* try CM to get there */
+ mode = 0;
+ m = (char *)tgoto (CM,c,r);
+ count = strlen (m);
+ }
+
+ /* try HO and local movement */
+ if (HO && (n = r+c*lND+lHO) < count) {
+ mode = 1;
+ count = n;
+ }
+
+ /* try various LF combinations */
+ if (r >= curr) {
+ /* CR, LF, and ND */
+ if ((n = (r-curr)+c*lND+1) < count) {
+ mode = 2;
+ count = n;
+ }
+ /* LF, ND */
+ if (c >= curc && (n = (r-curr)+(c-curc)*lND) < count) {
+ mode = 3;
+ count = n;
+ }
+ /* LF, BS */
+ if (c < curc && (n = (r-curr)+(curc-c)*lBC) < count) {
+ mode = 4;
+ count = n;
+ }
+ }
+
+ /* try corresponding UP combinations */
+ if (r < curr) {
+ /* CR, UP, and ND */
+ if ((n = (curr-r)*lUP+c*lND+1) < count) {
+ mode = 5;
+ count = n;
+ }
+ /* UP and ND */
+ if (c >= curc && (n = (curr-r)*lUP+(c-curc)*lND) < count) {
+ mode = 6;
+ count = n;
+ }
+ /* UP and BS */
+ if (c < curc && (n = (curr-r)*lUP+(curc-c)*lBC) < count) {
+ mode = 7;
+ count = n;
+ }
+ }
+
+ /* space over */
+ if (curr == r && c > curc && linect[r] < curc && c-curc < count)
+ mode = 8;
+
+ switch (mode) {
+
+ case -1: /* error! */
+ write (2,"\r\nInternal cursor error.\r\n",26);
+ getout();
+
+ /* direct cursor motion */
+ case 0:
+ tputs (m,abs(curr-r),addbuf);
+ break;
+
+ /* relative to "home" */
+ case 1:
+ tputs (HO,r,addbuf);
+ for (i = 0; i < r; i++)
+ addbuf ('\012');
+ for (i = 0; i < c; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* CR and down and over */
+ case 2:
+ addbuf ('\015');
+ for (i = 0; i < r-curr; i++)
+ addbuf ('\012');
+ for (i = 0; i < c; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* down and over */
+ case 3:
+ for (i = 0; i < r-curr; i++)
+ addbuf ('\012');
+ for (i = 0; i < c-curc; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* down and back */
+ case 4:
+ for (i = 0; i < r-curr; i++)
+ addbuf ('\012');
+ for (i = 0; i < curc-c; i++)
+ addbuf ('\010');
+ break;
+
+ /* CR and up and over */
+ case 5:
+ addbuf ('\015');
+ for (i = 0; i < curr-r; i++)
+ tputs (UP,1,addbuf);
+ for (i = 0; i < c; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* up and over */
+ case 6:
+ for (i = 0; i < curr-r; i++)
+ tputs (UP,1,addbuf);
+ for (i = 0; i < c-curc; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* up and back */
+ case 7:
+ for (i = 0; i < curr-r; i++)
+ tputs (UP,1,addbuf);
+ for (i = 0; i < curc-c; i++) {
+ if (BC)
+ tputs (BC,1,addbuf);
+ else
+ addbuf ('\010');
+ }
+ break;
+
+ /* safe space */
+ case 8:
+ for (i = 0; i < c-curc; i++)
+ addbuf (' ');
+ }
+
+ /* fix positions */
+ curr = r;
+ curc = c;
+ realr = -1;
+ realc = -1;
+}
+
+clear () {
+ register int i;
+
+ /* double space if can't clear */
+ if (CL == 0) {
+ writel ("\n\n");
+ return;
+ }
+
+ curr = curc = 0; /* fix position markers */
+ realr = realc = -1;
+ for (i = 0; i < 24; i++) /* clear line counts */
+ linect[i] = -1;
+ buffnum = -1; /* ignore leftover buffer contents */
+ tputs (CL,CO,addbuf); /* put CL in buffer */
+}
+
+tos () { /* home cursor */
+ curmove (0,0);
+}
+
+fancyc (c)
+register char c; /* character to output */
+{
+ register int sp; /* counts spaces in a tab */
+
+ if (c == '\007') { /* bells go in blindly */
+ addbuf (c);
+ return;
+ }
+
+ /* process tabs, use spaces if the
+ * the tab should be erasing things,
+ * otherwise use cursor movement
+ * routines. Note this does not use
+ * hardware tabs at all. */
+ if (c == '\t') {
+ sp = (curc+8) & (~ 7); /* compute spaces */
+ /* check line length */
+ if (linect[curr] >= curc || sp < 4) {
+ for (; sp > curc; sp--)
+ addbuf (' ');
+ curc = sp; /* fix curc */
+ } else
+ curmove (curr,sp);
+ return;
+ }
+
+ /* do newline be calling newline */
+ if (c == '\n') {
+ newline();
+ return;
+ }
+
+ /* ignore any other control chars */
+ if (c < ' ')
+ return;
+
+ /* if an erasing space or non-space,
+ * just add it to buffer. Otherwise
+ * use cursor movement routine, so that
+ * multiple spaces will be grouped
+ * together */
+ if (c > ' ' || linect[curr] >= curc) {
+ newpos (); /* make sure position correct */
+ addbuf (c); /* add character to buffer */
+ /* fix line length */
+ if (c == ' ' && linect[curr] == curc)
+ linect[curr]--;
+ else if (linect[curr] < curc)
+ linect[curr] = curc;
+ curc++; /* fix curc */
+ } else
+ /* use cursor movement routine */
+ curmove (curr,curc+1);
+}
+
+clend() {
+ register int i;
+ register char *s;
+
+
+ if (CD) {
+ tputs (CD,CO-curr,addbuf);
+ for (i = curr; i < LI; i++)
+ linect[i] = -1;
+ return;
+ }
+
+ curmove (i = curr,0);
+ cline();
+ while (curr < LI-1) {
+ curmove (curr+1,0);
+ if (linect[curr] > -1)
+ cline ();
+ }
+ curmove (i,0);
+}
+
+cline () {
+ register int i;
+ register int c;
+ register char *s;
+
+ if (curc > linect[curr])
+ return;
+ newpos ();
+ if (CE) {
+ tputs (CE,1,addbuf);
+ linect[curr] = curc-1;
+ } else {
+ c = curc-1;
+ while (linect[curr] > c) {
+ addbuf (' ');
+ curc++;
+ linect[curr]--;
+ }
+ curmove (curr,c+1);
+ }
+}
+
+newline () {
+ cline();
+ if (curr == LI-1)
+ curmove (begscr,0);
+ else
+ curmove (curr+1,0);
+}
+
+getcaps (s)
+register char *s;
+
+{
+ register char *code; /* two letter code */
+ register char ***cap; /* pointer to cap string */
+ char *bufp; /* pointer to cap buffer */
+ char tentry[1024]; /* temporary uncoded caps buffer */
+
+ tgetent (tentry,s); /* get uncoded termcap entry */
+
+ LI = tgetnum ("li"); /* get number of lines */
+ if (LI == -1)
+ LI = 12;
+ CO = tgetnum ("co"); /* get number of columns */
+ if (CO == -1)
+ CO = 65;
+
+ bufp = tbuf; /* get padding character */
+ tgetstr ("pc",&bufp);
+ if (bufp != tbuf)
+ PC = *tbuf;
+ else
+ PC = 0;
+
+ bufp = tbuf; /* get string entries */
+ cap = tstr;
+ for (code = tcap; *code; code += 2)
+ **cap++ = (char *)tgetstr (code,&bufp);
+
+ /* get pertinent lengths */
+ if (HO)
+ lHO = strlen (HO);
+ if (BC)
+ lBC = strlen (BC);
+ else
+ lBC = 1;
+ if (UP)
+ lUP = strlen (UP);
+ if (ND)
+ lND = strlen (ND);
+ if (LI < 24 || CO < 72 || !(CL && UP && ND))
+ return (0);
+ linect = (int *)calloc (LI+1,sizeof(int));
+ return (1);
+}
diff --git a/backgammon/common_source/init.c b/backgammon/common_source/init.c
new file mode 100644
index 00000000..9d3fce3b
--- /dev/null
+++ b/backgammon/common_source/init.c
@@ -0,0 +1,65 @@
+/*
+ * 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
+static char sccsid[] = "@(#)init.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <sgtty.h>
+
+/*
+ * variable initialization.
+ */
+
+ /* name of executable object programs */
+char EXEC[] = "/usr/games/backgammon";
+char TEACH[] = "/usr/games/teachgammon";
+
+int pnum = 2; /* color of player:
+ -1 = white
+ 1 = red
+ 0 = both
+ 2 = not yet init'ed */
+int acnt = 0; /* length of args */
+int aflag = 1; /* flag to ask for rules or instructions */
+int bflag = 0; /* flag for automatic board printing */
+int cflag = 0; /* case conversion flag */
+int hflag = 1; /* flag for cleaning screen */
+int mflag = 0; /* backgammon flag */
+int raflag = 0; /* 'roll again' flag for recovered game */
+int rflag = 0; /* recovered game flag */
+int tflag = 0; /* cursor addressing flag */
+int iroll = 0; /* special flag for inputting rolls */
+int rfl = 0;
+
+char *color[] = {"White","Red","white","red"};
diff --git a/backgammon/common_source/odds.c b/backgammon/common_source/odds.c
new file mode 100644
index 00000000..dc780497
--- /dev/null
+++ b/backgammon/common_source/odds.c
@@ -0,0 +1,113 @@
+/*
+ * 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
+static char sccsid[] = "@(#)odds.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+odds (r1,r2,val)
+register int r1;
+int r2, val;
+{
+ register int i, j;
+
+ if (r1 == 0) {
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 6; j++)
+ table[i][j] = 0;
+ return;
+ } else {
+ r1--;
+ if (r2-- == 0)
+ for (i = 0; i < 6; i++) {
+ table[i][r1] += val;
+ table[r1][i] += val;
+ }
+ else {
+ table[r2][r1] += val;
+ table[r1][r2] += val;
+ }
+ }
+}
+
+count () {
+ register int i;
+ register int j;
+ register int total;
+
+ total = 0;
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 6; j++)
+ total += table[i][j];
+ return (total);
+}
+
+canhit (i,c)
+int i, c;
+
+{
+ register int j, k, b;
+ int a, d, diff, place, addon, menstuck;
+
+ if (c == 0)
+ odds (0,0,0);
+ if (board[i] > 0) {
+ a = -1;
+ b = 25;
+ } else {
+ a = 1;
+ b = 0;
+ }
+ place = abs (25-b-i);
+ menstuck = abs (board[b]);
+ for (j = b; j != i; j += a) {
+ if (board[j]*a > 0) {
+ diff = abs(j-i);
+ addon = place+((board[j]*a > 2 || j == b)? 5: 0);
+ if ((j == b && menstuck == 1) &&
+ (j != b && menstuck == 0))
+ for (k = 1; k < diff; k++)
+ if (k < 7 && diff-k < 7 &&
+ (board[i+a*k]*a >= 0 ||
+ board[i+a*(diff-k)] >= 0))
+ odds (k,diff-k,addon);
+ if ((j == b || menstuck < 2) && diff < 7)
+ odds (diff,0,addon);
+ }
+ if (j == b && menstuck > 1)
+ break;
+ }
+ return (count());
+}
diff --git a/backgammon/common_source/one.c b/backgammon/common_source/one.c
new file mode 100644
index 00000000..c00f4ca1
--- /dev/null
+++ b/backgammon/common_source/one.c
@@ -0,0 +1,169 @@
+/*
+ * 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
+static char sccsid[] = "@(#)one.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+makmove (i)
+register int i;
+
+{
+ register int n, d;
+ int max;
+
+ d = d0;
+ n = abs(g[i]-p[i]);
+ max = (*offptr < 0? 7: last());
+ if (board[p[i]]*cturn <= 0)
+ return (checkd(d)+2);
+ if (g[i] != home && board[g[i]]*cturn < -1)
+ return (checkd(d)+3);
+ if (i || D0 == D1) {
+ if (n == max? D1 < n: D1 != n)
+ return (checkd(d)+1);
+ } else {
+ if (n == max? D0 < n && D1 < n: D0 != n && D1 != n)
+ return (checkd(d)+1);
+ if (n == max? D0 < n: D0 != n) {
+ if (d0)
+ return (checkd(d)+1);
+ swap;
+ }
+ }
+ if (g[i] == home && *offptr < 0)
+ return (checkd(d)+4);
+ h[i] = 0;
+ board[p[i]] -= cturn;
+ if (g[i] != home) {
+ if (board[g[i]] == -cturn) {
+ board[home] -= cturn;
+ board[g[i]] = 0;
+ h[i] = 1;
+ if (abs(bar-g[i]) < 7) {
+ (*inopp)--;
+ if (*offopp >= 0)
+ *offopp -= 15;
+ }
+ }
+ board[g[i]] += cturn;
+ if (abs(home-g[i]) < 7 && abs(home-p[i]) > 6) {
+ (*inptr)++;
+ if (*inptr+*offptr == 0)
+ *offptr += 15;
+ }
+ } else {
+ (*offptr)++;
+ (*inptr)--;
+ }
+ return (0);
+}
+
+moverr (i)
+register int i;
+
+{
+ register int j;
+
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ writel ("Error: ");
+ for (j = 0; j <= i; j++) {
+ wrint (p[j]);
+ writec ('-');
+ wrint (g[j]);
+ if (j < i)
+ writec (',');
+ }
+ writel ("... ");
+ movback (i);
+}
+
+
+checkd (d)
+register int d;
+
+{
+ if (d0 != d)
+ swap;
+ return (0);
+}
+
+last () {
+ register int i;
+
+ for (i = home-6*cturn; i != home; i += cturn)
+ if (board[i]*cturn > 0)
+ return (abs(home-i));
+}
+
+movback (i)
+register int i;
+
+{
+ register int j;
+
+ for (j = i-1; j >= 0; j--)
+ backone(j);
+}
+
+backone (i)
+register int i;
+
+{
+ board[p[i]] += cturn;
+ if (g[i] != home) {
+ board[g[i]] -= cturn;
+ if (abs(g[i]-home) < 7 && abs(p[i]-home) > 6) {
+ (*inptr)--;
+ if (*inptr+*offptr < 15 && *offptr >= 0)
+ *offptr -= 15;
+ }
+ } else {
+ (*offptr)--;
+ (*inptr)++;
+ }
+ if (h[i]) {
+ board[home] += cturn;
+ board[g[i]] = -cturn;
+ if (abs(bar-g[i]) < 7) {
+ (*inopp)++;
+ if (*inopp+*offopp == 0)
+ *offopp += 15;
+ }
+ }
+}
diff --git a/backgammon/common_source/save.c b/backgammon/common_source/save.c
new file mode 100644
index 00000000..b91d3ec3
--- /dev/null
+++ b/backgammon/common_source/save.c
@@ -0,0 +1,180 @@
+/*
+ * 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
+static char sccsid[] = "@(#)save.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+extern int errno;
+
+static char confirm[] = "Are you sure you want to leave now?";
+static char prompt[] = "Enter a file name: ";
+static char exist1[] = "The file '";
+static char exist2[] =
+ "' already exists.\nAre you sure you want to use this file?";
+static char cantuse[] = "\nCan't use ";
+static char saved[] = "This game has been saved on the file '";
+static char type[] = "'.\nType \"backgammon ";
+static char rec[] = "\" to recover your game.\n\n";
+static char cantrec[] = "Can't recover file: ";
+
+save (n)
+register int n;
+
+{
+ register int fdesc;
+ register char *fs;
+ char fname[50];
+
+ if (n) {
+ if (tflag) {
+ curmove (20,0);
+ clend();
+ } else
+ writec ('\n');
+ writel (confirm);
+ if (! yorn(0))
+ return;
+ }
+ cflag = 1;
+ for (;;) {
+ writel (prompt);
+ fs = fname;
+ while ((*fs = readc()) != '\n') {
+ if (*fs == tty.sg_erase) {
+ if (fs > fname) {
+ fs--;
+ if (tflag)
+ curmove (curr,curc-1);
+ else
+ writec (*fs);
+ } else
+ writec ('\007');
+ continue;
+ }
+ writec (*fs++);
+ }
+ *fs = '\0';
+ if ((fdesc = open(fname,2)) == -1 && errno == 2) {
+ if ((fdesc = creat (fname,0700)) != -1)
+ break;
+ }
+ if (fdesc != -1) {
+ if (tflag) {
+ curmove (18,0);
+ clend();
+ } else
+ writec ('\n');
+ writel (exist1);
+ writel (fname);
+ writel (exist2);
+ cflag = 0;
+ close (fdesc);
+ if (yorn (0)) {
+ unlink (fname);
+ fdesc = creat (fname,0700);
+ break;
+ } else {
+ cflag = 1;
+ continue;
+ }
+ }
+ writel (cantuse);
+ writel (fname);
+ writel (".\n");
+ close (fdesc);
+ cflag = 1;
+ }
+ write (fdesc,board,sizeof board);
+ write (fdesc,off,sizeof off);
+ write (fdesc,in,sizeof in);
+ write (fdesc,dice,sizeof dice);
+ write (fdesc,&cturn,sizeof cturn);
+ write (fdesc,&dlast,sizeof dlast);
+ write (fdesc,&pnum,sizeof pnum);
+ write (fdesc,&rscore,sizeof rscore);
+ write (fdesc,&wscore,sizeof wscore);
+ write (fdesc,&gvalue,sizeof gvalue);
+ write (fdesc,&raflag,sizeof raflag);
+ close (fdesc);
+ if (tflag)
+ curmove (18,0);
+ writel (saved);
+ writel (fname);
+ writel (type);
+ writel (fname);
+ writel (rec);
+ if (tflag)
+ clend();
+ getout ();
+}
+
+recover (s)
+char *s;
+
+{
+ register int i;
+ int fdesc;
+
+ if ((fdesc = open (s,0)) == -1)
+ norec (s);
+ read (fdesc,board,sizeof board);
+ read (fdesc,off,sizeof off);
+ read (fdesc,in,sizeof in);
+ read (fdesc,dice,sizeof dice);
+ read (fdesc,&cturn,sizeof cturn);
+ read (fdesc,&dlast,sizeof dlast);
+ read (fdesc,&pnum,sizeof pnum);
+ read (fdesc,&rscore,sizeof rscore);
+ read (fdesc,&wscore,sizeof wscore);
+ read (fdesc,&gvalue,sizeof gvalue);
+ read (fdesc,&raflag,sizeof raflag);
+ close (fdesc);
+ rflag = 1;
+}
+
+norec (s)
+register char *s;
+
+{
+ register char *c;
+
+ tflag = 0;
+ writel (cantrec);
+ c = s;
+ while (*c != '\0')
+ writec (*c++);
+ getout ();
+}
diff --git a/backgammon/common_source/subs.c b/backgammon/common_source/subs.c
new file mode 100644
index 00000000..7917124f
--- /dev/null
+++ b/backgammon/common_source/subs.c
@@ -0,0 +1,477 @@
+/*
+ * 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
+static char sccsid[] = "@(#)subs.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <stdio.h>
+#include "back.h"
+
+int buffnum;
+char outbuff[BUFSIZ];
+
+static char plred[] = "Player is red, computer is white.";
+static char plwhite[] = "Player is white, computer is red.";
+static char nocomp[] = "(No computer play.)";
+
+char *descr[] = {
+ "Usage: backgammon [-] [n r w b pr pw pb t3a]\n",
+ "\t-\tgets this list\n\tn\tdon't ask for rules or instructions",
+ "\tr\tplayer is red (implies n)\n\tw\tplayer is white (implies n)",
+ "\tb\ttwo players, red and white (implies n)",
+ "\tpr\tprint the board before red's turn",
+ "\tpw\tprint the board before white's turn",
+ "\tpb\tprint the board before both player's turn",
+ "\tterm\tterminal is a term",
+ "\tsfile\trecover saved game from file",
+ 0
+};
+
+errexit (s)
+register char *s;
+{
+ write (2,"\n",1);
+ perror (s);
+ getout();
+}
+
+strset (s1,s2)
+register char *s1, *s2;
+{
+ while ( (*s1++ = *s2++) != '\0');
+}
+
+addbuf (c)
+register char c;
+
+{
+ buffnum++;
+ if (buffnum == BUFSIZ) {
+ if (write(1,outbuff,BUFSIZ) != BUFSIZ)
+ errexit ("addbuf (write):");
+ buffnum = 0;
+ }
+ outbuff[buffnum] = c;
+}
+
+buflush () {
+ if (buffnum < 0)
+ return;
+ buffnum++;
+ if (write (1,outbuff,buffnum) != buffnum)
+ errexit ("buflush (write):");
+ buffnum = -1;
+}
+
+readc () {
+ char c;
+
+ if (tflag) {
+ cline();
+ newpos();
+ }
+ buflush();
+ if (read(0,&c,1) != 1)
+ errexit ("readc");
+#ifdef WHY_IS_THIS_HARDWIRED_IN_HERE
+ if (c == '\177')
+ getout();
+#endif
+ if (c == '\033' || c == '\015')
+ return ('\n');
+ if (cflag)
+ return (c);
+ if (c == '\014')
+ return ('R');
+ if (c >= 'a' && c <= 'z')
+ return (c & 0137);
+ return (c);
+}
+
+writec (c)
+char c;
+{
+ if (tflag)
+ fancyc (c);
+ else
+ addbuf (c);
+}
+
+writel (l)
+register char *l;
+{
+#ifdef DEBUG
+ register char *s;
+
+ if (trace == NULL)
+ trace = fopen ("bgtrace","w");
+
+ fprintf (trace,"writel: \"");
+ for (s = l; *s; s++) {
+ if (*s < ' ' || *s == '\177')
+ fprintf (trace,"^%c",(*s)^0100);
+ else
+ putc (*s,trace);
+ }
+ fprintf (trace,"\"\n");
+ fflush (trace);
+#endif
+
+ while (*l)
+ writec (*l++);
+}
+
+proll () {
+ if (d0)
+ swap;
+ if (cturn == 1)
+ writel ("Red's roll: ");
+ else
+ writel ("White's roll: ");
+ writec (D0+'0');
+ writec ('\040');
+ writec (D1+'0');
+ if (tflag)
+ cline();
+}
+
+wrint (n)
+int n;
+{
+ register int i, j, t;
+
+ for (i = 4; i > 0; i--) {
+ t = 1;
+ for (j = 0; j<i; j++)
+ t *= 10;
+ if (n > t-1)
+ writec ((n/t)%10+'0');
+ }
+ writec (n%10+'0');
+}
+
+gwrite() {
+ register int r, c;
+
+ if (tflag) {
+ r = curr;
+ c = curc;
+ curmove (16,0);
+ }
+
+ if (gvalue > 1) {
+ writel ("Game value: ");
+ wrint (gvalue);
+ writel (". ");
+ if (dlast == -1)
+ writel (color[0]);
+ else
+ writel (color[1]);
+ writel (" doubled last.");
+ } else {
+ switch (pnum) {
+ case -1: /* player is red */
+ writel (plred);
+ break;
+ case 0: /* player is both colors */
+ writel (nocomp);
+ break;
+ case 1: /* player is white */
+ writel (plwhite);
+ }
+ }
+
+ if (rscore || wscore) {
+ writel (" ");
+ wrscore();
+ }
+
+ if (tflag) {
+ cline();
+ curmove (r,c);
+ }
+}
+
+quit () {
+ register int i;
+
+ if (tflag) {
+ curmove (20,0);
+ clend();
+ } else
+ writec ('\n');
+ writel ("Are you sure you want to quit?");
+ if (yorn (0)) {
+ if (rfl) {
+ writel ("Would you like to save this game?");
+ if (yorn(0))
+ save(0);
+ }
+ cturn = 0;
+ return (1);
+ }
+ return (0);
+}
+
+yorn (special)
+register char special; /* special response */
+{
+ register char c;
+ register int i;
+
+ i = 1;
+ while ( (c = readc()) != 'Y' && c != 'N') {
+ if (special && c == special)
+ return (2);
+ if (i) {
+ if (special) {
+ writel (" (Y, N, or ");
+ writec (special);
+ writec (')');
+ } else
+ writel (" (Y or N)");
+ i = 0;
+ } else
+ writec ('\007');
+ }
+ if (c == 'Y')
+ writel (" Yes.\n");
+ else
+ writel (" No.\n");
+ if (tflag)
+ buflush();
+ return (c == 'Y');
+}
+
+wrhit (i)
+register int i;
+{
+ writel ("Blot hit on ");
+ wrint (i);
+ writec ('.');
+ writec ('\n');
+}
+
+nexturn () {
+ register int c;
+
+ cturn = -cturn;
+ c = cturn/abs(cturn);
+ home = bar;
+ bar = 25-bar;
+ offptr += c;
+ offopp -= c;
+ inptr += c;
+ inopp -= c;
+ Colorptr += c;
+ colorptr += c;
+}
+
+getarg (arg)
+register char ***arg;
+
+{
+ register char **s;
+
+ /* process arguments here. dashes are ignored, nbrw are ignored
+ if the game is being recovered */
+
+ s = *arg;
+ while (s[0][0] == '-') {
+ switch (s[0][1]) {
+
+ /* don't ask if rules or instructions needed */
+ case 'n':
+ if (rflag)
+ break;
+ aflag = 0;
+ args[acnt++] = 'n';
+ break;
+
+ /* player is both read and white */
+ case 'b':
+ if (rflag)
+ break;
+ pnum = 0;
+ aflag = 0;
+ args[acnt++] = 'b';
+ break;
+
+ /* player is red */
+ case 'r':
+ if (rflag)
+ break;
+ pnum = -1;
+ aflag = 0;
+ args[acnt++] = 'r';
+ break;
+
+ /* player is white */
+ case 'w':
+ if (rflag)
+ break;
+ pnum = 1;
+ aflag = 0;
+ args[acnt++] = 'w';
+ break;
+
+ /* print board after move according to following character */
+ case 'p':
+ if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b')
+ break;
+ args[acnt++] = 'p';
+ args[acnt++] = s[0][2];
+ if (s[0][2] == 'r')
+ bflag = 1;
+ if (s[0][2] == 'w')
+ bflag = -1;
+ if (s[0][2] == 'b')
+ bflag = 0;
+ break;
+
+ case 't':
+ if (s[0][2] == '\0') { /* get terminal caps */
+ s++;
+ tflag = getcaps (*s);
+ } else
+ tflag = getcaps (&s[0][2]);
+ break;
+
+ case 's':
+ s++;
+ /* recover file */
+ recover (s[0]);
+ break;
+ }
+ s++;
+ }
+ if (s[0] != 0)
+ recover(s[0]);
+}
+
+init () {
+ register int i;
+ for (i = 0; i < 26;)
+ board[i++] = 0;
+ board[1] = 2;
+ board[6] = board[13] = -5;
+ board[8] = -3;
+ board[12] = board[19] = 5;
+ board[17] = 3;
+ board[24] = -2;
+ off[0] = off[1] = -15;
+ in[0] = in[1] = 5;
+ gvalue = 1;
+ dlast = 0;
+}
+
+wrscore () {
+ writel ("Score: ");
+ writel (color[1]);
+ writec (' ');
+ wrint (rscore);
+ writel (", ");
+ writel (color[0]);
+ writec (' ');
+ wrint (wscore);
+}
+
+fixtty (mode)
+int mode;
+{
+ if (tflag)
+ newpos();
+ buflush();
+ tty.sg_flags = mode;
+ if (stty (0,&tty) < 0)
+ errexit("fixtty");
+}
+
+getout () {
+ /* go to bottom of screen */
+ if (tflag) {
+ curmove (23,0);
+ cline();
+ } else
+ writec ('\n');
+
+ /* fix terminal status */
+ fixtty (old);
+ exit();
+}
+roll () {
+ register char c;
+ register int row;
+ register int col;
+
+ if (iroll) {
+ if (tflag) {
+ row = curr;
+ col = curc;
+ curmove (17,0);
+ } else
+ writec ('\n');
+ writel ("ROLL: ");
+ c = readc();
+ if (c != '\n') {
+ while (c < '1' || c > '6')
+ c = readc();
+ D0 = c-'0';
+ writec (' ');
+ writec (c);
+ c = readc();
+ while (c < '1' || c > '6')
+ c = readc();
+ D1 = c-'0';
+ writec (' ');
+ writec (c);
+ if (tflag) {
+ curmove (17,0);
+ cline();
+ curmove (row,col);
+ } else
+ writec ('\n');
+ return;
+ }
+ if (tflag) {
+ curmove (17,0);
+ cline();
+ curmove (row,col);
+ } else
+ writec ('\n');
+ }
+ D0 = rnum(6)+1;
+ D1 = rnum(6)+1;
+ d0 = 0;
+}
diff --git a/backgammon/common_source/table.c b/backgammon/common_source/table.c
new file mode 100644
index 00000000..9555e8dd
--- /dev/null
+++ b/backgammon/common_source/table.c
@@ -0,0 +1,308 @@
+/*
+ * 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
+static char sccsid[] = "@(#)table.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *help2[] = {
+ " Enter moves as <s>-<f> or <s>/<r> where <s> is the starting",
+ "position, <f> is the finishing position, and <r> is the roll.",
+ "Remember, each die roll must be moved separately.",
+ 0
+};
+
+struct state {
+ char ch;
+ int fcode;
+ int newst;
+};
+
+struct state atmata[] = {
+
+ 'R', 1, 0, '?', 7, 0, 'Q', 0, -3, 'B', 8, 25,
+ '9', 2, 25, '8', 2, 25, '7', 2, 25, '6', 2, 25,
+ '5', 2, 25, '4', 2, 25, '3', 2, 25, '2', 2, 19,
+ '1', 2, 15, '0', 2, 25, '.', 0, 0, '9', 2, 25,
+ '8', 2, 25, '7', 2, 25, '6', 2, 25, '5', 2, 25,
+
+ '4', 2, 25, '3', 2, 25, '2', 2, 25, '1', 2, 25,
+ '0', 2, 25, '/', 0, 32, '-', 0, 39, '.', 0, 0,
+ '/', 5, 32, ' ', 6, 3, ',', 6, 3, '\n', 0, -1,
+ '6', 3, 28, '5', 3, 28, '4', 3, 28, '3', 3, 28,
+ '2', 3, 28, '1', 3, 28, '.', 0, 0, 'H', 9, 61,
+
+ '9', 4, 61, '8', 4, 61, '7', 4, 61, '6', 4, 61,
+ '5', 4, 61, '4', 4, 61, '3', 4, 61, '2', 4, 53,
+ '1', 4, 51, '0', 4, 61, '.', 0, 0, '9', 4, 61,
+ '8', 4, 61, '7', 4, 61, '6', 4, 61, '5', 4, 61,
+ '4', 4, 61, '3', 4, 61, '2', 4, 61, '1', 4, 61,
+
+ '0', 4, 61, ' ', 6, 3, ',', 6, 3, '-', 5, 39,
+ '\n', 0, -1, '.', 0, 0
+};
+
+checkmove (ist)
+
+int ist;
+
+{
+ register int j, n;
+ register char c;
+ char a;
+
+domove:
+ if (ist == 0) {
+ if (tflag)
+ curmove (curr,32);
+ else
+ writel ("\t\t");
+ writel ("Move: ");
+ }
+ ist = mvl = ncin = 0;
+ for (j = 0; j < 5; j++)
+ p[j] = g[j] = -1;
+
+dochar:
+ c = readc();
+
+ if (c == 'S') {
+ raflag = 0;
+ save (1);
+ if (tflag) {
+ curmove (cturn == -1? 18: 19,39);
+ ist = -1;
+ goto domove;
+ } else {
+ proll ();
+ ist = 0;
+ goto domove;
+ }
+ }
+
+ if (c == tty.sg_erase && ncin > 0) {
+ if (tflag)
+ curmove (curr,curc-1);
+ else {
+ if (tty.sg_erase == '\010')
+ writel ("\010 \010");
+ else
+ writec (cin[ncin-1]);
+ }
+ ncin--;
+ n = rsetbrd();
+ if (n == 0) {
+ n = -1;
+ if (tflag)
+ refresh();
+ }
+ if ((ist = n) > 0)
+ goto dochar;
+ goto domove;
+ }
+
+ if (c == tty.sg_kill && ncin > 0) {
+ if (tflag) {
+ refresh();
+ curmove (curr,39);
+ ist = -1;
+ goto domove;
+ } else if (tty.sg_erase == '\010') {
+ for (j = 0; j < ncin; j++)
+ writel ("\010 \010");
+ ist = -1;
+ goto domove;
+ } else {
+ writec ('\\');
+ writec ('\n');
+ proll ();
+ ist = 0;
+ goto domove;
+ }
+ }
+
+ n = dotable(c,ist);
+ if (n >= 0) {
+ cin[ncin++] = c;
+ if (n > 2)
+ if ((! tflag) || c != '\n')
+ writec (c);
+ ist = n;
+ if (n)
+ goto dochar;
+ else
+ goto domove;
+ }
+
+ if (n == -1 && mvl >= mvlim)
+ return(0);
+ if (n == -1 && mvl < mvlim-1)
+ return(-4);
+
+ if (n == -6) {
+ if (! tflag) {
+ if (movokay(mvl+1)) {
+ wrboard();
+ movback (mvl+1);
+ }
+ proll ();
+ writel ("\t\tMove: ");
+ for (j = 0; j < ncin;)
+ writec (cin[j++]);
+ } else {
+ if (movokay(mvl+1)) {
+ refresh();
+ movback (mvl+1);
+ } else
+ curmove (cturn == -1? 18:19,ncin+39);
+ }
+ ist = n = rsetbrd();
+ goto dochar;
+ }
+
+ if (n != -5)
+ return(n);
+ writec ('\007');
+ goto dochar;
+}
+
+dotable (c,i)
+char c;
+register int i;
+
+{
+ register int a, j;
+ int test;
+
+ test = (c == 'R');
+
+ while ( (a = atmata[i].ch) != '.') {
+ if (a == c || (test && a == '\n')) {
+ switch (atmata[i].fcode) {
+
+ case 1:
+ wrboard();
+ if (tflag) {
+ curmove (cturn == -1? 18: 19,0);
+ proll ();
+ writel ("\t\t");
+ } else
+ proll ();
+ break;
+
+ case 2:
+ if (p[mvl] == -1)
+ p[mvl] = c-'0';
+ else
+ p[mvl] = p[mvl]*10+c-'0';
+ break;
+
+ case 3:
+ if (g[mvl] != -1) {
+ if (mvl < mvlim)
+ mvl++;
+ p[mvl] = p[mvl-1];
+ }
+ g[mvl] = p[mvl]+cturn*(c-'0');
+ if (g[mvl] < 0)
+ g[mvl] = 0;
+ if (g[mvl] > 25)
+ g[mvl] = 25;
+ break;
+
+ case 4:
+ if (g[mvl] == -1)
+ g[mvl] = c-'0';
+ else
+ g[mvl] = g[mvl]*10+c-'0';
+ break;
+
+ case 5:
+ if (mvl < mvlim)
+ mvl++;
+ p[mvl] = g[mvl-1];
+ break;
+
+ case 6:
+ if (mvl < mvlim)
+ mvl++;
+ break;
+
+ case 7:
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ text (help2);
+ if (tflag) {
+ curmove (cturn == -1? 18: 19,39);
+ } else {
+ writec ('\n');
+ proll();
+ writel ("\t\tMove: ");
+ }
+ break;
+
+ case 8:
+ p[mvl] = bar;
+ break;
+
+ case 9:
+ g[mvl] = home;
+ }
+
+ if (! test || a != '\n')
+ return (atmata[i].newst);
+ else
+ return (-6);
+ }
+
+ i++;
+ }
+
+ return (-5);
+}
+
+rsetbrd () {
+ register int i, j, n;
+
+ n = 0;
+ mvl = 0;
+ for (i = 0; i < 4; i++)
+ p[i] = g[i] = -1;
+ for (j = 0; j < ncin; j++)
+ n = dotable (cin[j],n);
+ return (n);
+}
diff --git a/backgammon/teachgammon/Makefile b/backgammon/teachgammon/Makefile
new file mode 100644
index 00000000..b57ab045
--- /dev/null
+++ b/backgammon/teachgammon/Makefile
@@ -0,0 +1,15 @@
+# @(#)Makefile 5.1 (Berkeley) 5/11/90
+
+PROG= teachgammon
+CFLAGS+=-DV7 -I${.CURDIR}/../common_source
+SRCS= allow.c board.c check.c data.c fancy.c init.c odds.c one.c save.c \
+ subs.c table.c teach.c ttext1.c ttext2.c tutor.c
+DPADD= ${LIBTERM} ${LIBCOMPAT}
+LDADD= -ltermcap -lcompat
+HIDEGAME=hidegame
+NOMAN= noman
+
+.PATH: ${.CURDIR}/../common_source
+
+.include "../../Makefile.inc"
+.include <bsd.prog.mk>
diff --git a/backgammon/teachgammon/data.c b/backgammon/teachgammon/data.c
new file mode 100644
index 00000000..2f7b292a
--- /dev/null
+++ b/backgammon/teachgammon/data.c
@@ -0,0 +1,315 @@
+/*
+ * 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
+static char sccsid[] = "@(#)data.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "tutor.h"
+
+int maxmoves = 23;
+
+char *text0[] = {
+ "To start the game, I roll a 3, and you roll a 1. This means",
+ "that I get to start first. I move 8-5,6-5 since this makes a",
+ "new point and helps to trap your back men on 1. You should be",
+ "able to do a similar move with your roll.",
+ 0
+};
+
+char *text1[] = {
+ "Now you shall see a move using doubles. I just rolled double",
+ "5's. I will move two men from position 13 to position 3. The",
+ "notation for this is 13-8,13-8,8-3,8-3. You will also roll dou-",
+ "bles, but you will be able to make a much stronger move.",
+ 0
+};
+
+char *text2[] = {
+ "Excellent! As you can see, you are beginning to develop a wall",
+ "which is trapping my men on position 24. Also, moving your back",
+ "men forward not only improves your board position safely, but it",
+ "thwarts my effort to make a wall.",
+ "",
+ "My roll now is 5 6. Normally, I would use that roll to move from",
+ "position 24 to position 13 (24-18-13), but your new point prevents",
+ "that. Instead, I am forced to move from 13 to 2, where my man is",
+ "open but cannot be hit.",
+ 0
+};
+
+char *text3[] = {
+ "As you can see, although you left a man open, it is a rela-",
+ "tively safe move to an advantageous position, which might help",
+ "you make a point later. Only two rolls (4 5 or 5 4) will allow",
+ "me to hit you. With an unprecedented amount of luck, I happen",
+ "to roll a 4 5 and hit you as just mentioned.",
+ 0
+};
+
+char *text4[] = {
+ "You're pretty lucky yourself, you know. I follow by rolling 2 3",
+ "and moving 25-22,24-22, forming a new point.",
+ 0
+};
+
+char *text5[] = {
+ "Not a spectacular move, but a safe one. I follow by rolling 6 1.",
+ "I decide to use this roll to move 22-16,16-17. It leaves me with",
+ "one man still open, but the blot is farther back on the board, and",
+ "would suffer less of a loss by being hit.",
+ 0
+};
+
+char *text6[] = {
+ "By moving your two men from 17 to 20, you lessen my chance of",
+ "getting my man off the board. In fact, the odds are 5 to 4",
+ "against me getting off. I roll with the odds and helplessly",
+ "receive a 3 5.",
+ 0
+};
+
+char *text7[] = {
+ "Note that the blot on 7 cannot be hit unless I get off the bar",
+ "and have a 1 or a 6 left over, and doing so will leave two of",
+ "my men open. Also, the blot on 16 cannot be hit at all! With",
+ "a sigh of frustration, I roll double 6's and remain immobile.",
+ 0
+};
+
+char *text8[] = {
+ "See, you did not get hit and, you got to 'cover up' your open men.",
+ "Quite an accomplishment. Finally, I get off the bar by rolling",
+ "6 2 and moving 25-23,23-17.",
+ 0
+};
+
+char *text9[] = {
+ "My venture off the bar did not last long. However, I got lucky",
+ "and rolled double 1's, allowing me to move 0-1,1-2,15-14,15-14.",
+ 0
+};
+
+char *text10[] = {
+ "You are improving your position greatly and safely, and are well",
+ "on the way to winning the game. I roll a 6 2 and squeak past",
+ "your back man. Now the game becomes a race to the finish.",
+ 0
+};
+
+char *text11[] = {
+ "Now that it is merely a race, you are trying to get as many men",
+ "as possible into the inner table, so you can start removing them.",
+ "I roll a 3 4 and move my two men farthest back to position 11",
+ "(15-11,14-11).",
+ 0
+};
+
+char *text12[] = {
+ "The race is still on, and you have seem to be doing all right.",
+ "I roll 6 1 and move 14-8,13-12.",
+ 0
+};
+
+char *text13[] = {
+ "Notice that you get to remove men the instant you have all of",
+ "them at your inner table, even if it is the middle of a turn.",
+ "I roll 1 2 and move 13-11,12-11.",
+ 0
+};
+
+char *text14[] = {
+ "Although you could have removed a man, this move illustrates two",
+ "points: 1) You never have to remove men, and 2) You should try",
+ "to spread out your men on your inner table. Since you have one",
+ "man on each position, you should be able to remove at least two",
+ "men next turn. I roll 2 5 and move 8-6,11-6.",
+ 0
+};
+
+char *text15[] = {
+ "This time you were able to remove men. I roll 3 4 and move",
+ "11-7,11-8. The race continues.",
+ 0
+};
+
+char *text16[] = {
+ "More holes are opening up in your inner table, but you are",
+ "still very much ahead. If we were doubling, you would have",
+ "doubled long ago. I roll 2 6 and move 8-6,11-5.",
+ 0
+};
+
+char *text17[] = {
+ "It pays to spread out your men. I roll 3 5 and move 7-4,8-3.",
+ 0
+};
+
+char *text18[] = {
+ "You can only remove some men, but you spread out more and",
+ "more, in order to be able to remove men more efficiently.",
+ "I roll double 3's, which help, but not that much. I move",
+ "8-5,3-0,3-0,3-0.",
+ 0
+};
+
+char *text19[] = {
+ "I roll 1 4 and move 5-4,4-0.",
+ 0
+};
+
+char *text20[] = {
+ "You are now nicely spread out to win a game. I roll 5 6 and",
+ "move 5-0,6-0.",
+ 0
+};
+
+char *text21[] = {
+ "Any minute now. Just a few short steps from victory. I roll",
+ "2 4 and move 6-4,4-0.",
+ 0
+};
+
+char *text22[] = {
+ "It looks pretty hopeless for me, but I play on, rolling 1 3 and",
+ "moving 4-3,3-0.",
+ 0
+};
+
+char *text23[] = {
+ "Congratulations! You just won a game of backgammon against the",
+ "computer! You will now be able to play a game, but remember,",
+ "when you start playing, that doubling will be enabled, which",
+ "will add another factor to the game... Good luck!!",
+ "",
+ 0
+};
+
+struct situatn test[] = {
+ {
+ {0,2,0,0,0,0,-5,0,-3,0,0,0,5,-5,0,0,0,3,0,5,0,0,0,0,-2,0},
+ 3, 1, {8,6,0,0}, {5,5,0,0}, 4, 2, text0
+ },
+ {
+ {0,2,0,0,0,-2,-4,0,-2,0,0,0,5,-5,0,0,0,2,0,4,0,2,0,0,-2,0},
+ 5, 5, {13,13,8,8}, {8,8,3,3}, 6, 6, text1
+ },
+ {
+ {0,0,0,-2,0,-2,-4,2,-2,0,0,0,3,-3,0,0,0,2,2,4,0,2,0,0,-2,0},
+ 6, 5, {13,8,0,0}, {8,2,0,0}, 1, 2, text2
+ },
+ {
+ {0,0,-1,-2,0,-2,-4,2,-2,0,0,0,2,-2,0,1,0,2,2,4,0,2,0,0,-2,0},
+ 4, 5, {24,20,0,0}, {20,15,0,0}, 2, 5, text3
+ },
+ {
+ {0,0,0,-2,0,-2,-4,3,-2,0,0,0,2,-2,0,-1,0,2,2,4,0,2,0,0,-1,-1},
+ 2, 3, {25,24,0,0}, {22,22,0,0}, 4, 1, text4
+ },
+ {
+ {0,0,0,-2,0,-2,-4,2,-2,0,0,0,3,-2,0,-1,0,2,2,4,0,2,-2,0,0,0},
+ 6, 1, {22,16,0,0}, {16,15,0,0}, 3, 3, text5
+ },
+ {
+ {0,0,0,-2,0,-2,-4,2,-2,0,0,0,3,-2,0,-2,0,0,2,2,2,2,2,0,0,-1},
+ 3, 5, {0,0,0,0}, {0,0,0,0}, 5, 4, text6
+ },
+ {
+ {0,0,0,-2,0,-2,-4,1,-2,0,0,0,3,-2,0,-2,1,0,2,2,2,2,2,0,0,-1},
+ 6, 6, {0,0,0,0}, {0,0,0,0}, 3, 6, text7
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-2,0,0,0,3,-2,0,-2,2,0,2,2,2,2,2,0,0,-1},
+ 2, 6, {25,23,0,0}, {23,17,0,0}, 5, 1, text8
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-2,0,0,0,2,-2,0,-2,2,0,3,2,2,2,2,0,0,-1},
+ 1, 1, {25,24,15,15}, {24,23,14,14}, 4, 6, text9
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-2,0,0,0,0,-2,-2,0,3,0,4,2,2,2,2,-1,0,0},
+ 6, 2, {23,17,0,0}, {17,15,0,0}, 1, 3, text10
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-2,0,0,0,0,-2,-2,-1,2,0,3,4,2,2,2,0,0,0},
+ 4, 3, {15,14,0,0}, {11,11,0,0}, 5, 3, text11
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-2,0,0,-2,0,-2,-1,0,0,0,3,5,2,3,2,0,0,0},
+ 6, 1, {14,13,0,0}, {8,12,0,0}, 4, 4, text12
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-3,0,0,-2,-1,-1,0,0,0,0,0,5,2,2,5,0,0,0},
+ 2, 1, {13,12,0,0}, {11,11,0,0}, 2, 1, text13
+ },
+ {
+ {0,0,0,-2,0,-2,-4,0,-3,0,0,-4,0,0,0,0,0,0,0,5,2,2,3,1,1,0},
+ 2, 5, {8,11,0,0}, {6,6,0,0}, 6, 3, text14
+ },
+ {
+ {0,0,0,-2,0,-2,-6,0,-2,0,0,-3,0,0,0,0,0,0,0,4,2,2,2,1,1,0},
+ 4, 3, {11,11,0,0}, {7,8,0,0}, 2, 5, text15
+ },
+ {
+ {0,0,0,-2,0,-2,-6,-1,-3,0,0,-1,0,0,0,0,0,0,0,4,1,2,2,0,1,0},
+ 2, 6, {8,11,0,0}, {6,5,0,0}, 6, 1, text16
+ },
+ {
+ {0,0,0,-2,0,-3,-7,-1,-2,0,0,0,0,0,0,0,0,0,0,3,1,2,2,0,0,0},
+ 5, 3, {8,7,0,0}, {3,4,0,0}, 5, 2, text17
+ },
+ {
+ {0,0,0,-3,-1,-3,-7,0,-1,0,0,0,0,0,0,0,0,0,0,3,0,1,2,1,0,0},
+ 3, 3, {8,3,3,3}, {5,0,0,0}, 1, 6, text18
+ },
+ {
+ {0,0,0,0,-1,-4,-7,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,1,0,0},
+ 1, 4, {4,5,0,0}, {0,4,0,0}, 2, 3, text19
+ },
+ {
+ {0,0,0,0,-1,-3,-7,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0},
+ 5, 6, {6,5,0,0}, {0,0,0,0}, 1, 4, text20
+ },
+ {
+ {0,0,0,0,-1,-2,-6,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0},
+ 2, 4, {4,6,0,0}, {0,4,0,0}, 6, 2, text21
+ },
+ {
+ {0,0,0,0,-1,-2,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0},
+ 3, 1, {4,3,0,0}, {3,0,0,0}, 4, 3, text22
+ },
+ {
+ {0,0,0,0,0,-2,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ 0, 0, {0,0,0,0}, {0,0,0,0}, 0, 0, text23
+ }
+};
diff --git a/backgammon/teachgammon/teach.c b/backgammon/teachgammon/teach.c
new file mode 100644
index 00000000..18528d05
--- /dev/null
+++ b/backgammon/teachgammon/teach.c
@@ -0,0 +1,166 @@
+/*
+ * 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[] = "@(#)teach.c 5.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *hello[];
+char *list[];
+char *intro1[];
+char *intro2[];
+char *moves[];
+char *remove[];
+char *hits[];
+char *endgame[];
+char *doubl[];
+char *stragy[];
+char *prog[];
+char *lastch[];
+
+extern char ospeed; /* tty output speed for termlib */
+
+char *helpm[] = {
+ "\nEnter a space or newline to roll, or",
+ " b to display the board",
+ " d to double",
+ " q to quit\n",
+ 0
+};
+
+char *contin[] = {
+ "",
+ 0
+};
+
+main (argc,argv)
+int argc;
+char **argv;
+
+{
+ register int i;
+
+ signal (2,getout);
+ if (gtty (0,&tty) == -1) /* get old tty mode */
+ errexit ("teachgammon(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 */
+ tflag = getcaps (getenv ("TERM"));
+#ifdef V7
+ while (*++argv != 0)
+#else
+ while (*++argv != -1)
+#endif
+ getarg (&argv);
+ if (tflag) {
+ noech &= ~(CRMOD|XTABS);
+ raw &= ~(CRMOD|XTABS);
+ clear();
+ }
+ text (hello);
+ text (list);
+ i = text (contin);
+ if (i == 0)
+ i = 2;
+ init();
+ while (i)
+ switch (i) {
+
+ case 1:
+ leave();
+
+ case 2:
+ if (i = text(intro1))
+ break;
+ wrboard();
+ if (i = text(intro2))
+ break;
+
+ case 3:
+ if (i = text(moves))
+ break;
+
+ case 4:
+ if (i = text(remove))
+ break;
+
+ case 5:
+ if (i = text(hits))
+ break;
+
+ case 6:
+ if (i = text(endgame))
+ break;
+
+ case 7:
+ if (i = text(doubl))
+ break;
+
+ case 8:
+ if (i = text(stragy))
+ break;
+
+ case 9:
+ if (i = text(prog))
+ break;
+
+ case 10:
+ if (i = text(lastch))
+ break;
+ }
+ tutor();
+}
+
+leave() {
+ if (tflag)
+ clear();
+ else
+ writec ('\n');
+ fixtty(old);
+ execl (EXEC,"backgammon",args,"n",0);
+ writel ("Help! Backgammon program is missing\007!!\n");
+ exit (-1);
+}
diff --git a/backgammon/teachgammon/ttext1.c b/backgammon/teachgammon/ttext1.c
new file mode 100644
index 00000000..adf4cc1a
--- /dev/null
+++ b/backgammon/teachgammon/ttext1.c
@@ -0,0 +1,184 @@
+/*
+ * 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
+static char sccsid[] = "@(#)ttext1.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *opts = " QIMRHEDSPT";
+char *prompt = "-->";
+
+char *list[] = {
+ "\n\n\tI\tIntroduction to Backgammon",
+ "\tM\tMoves and Points",
+ "\tR\tRemoving Men from the Board",
+ "\tH\tHitting Blots",
+ "\tE\tEnding the Game and Scoring",
+ "\tD\tDoubling",
+ "\tS\tStrategy",
+ "\tP\tThe Program and How to Use It",
+ "\nalso, you can type:",
+ "\t?\tto get this list",
+ "\tQ\tto go start playing",
+ "\tT\tto go straight to the tutorial",
+ 0
+};
+
+char *hello[] = {
+ "\n\032 These rules consist of text describing how to play Backgammon",
+ "followed by a tutorial session where you play a practice game",
+ "against the computer. When using this program, think carefuly",
+ "before typing, since it reacts as soon as you type something. In",
+ "addition, the program presents text output, such as these rules,",
+ "in small blocks that will not roll off the top of the screen.",
+ "Frequently, you will see the characters '-->' indicating that the",
+ "program is waiting for you to finish reading, and will continue",
+ "printing when you type a space or newline. Also, the rules are",
+ "divided into sections, and although you should read them in or-",
+ "der, you can go directly to any of them by typing one of the fol-",
+ "lowing letters:",
+ "(Remember to hit a space or a newline to continue.)",
+ "",
+ 0
+};
+
+char *intro1[] = {
+ "\nIntroduction:",
+ "\n Backgammon is a game involving the skill of two players and",
+ "the luck of two dice. There are two players, red and white, and",
+ "each player gets fifteen men. The object of the game is to re-",
+ "move all your men from the board before the opponent does. The",
+ "board consists of twenty-four positions, a 'bar' and a 'home' for",
+ "each player. It looks like this:",
+ "",
+ 0};
+
+char *intro2[] = {
+ "",
+ "\n Although not indicated on the board, the players' homes are",
+ "located just to the right of the board. A player's men are placed",
+ "there when they are removed from the board. The board you just",
+ "saw was in it's initial position. All games start with the board",
+ "looking like this. Notice that red's pieces are represented by the",
+ "letter 'r' and white's pieces are represented by the letter 'w'.",
+ "Also, a position may have zero or more pieces on it, e.g. posi-",
+ "tion 12 has five red pieces on it, while position 11 does not",
+ "have any pieces of either color.",
+ "",
+ 0};
+
+char *moves[] = {
+ "\nMoves and Points:",
+ "\n Moves are made along the positions on the board according to",
+ "their numbers. Red moves in the positive direction (clockwise",
+ "from 1 to 24), and white moves in the negative direction (coun-",
+ "terclockwise from 24 to 1).",
+ "\n A turn consists of rolling the dice, and moving the number of",
+ "positions indicated on each die. The two numbers can be used to",
+ "move one man the sum of the two rolls, or two men the number on",
+ "each individual die. For example, if red rolled 6 3 at the start",
+ "of the game, he might move a man from 1 to 7 to 10, using both",
+ "dice for one man, or he might move two men from position 12, one",
+ "to 15 and one to 18. (Red did not have to choose two men start-",
+ "ing from the same position.) In addition, doubles are treated",
+ "specially in backgammon. When a player rolls doubles, he gets to",
+ "move as if he had four dice instead of two. For instance, if you",
+ "rolled double 2's, you could move one man eight positions, four",
+ "men two positions each, or any permutation in between.",
+ "",
+ "\n However, there are certain limitations, called 'points.' A",
+ "player has a point when he has two or more men on the same posi-",
+ "tion. This gives him custody of that position, and his opponent",
+ "cannot place his men there, even if passing through on the way to",
+ "another position. When a player has six points in a row, it is",
+ "called a 'wall,' since any of his opponent's men behind the wall",
+ "cannot pass it and are trapped, at least for the moment. Notice",
+ "that this could mean that a player could not use part or all of",
+ "his roll. However, he must use as much of his roll as possible.",
+ "",
+ 0};
+
+char *remove[] = {
+ "\nRemoving Men from the Board:",
+ "\n The most important part of the game is removing men, since",
+ "that is how you win the game. Once a man is removed, he stays",
+ "off the board for the duration of the game. However, a player",
+ "cannot remove men until all his men are on his 'inner table,' or",
+ "the last six positions of the board (19-24 for red, 6-1 for",
+ "white).",
+ "\n To get off the board, a player must roll the exact number to",
+ "get his man one position past the last position on the board, or",
+ "his 'home.' Hence, if red wanted to remove a man from position",
+ "23, he would have to roll a 2, anything else would be used for",
+ "another man, or for another purpose. However, there is one ex-",
+ "ception. If the player rolling has no men far enough to move the",
+ "roll made, he may move his farthest man off the board. For exam-",
+ "ple, if red's farthest man back was on position 21, he could re-",
+ "move men from that position if he rolled a 5 or a 6, as well as a",
+ "4. Since he does not have men on 20 (where he could use a 5) or",
+ "on 19 (where he could use a 6), he can use these rolls for posi-",
+ "tion 21. A player never has to remove men, but he must make as",
+ "many moves as possible.",
+ "",
+ 0};
+
+char *hits[] = {
+ "\nHitting Blots:",
+ "\n Although two men on a position form an impenetrable point, a",
+ "lone man is not so secure. Such a man is called a 'blot' and has",
+ "the potential of getting hit by an opposing man. When a player's",
+ "blot is hit, he is placed on the bar, and the first thing that",
+ "player must do is move the man off the bar. Such moves are",
+ "counted as if the bar is one position behind the first position",
+ "on the board. Thus if red has a man on the bar and rolls 2 3, he",
+ "must move the man on the bar to position 2 or 3 before moving any",
+ "other man. If white had points on positions 2 and 3, then red",
+ "would forfeit his turn. Being on the bar is a very bad position,",
+ "for often a player can lose many turns trying to move off the",
+ "bar, as well as being set back the full distance of the board.",
+ "",
+ 0};
+
+char *endgame[] = {
+ "\nEnding the Game and Scoring:",
+ "\n Winning a game usually wins one point, the normal value of a",
+ "game. However, if the losing player has not removed any men yet,",
+ "then the winning player wins double the game value, called a",
+ "'gammon.' If the losing player has a player on the bar or on the",
+ "winner's inner table, then the winner gets triple the game value,",
+ "which is called a 'backgammon.' (So that's where the name comes",
+ "from!)",
+ "",
+ 0};
diff --git a/backgammon/teachgammon/ttext2.c b/backgammon/teachgammon/ttext2.c
new file mode 100644
index 00000000..a1279b12
--- /dev/null
+++ b/backgammon/teachgammon/ttext2.c
@@ -0,0 +1,193 @@
+/*
+ * 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
+static char sccsid[] = "@(#)ttext2.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *prompt, *list, *opts;
+
+char *doubl[] = {
+ "\nDoubling:",
+ "\n If a player thinks he is in a good position, he may double the",
+ "value of the game. However, his opponent may not accept the pro-",
+ "posal and forfeit the game before the price gets too high. A",
+ "player must double before he rolls, and once his double has been",
+ "accepted, he cannot double again, until his opponent has doubled.",
+ "Thus, unless the game swings back and forth in advantage between",
+ "the two players a great deal, the value of the game should be",
+ "low. At any rate, the value of the game will never go above 64,",
+ "or six doubles. However, if a player wins a backgammon at 64",
+ "points, he wins 192 points!",
+ "",
+ 0};
+
+char *stragy[] = {
+ "\nStrategy:",
+ "\n Some general hints when playing: Try not to leave men open",
+ "unless absolutely necessary. Also, it is good to make as many",
+ "points as possible. Often, two men from different positions can",
+ "be brought together to form a new point. Although walls (six",
+ "points in a row) are difficult to form, many points nestled close-",
+ "ly together produce a formidable barrier. Also, while it is good",
+ "to move back men forward, doing so lessens the opportunity for you",
+ "to hit men. Finally, remember that once the two player's have",
+ "passed each other on the board, there is no chance of either team",
+ "being hit, so the game reduces to a race off the board. Addi-",
+ "tional hints on strategy are presented in the practice game.",
+ "",
+ 0};
+
+char *prog[] = {
+ "\nThe Program and How It Works:",
+ "\n A general rule of thumb is when you don't know what to do,",
+ "type a question mark, and you should get some help. When it is",
+ "your turn, only your color will be printed out, with nothing",
+ "after it. You may double by typing a 'd', but if you type a",
+ "space or newline, you will get your roll. (Remember, you must",
+ "double before you roll.) Also, typing a 'r' will reprint the",
+ "board, and a 'q' will quit the game. The program will type",
+ "'Move:' when it wants your move, and you may indicate each die's",
+ "move with <s>-<f>, where <s> is the starting position and <f> is",
+ "the finishing position, or <s>/<r> where <r> is the roll made.",
+ "<s>-<f1>-<f2> is short for <s>-<f1>,<f1>-<f2> and <s>/<r1><r2> is",
+ "short for <s>/<r1>,<s>/<r2>. Moves may be separated by a comma",
+ "or a space.",
+ "",
+ "\n While typing, any input which does not make sense will not be",
+ "echoed, and a bell will sound instead. Also, backspacing and",
+ "killing lines will echo differently than normal. You may examine",
+ "the board by typing a 'r' if you have made a partial move, or be-",
+ "fore you type a newline, to see what the board looks like. You",
+ "must end your move with a newline. If you cannot double, your",
+ "roll will always be printed, and you will not be given the oppor-",
+ "tunity to double. Home and bar are represented by the appropri-",
+ "ate number, 0 or 25 as the case may be, or by the letters 'h' or",
+ "'b' as appropriate. You may also type 'r' or 'q' when the program",
+ "types 'Move:', which has the same effect as above. Finally, you",
+ "will get to decide if you want to play red or white (or both if you",
+ "want to play a friend) at the beginning of the session, and you",
+ "will not get to change your mind later, since the computer keeps",
+ "score.",
+ "",
+ 0};
+
+char *lastch[] = {
+ "\nTutorial (Practice Game):",
+ "\n This tutorial, for simplicity's sake, will let you play one",
+ "predetermined game. All the rolls have been pre-arranged, and",
+ "only one response will let you advance to the next move.",
+ "Although a given roll will may have several legal moves, the tu-",
+ "torial will only accept one (not including the same moves in a",
+ "different order), claiming that that move is 'best.' Obviously,",
+ "a subjective statement. At any rate, be patient with it and have",
+ "fun learning about backgammon. Also, to speed things up a lit-",
+ "tle, doubling will not take place in the tutorial, so you will",
+ "never get that opportunity, and quitting only leaves the tutori-",
+ "al, not the game. You will still be able to play backgammon",
+ "after quitting.",
+ "\n This is your last chance to look over the rules before the tu-",
+ "torial starts.",
+ "",
+ 0};
+
+text (txt)
+char **txt;
+
+{
+ char **begin;
+ char *a;
+ char b;
+ char *c;
+ int i;
+
+ fixtty (noech);
+ begin = txt;
+ while (*txt) {
+ a = *(txt++);
+ if (*a != '\0') {
+ c = a;
+ for (i = 0; *(c++) != '\0'; i--);
+ writel (a);
+ writec ('\n');
+ } else {
+ fixtty (raw);
+ writel (prompt);
+ for (;;) {
+ if ((b = readc()) == '?') {
+ if (tflag) {
+ if (begscr) {
+ curmove (18,0);
+ clend();
+ } else
+ clear();
+ } else
+ writec ('\n');
+ text (list);
+ writel (prompt);
+ continue;
+ }
+ i = 0;
+ if (b == '\n')
+ break;
+ while (i < 11) {
+ if (b == opts[i])
+ break;
+ i++;
+ }
+ if (i == 11)
+ writec ('\007');
+ else
+ break;
+ }
+ if (tflag) {
+ if (begscr) {
+ curmove (18,0);
+ clend();
+ } else
+ clear();
+ } else
+ writec ('\n');
+ if (i)
+ return(i);
+ fixtty (noech);
+ if (tflag)
+ curmove (curr,0);
+ begin = txt;
+ }
+ }
+ fixtty (raw);
+ return (0);
+}
diff --git a/backgammon/teachgammon/tutor.c b/backgammon/teachgammon/tutor.c
new file mode 100644
index 00000000..2c96308c
--- /dev/null
+++ b/backgammon/teachgammon/tutor.c
@@ -0,0 +1,155 @@
+/*
+ * 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
+static char sccsid[] = "@(#)tutor.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+#include "tutor.h"
+
+extern int maxmoves;
+extern char *finis[];
+
+extern struct situatn test[];
+
+static char better[] = "That is a legal move, but there is a better one.\n";
+
+tutor () {
+ register int i, j;
+
+ i = 0;
+ begscr = 18;
+ cturn = -1;
+ home = 0;
+ bar = 25;
+ inptr = &in[0];
+ inopp = &in[1];
+ offptr = &off[0];
+ offopp = &off[1];
+ Colorptr = &color[0];
+ colorptr = &color[2];
+ colen = 5;
+ wrboard();
+
+ while (1) {
+ if (! brdeq(test[i].brd,board)) {
+ if (tflag && curr == 23)
+ curmove (18,0);
+ writel (better);
+ nexturn();
+ movback (mvlim);
+ if (tflag) {
+ refresh();
+ clrest ();
+ }
+ if ((! tflag) || curr == 19) {
+ proll();
+ writec ('\t');
+ }
+ else
+ curmove (curr > 19? curr-2: curr+4,25);
+ getmove();
+ if (cturn == 0)
+ leave();
+ continue;
+ }
+ if (tflag)
+ curmove (18,0);
+ text (*test[i].com);
+ if (! tflag)
+ writec ('\n');
+ if (i == maxmoves)
+ break;
+ D0 = test[i].roll1;
+ D1 = test[i].roll2;
+ d0 = 0;
+ mvlim = 0;
+ for (j = 0; j < 4; j++) {
+ if (test[i].mp[j] == test[i].mg[j])
+ break;
+ p[j] = test[i].mp[j];
+ g[j] = test[i].mg[j];
+ mvlim++;
+ }
+ if (mvlim)
+ for (j = 0; j < mvlim; j++)
+ if (makmove(j))
+ writel ("AARGH!!!\n");
+ if (tflag)
+ refresh();
+ nexturn();
+ D0 = test[i].new1;
+ D1 = test[i].new2;
+ d0 = 0;
+ i++;
+ mvlim = movallow();
+ if (mvlim) {
+ if (tflag)
+ clrest();
+ proll();
+ writec('\t');
+ getmove();
+ if (tflag)
+ refresh();
+ if (cturn == 0)
+ leave();
+ }
+ }
+ leave();
+}
+
+clrest () {
+ register int r, c, j;
+
+ r = curr;
+ c = curc;
+ for (j = r+1; j < 24; j++) {
+ curmove (j,0);
+ cline();
+ }
+ curmove (r,c);
+}
+
+brdeq (b1,b2)
+register int *b1, *b2;
+
+{
+ register int *e;
+
+ e = b1+26;
+ while (b1 < e)
+ if (*b1++ != *b2++)
+ return(0);
+ return(1);
+}
diff --git a/backgammon/teachgammon/tutor.h b/backgammon/teachgammon/tutor.h
new file mode 100644
index 00000000..6bd1cf87
--- /dev/null
+++ b/backgammon/teachgammon/tutor.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ *
+ * @(#)tutor.h 5.4 (Berkeley) 6/1/90
+ */
+
+struct situatn {
+ int brd[26];
+ int roll1;
+ int roll2;
+ int mp[4];
+ int mg[4];
+ int new1;
+ int new2;
+ char *(*com[8]);
+};