From 77e3814f0c0e3dea4d0032e25666f77e6f83bfff Mon Sep 17 00:00:00 2001 From: cgd Date: Sun, 21 Mar 1993 09:45:37 +0000 Subject: initial import of 386bsd-0.1 sources --- backgammon/Makefile | 5 + backgammon/backgammon/Makefile | 14 + backgammon/backgammon/backgammon.6 | 205 ++++++++++ backgammon/backgammon/extra.c | 253 ++++++++++++ backgammon/backgammon/main.c | 591 ++++++++++++++++++++++++++ backgammon/backgammon/move.c | 551 +++++++++++++++++++++++++ backgammon/backgammon/text.c | 132 ++++++ backgammon/backgammon/version.c | 41 ++ backgammon/common_source/allow.c | 109 +++++ backgammon/common_source/back.h | 127 ++++++ backgammon/common_source/backgammon.c | 751 ++++++++++++++++++++++++++++++++++ backgammon/common_source/board.c | 176 ++++++++ backgammon/common_source/check.c | 158 +++++++ backgammon/common_source/fancy.c | 748 +++++++++++++++++++++++++++++++++ backgammon/common_source/init.c | 65 +++ backgammon/common_source/odds.c | 113 +++++ backgammon/common_source/one.c | 169 ++++++++ backgammon/common_source/save.c | 180 ++++++++ backgammon/common_source/subs.c | 477 +++++++++++++++++++++ backgammon/common_source/table.c | 308 ++++++++++++++ backgammon/teachgammon/Makefile | 15 + backgammon/teachgammon/data.c | 315 ++++++++++++++ backgammon/teachgammon/teach.c | 166 ++++++++ backgammon/teachgammon/ttext1.c | 184 +++++++++ backgammon/teachgammon/ttext2.c | 193 +++++++++ backgammon/teachgammon/tutor.c | 155 +++++++ backgammon/teachgammon/tutor.h | 45 ++ 27 files changed, 6246 insertions(+) create mode 100644 backgammon/Makefile create mode 100644 backgammon/backgammon/Makefile create mode 100644 backgammon/backgammon/backgammon.6 create mode 100644 backgammon/backgammon/extra.c create mode 100644 backgammon/backgammon/main.c create mode 100644 backgammon/backgammon/move.c create mode 100644 backgammon/backgammon/text.c create mode 100644 backgammon/backgammon/version.c create mode 100644 backgammon/common_source/allow.c create mode 100644 backgammon/common_source/back.h create mode 100644 backgammon/common_source/backgammon.c create mode 100644 backgammon/common_source/board.c create mode 100644 backgammon/common_source/check.c create mode 100644 backgammon/common_source/fancy.c create mode 100644 backgammon/common_source/init.c create mode 100644 backgammon/common_source/odds.c create mode 100644 backgammon/common_source/one.c create mode 100644 backgammon/common_source/save.c create mode 100644 backgammon/common_source/subs.c create mode 100644 backgammon/common_source/table.c create mode 100644 backgammon/teachgammon/Makefile create mode 100644 backgammon/teachgammon/data.c create mode 100644 backgammon/teachgammon/teach.c create mode 100644 backgammon/teachgammon/ttext1.c create mode 100644 backgammon/teachgammon/ttext2.c create mode 100644 backgammon/teachgammon/tutor.c create mode 100644 backgammon/teachgammon/tutor.h (limited to 'backgammon') 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 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 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 +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 +#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 +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 -, where is the starting position, and 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 / where is the", + "starting position, an 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 / format as by", + "entering more than one , 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 + +#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 + +#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, " 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(n1){ + nn=n; + n=0; + prob=32000; + for(k = 0; k < nn; k++){ + if((moveval=probmoves[k]) > prob) + continue; + if(moveval>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(player6) { + 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 + +/* + * 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 +#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 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 - or / where is the starting", + "position, is the finishing position, and 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 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 -, where is the starting position and is", + "the finishing position, or / where is the roll made.", + "-- is short for -,- and / is", + "short for /,/. 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]); +}; -- cgit v1.2.3-56-ge451