summaryrefslogtreecommitdiffstats
path: root/backgammon/common_source
diff options
context:
space:
mode:
authorcgd <cgd@NetBSD.org>1993-03-21 09:45:37 +0000
committercgd <cgd@NetBSD.org>1993-03-21 09:45:37 +0000
commit77e3814f0c0e3dea4d0032e25666f77e6f83bfff (patch)
tree7eddfcbf3dd12089e71dc3fafb0a106c5c5766c7 /backgammon/common_source
parente81d63576b2e46ab90da7d75fa155ea57ee4d32e (diff)
downloadbsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.tar.gz
bsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.zip
initial import of 386bsd-0.1 sources
Diffstat (limited to 'backgammon/common_source')
-rw-r--r--backgammon/common_source/allow.c109
-rw-r--r--backgammon/common_source/back.h127
-rw-r--r--backgammon/common_source/backgammon.c751
-rw-r--r--backgammon/common_source/board.c176
-rw-r--r--backgammon/common_source/check.c158
-rw-r--r--backgammon/common_source/fancy.c748
-rw-r--r--backgammon/common_source/init.c65
-rw-r--r--backgammon/common_source/odds.c113
-rw-r--r--backgammon/common_source/one.c169
-rw-r--r--backgammon/common_source/save.c180
-rw-r--r--backgammon/common_source/subs.c477
-rw-r--r--backgammon/common_source/table.c308
12 files changed, 3381 insertions, 0 deletions
diff --git a/backgammon/common_source/allow.c b/backgammon/common_source/allow.c
new file mode 100644
index 00000000..2a7c9e0d
--- /dev/null
+++ b/backgammon/common_source/allow.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)allow.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+movallow () {
+
+ register int i, m, iold;
+ int r;
+
+ if (d0)
+ swap;
+ m = (D0 == D1? 4: 2);
+ for (i = 0; i < 4; i++)
+ p[i] = bar;
+ i = iold = 0;
+ while (i < m) {
+ if (*offptr == 15)
+ break;
+ h[i] = 0;
+ if (board[bar]) {
+ if (i == 1 || m == 4)
+ g[i] = bar+cturn*D1;
+ else
+ g[i] = bar+cturn*D0;
+ if (r = makmove(i)) {
+ if (d0 || m == 4)
+ break;
+ swap;
+ movback (i);
+ if (i > iold)
+ iold = i;
+ for (i = 0; i < 4; i++)
+ p[i] = bar;
+ i = 0;
+ } else
+ i++;
+ continue;
+ }
+ if ((p[i] += cturn) == home) {
+ if (i > iold)
+ iold = i;
+ if (m == 2 && i) {
+ movback(i);
+ p[i--] = bar;
+ if (p[i] != bar)
+ continue;
+ else
+ break;
+ }
+ if (d0 || m == 4)
+ break;
+ swap;
+ movback (i);
+ for (i = 0; i < 4; i++)
+ p[i] = bar;
+ i = 0;
+ continue;
+ }
+ if (i == 1 || m == 4)
+ g[i] = p[i]+cturn*D1;
+ else
+ g[i] = p[i]+cturn*D0;
+ if (g[i]*cturn > home) {
+ if (*offptr >= 0)
+ g[i] = home;
+ else
+ continue;
+ }
+ if (board[p[i]]*cturn > 0 && (r = makmove(i)) == 0)
+ i++;
+ }
+ movback (i);
+ return (iold > i? iold: i);
+}
diff --git a/backgammon/common_source/back.h b/backgammon/common_source/back.h
new file mode 100644
index 00000000..5bab6e55
--- /dev/null
+++ b/backgammon/common_source/back.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)back.h 5.4 (Berkeley) 6/1/90
+ */
+
+#include <sgtty.h>
+
+#define rnum(r) (random()%r)
+#define D0 dice[0]
+#define D1 dice[1]
+#define swap {D0 ^= D1; D1 ^= D0; D0 ^= D1; d0 = 1-d0;}
+
+/*
+ *
+ * Some numerical conventions:
+ *
+ * Arrays have white's value in [0], red in [1].
+ * Numeric values which are one color or the other use
+ * -1 for white, 1 for red.
+ * Hence, white will be negative values, red positive one.
+ * This makes a lot of sense since white is going in decending
+ * order around the board, and red is ascending.
+ *
+ */
+
+char EXEC[]; /* object for main program */
+char TEACH[]; /* object for tutorial program */
+
+int pnum; /* color of player:
+ -1 = white
+ 1 = red
+ 0 = both
+ 2 = not yet init'ed */
+char args[100]; /* args passed to teachgammon and back */
+int acnt; /* length of args */
+int aflag; /* flag to ask for rules or instructions */
+int bflag; /* flag for automatic board printing */
+int cflag; /* case conversion flag */
+int hflag; /* flag for cleaning screen */
+int mflag; /* backgammon flag */
+int raflag; /* 'roll again' flag for recovered game */
+int rflag; /* recovered game flag */
+int tflag; /* cursor addressing flag */
+int rfl; /* saved value of rflag */
+int iroll; /* special flag for inputting rolls */
+int board[26]; /* board: negative values are white,
+ positive are red */
+int dice[2]; /* value of dice */
+int mvlim; /* 'move limit': max. number of moves */
+int mvl; /* working copy of mvlim */
+int p[5]; /* starting position of moves */
+int g[5]; /* ending position of moves (goals) */
+int h[4]; /* flag for each move if a man was hit */
+int cturn; /* whose turn it currently is:
+ -1 = white
+ 1 = red
+ 0 = just quitted
+ -2 = white just lost
+ 2 = red just lost */
+int d0; /* flag if dice have been reversed from
+ original position */
+int table[6][6]; /* odds table for possible rolls */
+int rscore; /* red's score */
+int wscore; /* white's score */
+int gvalue; /* value of game (64 max.) */
+int dlast; /* who doubled last (0 = neither) */
+int bar; /* position of bar for current player */
+int home; /* position of home for current player */
+int off[2]; /* number of men off board */
+int *offptr; /* pointer to off for current player */
+int *offopp; /* pointer to off for opponent */
+int in[2]; /* number of men in inner table */
+int *inptr; /* pointer to in for current player */
+int *inopp; /* pointer to in for opponent */
+
+int ncin; /* number of characters in cin */
+char cin[100]; /* input line of current move
+ (used for reconstructing input after
+ a backspace) */
+
+char *color[];
+ /* colors as strings */
+char **colorptr; /* color of current player */
+char **Colorptr; /* color of current player, capitalized */
+int colen; /* length of color of current player */
+
+struct sgttyb tty; /* tty information buffer */
+int old; /* original tty status */
+int noech; /* original tty status without echo */
+int raw; /* raw tty status, no echo */
+
+int curr; /* row position of cursor */
+int curc; /* column position of cursor */
+int begscr; /* 'beginning' of screen
+ (not including board) */
+
+int getout(); /* function to exit backgammon cleanly */
diff --git a/backgammon/common_source/backgammon.c b/backgammon/common_source/backgammon.c
new file mode 100644
index 00000000..036301f4
--- /dev/null
+++ b/backgammon/common_source/backgammon.c
@@ -0,0 +1,751 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)backgammon.c 5.1 (Berkeley) 4/8/91";
+#endif /* not lint */
+
+/*
+** The game of Backgammon
+*/
+
+#include <stdio.h>
+
+#define WHITE 0
+#define BROWN 1
+#define NIL (-1)
+#define MAXGMOV 10
+#define MAXIMOVES 1000
+#define RULES "/usr/games/lib/backrules"
+
+char level; /*'b'=beginner, 'i'=intermediate, 'e'=expert*/
+
+int die1;
+int die2;
+int i;
+int j;
+int l;
+int m;
+int pflg = 1;
+int nobroll = 0;
+int count;
+int imoves;
+int goodmoves[MAXGMOV];
+int probmoves[MAXGMOV];
+
+int brown[] = { /* brown position table */
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+int white[] = { /* white position table */
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+int probability[] = {
+ 0, 11, 12, 13, 14, 15, 16,
+ 06, 05, 04, 03, 02, 01
+};
+
+struct {
+ int pos[4];
+ int mov[4];
+} moves[MAXIMOVES];
+
+main()
+{
+ int go[5], tvec[2];
+ int k, n, pid, ret, rpid, t;
+ char s[100];
+
+ srand(time(0));
+ go[5] = NIL;
+ fprintf(stdout, "Instructions? ");
+ gets(s);
+ if(*s == 'y')
+ instructions();
+ putchar('\n');
+ fprintf(stdout, "Opponent's level: b - beginner,\n");
+ fprintf(stdout, "i - intermediate, e - expert? ");
+ level='e';
+ gets(s);
+ if(*s == 'b')
+ level = 'b';
+ else if(*s == 'i')
+ level = 'i';
+ putchar('\n');
+ fprintf(stdout, "You will play brown.\n\n");
+ fprintf(stdout, "Would you like to roll your own dice? ");
+ gets(s);
+ putchar('\n');
+ if(*s == 'y')
+ nobroll = 1;
+ fprintf(stdout, "Would you like to go first? ");
+ gets(s);
+ putchar('\n');
+ if(*s == 'y')
+ goto nowhmove;
+whitesmv:
+ roll(WHITE);
+ fprintf(stdout, "white rolls %d, %d\n", die1, die2);
+ fprintf(stdout, "white's move is:");
+ if(nextmove(white, brown) == NIL)
+ goto nowhmove;
+ if(piececount(white, 0, 24) == 0){
+ fprintf(stdout, "White wins");
+ if(piececount(brown, 0, 6) != 0)
+ fprintf(stdout, " with a Backgammon!\n");
+ else if (piececount(brown, 0, 24) == 24)
+ fprintf(stdout, " with a Gammon.\n");
+ else
+ fprintf(stdout, ".\n");
+ exit(0);
+ }
+nowhmove:
+ if(pflg)
+ prtbrd();
+ roll(BROWN);
+retry:
+ fprintf(stdout, "\nYour roll is %d %d\n", die1, die2);
+ fprintf(stdout, "Move? ");
+ gets(s);
+ switch(*s) {
+ case '\0': /* empty line */
+ fprintf(stdout, "Brown's move skipped.\n");
+ goto whitesmv;
+
+ case 'b': /* how many beared off? */
+ fprintf(stdout, "Brown: %d\n", piececount(brown, 0, 24) - 15);
+ fprintf(stdout, "White: %d\n", piececount(white, 0, 24) - 15);
+ goto retry;
+
+ case 'p': /* print board */
+ prtbrd();
+ goto retry;
+
+ case 's': /* stop auto printing of board */
+ pflg = 0;
+ goto retry;
+
+ case 'r': /* resume auto printing */
+ pflg = 1;
+ goto retry;
+
+ case 'm': /* print possible moves */
+ pmoves();
+ goto retry;
+
+ case 'q': /* i give up */
+ exit(0);
+
+ case '!': /* escape to Shell */
+ if(s[1] != '\0')
+ system(s+1);
+ else if((pid = fork()) == 0) {
+ execl("/bin/sh", "sh", "-", 0);
+ fprintf(stderr, "back: cannot exec /bin/sh!\n");
+ exit(2);
+ }
+ while((rpid = wait(&ret)) != pid && rpid != -1)
+ ;
+ goto retry;
+
+ case '?': /* well, what can i do? */
+ fprintf(stdout, "<newline> skip this move\n");
+ fprintf(stdout, "b number beared off\n");
+ fprintf(stdout, "p print board\n");
+ fprintf(stdout, "q quit\n");
+ fprintf(stdout, "r resume auto print of board\n");
+ fprintf(stdout, "s stop auto print of board\n");
+ fprintf(stdout, "! escape to Shell\n");
+ goto retry;
+ }
+ n = sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]);
+ if((die1 != die2 && n > 2) || n > 4){
+ fprintf(stdout, "Too many moves.\n");
+ goto retry;
+ }
+ go[n] = NIL;
+ if(*s=='-'){
+ go[0]= -go[0];
+ t=die1;
+ die1=die2;
+ die2=t;
+ }
+ for(k = 0; k < n; k++){
+ if(0 <= go[k] && go[k] <= 24)
+ continue;
+ else{
+ fprintf(stdout, "Move %d illegal.\n", go[k]);
+ goto retry;
+ }
+ }
+ if(play(brown, white, go))
+ goto retry;
+ if(piececount(brown, 0, 24) == 0){
+ fprintf(stdout, "Brown wins");
+ if(piececount(white, 0, 6) != 0)
+ fprintf(stdout, " with a Backgammon.\n");
+ else if(piececount(white, 0, 24) == 24)
+ fprintf(stdout, " with a gammon.\n");
+ else
+ fprintf(stdout, ".\n");
+ exit(0);
+ }
+ goto whitesmv;
+}
+
+play(player,playee,pos)
+int *player,*playee,pos[];
+{
+ int k, n, die, ipos;
+
+ for(k=0; k < player[0]; k++){ /*blots on player[0] must be moved first*/
+ if(pos[k] == NIL)
+ break;
+ if(pos[k] != 0){
+ fprintf(stdout, "Stone on bar must be moved first.\n");
+ return(NIL);
+ }
+ }
+ for(k = 0; (ipos=pos[k]) != NIL; k++){
+ die = k?die2:die1;
+ n = 25-ipos-die;
+ if(player[ipos] == 0)
+ goto badmove;
+ if(n > 0 && playee[n] >= 2)
+ goto badmove;
+ if(n <= 0){
+ if(piececount(player,0,18) != 0)
+ goto badmove;
+ if((ipos+die) != 25 && piececount(player,19,24-die)!=0)
+ goto badmove;
+ }
+ player[ipos]--;
+ player[ipos+die]++;
+ }
+ for(k = 0; pos[k] != NIL; k++){
+ die = k?die2:die1;
+ n = 25-pos[k]-die;
+ if(n>0 && playee[n]==1){
+ playee[n]=0;
+ playee[0]++;
+ }
+ }
+ return(0);
+
+badmove:
+ fprintf(stdout, "Move %d illegal.\n", ipos);
+ while(k--){
+ die=k?die2:die1;
+ player[pos[k]]++;
+ player[pos[k]+die]--;
+ }
+ return(NIL);
+}
+nextmove(player,playee)
+int *player,*playee;
+{
+ int k;
+
+ imoves=0;
+ movegen(player,playee);
+ if(die1!=die2){
+ k=die1;
+ die1=die2;
+ die2=k;
+ movegen(player,playee);
+ }
+ if(imoves==0){
+ fprintf(stdout, "no move possible.\n");
+ return(NIL);
+ }
+ k=strategy(player,playee); /*select kth possible move*/
+ prtmov(k);
+ update(player,playee,k);
+ return(0);
+}
+prtmov(k)
+int k;
+{
+ int n;
+
+ if(k == NIL)
+ fprintf(stdout, "No move possible\n");
+ else for(n = 0; n < 4; n++){
+ if(moves[k].pos[n] == NIL)
+ break;
+ fprintf(stdout, " %d, %d",25-moves[k].pos[n],moves[k].mov[n]);
+ }
+ fprintf(stdout, "\n");
+}
+update(player,playee,k)
+int *player,*playee,k;
+{
+ int n,t;
+
+ for(n = 0; n < 4; n++){
+ if(moves[k].pos[n] == NIL)
+ break;
+ player[moves[k].pos[n]]--;
+ player[moves[k].pos[n]+moves[k].mov[n]]++;
+ t=25-moves[k].pos[n]-moves[k].mov[n];
+ if(t>0 && playee[t]==1){
+ playee[0]++;
+ playee[t]--;
+ }
+ }
+}
+piececount(player,startrow,endrow)
+int *player,startrow,endrow;
+{
+ int sum;
+
+ sum=0;
+ while(startrow <= endrow)
+ sum += player[startrow++];
+ return(sum);
+}
+pmoves()
+{
+ int i1, i2;
+
+ fprintf(stdout, "Possible moves are:\n");
+ for(i1 = 0; i1 < imoves; i1++){
+ fprintf(stdout, "\n%d",i1);
+ for (i2 = 0; i2<4; i2++){
+ if(moves[i1].pos[i2] == NIL)
+ break;
+ fprintf(stdout, "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]);
+ }
+ }
+ fprintf(stdout, "\n");
+}
+
+roll(who)
+{
+ register n;
+ char s[10];
+
+ if(who == BROWN && nobroll) {
+ fprintf(stdout, "Roll? ");
+ gets(s);
+ n = sscanf(s, "%d%d", &die1, &die2);
+ if(n != 2 || die1 < 1 || die1 > 6 || die2 < 1 || die2 > 6)
+ fprintf(stdout, "Illegal - I'll do it!\n");
+ else
+ return;
+ }
+ die1 = ((rand()>>8) % 6) + 1;
+ die2 = ((rand()>>8) % 6) + 1;
+}
+
+movegen(mover,movee)
+int *mover,*movee;
+{
+ int k;
+
+ for(i = 0; i <= 24; i++){
+ count = 0;
+ if(mover[i] == 0)
+ continue;
+ if((k=25-i-die1) > 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover, 0, 18) != 0)
+ break;
+ if((i+die1) != 25 && piececount(mover,19,i-1) != 0)
+ break;
+ }
+ mover[i]--;
+ mover[i+die1]++;
+ count = 1;
+ for(j = 0; j <= 24; j++){
+ if(mover[j]==0)
+ continue;
+ if((k=25-j-die2) > 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover,0,18) != 0)
+ break;
+ if((j+die2) != 25 && piececount(mover,19,j-1) != 0)
+ break;
+ }
+ mover[j]--;
+ mover[j+die2]++;
+ count = 2;
+ if(die1 != die2){
+ moverecord(mover);
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ }
+ for(l = 0; l <= 24; l++){
+ if(mover[l] == 0)
+ continue;
+ if((k=25-l-die1) > 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover, 0, 18) != 0)
+ break;
+ if((l+die2) != 25 && piececount(mover,19,l-1) != 0)
+ break;
+ }
+ mover[l]--;
+ mover[l+die1]++;
+ count=3;
+ for(m=0;m<=24;m++){
+ if(mover[m]==0)
+ continue;
+ if((k=25-m-die1) >= 0 && movee[k] >= 2)
+ if(mover[0] > 0)
+ break;
+ else
+ continue;
+ if(k <= 0){
+ if(piececount(mover,0,18) != 0)
+ break;
+ if((m+die2) != 25 && piececount(mover,19,m-1) != 0)
+ break;
+ }
+ count=4;
+ moverecord(mover);
+ if(mover[0] > 0)
+ break;
+ }
+ if(count == 3)
+ moverecord(mover);
+ else{
+ mover[l]++;
+ mover[l+die1]--;
+ }
+ if(mover[0] > 0)
+ break;
+ }
+ if(count == 2)
+ moverecord(mover);
+ else{
+ mover[j]++;
+ mover[j+die1]--;
+ }
+ if(mover[0] > 0)
+ break;
+ }
+ if(count == 1)
+ moverecord(mover);
+ else{
+ mover[i]++;
+ mover[i+die1]--;
+ }
+ if(mover[0] > 0)
+ break;
+ }
+}
+moverecord(mover)
+int *mover;
+{
+ int t;
+
+ if(imoves < MAXIMOVES) {
+ for(t = 0; t <= 3; t++)
+ moves[imoves].pos[t] = NIL;
+ switch(count) {
+ case 4:
+ moves[imoves].pos[3]=m;
+ moves[imoves].mov[3]=die1;
+
+ case 3:
+ moves[imoves].pos[2]=l;
+ moves[imoves].mov[2]=die1;
+
+ case 2:
+ moves[imoves].pos[1]=j;
+ moves[imoves].mov[1]=die2;
+
+ case 1:
+ moves[imoves].pos[0]=i;
+ moves[imoves].mov[0]=die1;
+ imoves++;
+ }
+ }
+ switch(count) {
+ case 4:
+ break;
+
+ case 3:
+ mover[l]++;
+ mover[l+die1]--;
+ break;
+
+ case 2:
+ mover[j]++;
+ mover[j+die2]--;
+ break;
+
+ case 1:
+ mover[i]++;
+ mover[i+die1]--;
+ }
+}
+
+strategy(player,playee)
+int *player,*playee;
+{
+ int k, n, nn, bestval, moveval, prob;
+
+ n = 0;
+ if(imoves == 0)
+ return(NIL);
+ goodmoves[0] = NIL;
+ bestval = -32000;
+ for(k = 0; k < imoves; k++){
+ if((moveval=eval(player,playee,k,&prob)) < bestval)
+ continue;
+ if(moveval > bestval){
+ bestval = moveval;
+ n = 0;
+ }
+ if(n<MAXGMOV){
+ goodmoves[n]=k;
+ probmoves[n++]=prob;
+ }
+ }
+ if(level=='e' && n>1){
+ nn=n;
+ n=0;
+ prob=32000;
+ for(k = 0; k < nn; k++){
+ if((moveval=probmoves[k]) > prob)
+ continue;
+ if(moveval<prob){
+ prob=moveval;
+ n=0;
+ }
+ goodmoves[n]=goodmoves[k];
+ probmoves[n++]=probmoves[k];
+ }
+ }
+ return(goodmoves[(rand()>>4)%n]);
+}
+
+eval(player,playee,k,prob)
+int *player,*playee,k,*prob;
+{
+ int newtry[31], newother[31], *r, *q, *p, n, sum, first;
+ int ii, lastwhite, lastbrown;
+
+ *prob = sum = 0;
+ r = player+25;
+ p = newtry;
+ q = newother;
+ while(player<r){
+ *p++= *player++;
+ *q++= *playee++;
+ }
+ q=newtry+31;
+ for(p = newtry+25; p < q; p++) /* zero out spaces for hit pieces */
+ *p = 0;
+ for(n = 0; n < 4; n++){
+ if(moves[k].pos[n] == NIL)
+ break;
+ newtry[moves[k].pos[n]]--;
+ newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++;
+ if(ii<25 && newother[25-ii]==1){
+ newother[25-ii]=0;
+ newother[0]++;
+ if(ii<=15 && level=='e') /* hit if near other's home */
+ sum++;
+ }
+ }
+ for(lastbrown = 0; newother[lastbrown] == 0; lastbrown++);
+ ;
+ for(lastwhite = 0; newtry[lastwhite] == 0; lastwhite++)
+ ;
+ lastwhite = 25-lastwhite;
+ if(lastwhite<=6 && lastwhite<lastbrown)
+ sum=1000;
+ /* experts running game. */
+ /* first priority is to */
+ /* get all pieces into */
+ /* white's home */
+ if(lastwhite<lastbrown && level=='e' && lastwhite>6) {
+ for(sum = 1000; lastwhite > 6; lastwhite--)
+ sum = sum-lastwhite*newtry[25-lastwhite];
+ }
+ for(first = 0; first < 25; first++)
+ if(newother[first] != 0) /*find other's first piece*/
+ break;
+ q = newtry+25;
+ for(p = newtry+1; p < q;) /* blocked points are good */
+ if(*p++ > 1)
+ sum++;
+ if(first > 5) { /* only stress removing pieces if */
+ /* homeboard cannot be hit */
+ q = newtry+31;
+ p=newtry+25;
+ for(n = 6; p < q; n--)
+ sum += *p++ * n; /*remove pieces, but just barely*/
+ }
+ if(level != 'b'){
+ r = newtry+25-first; /*singles past this point can't be hit*/
+ for(p = newtry+7; p < r; )
+ if(*p++ == 1) /*singles are bad after 1st 6 points if they can be hit*/
+ sum--;
+ q = newtry+3;
+ for(p = newtry; p < q; ) /*bad to be on 1st three points*/
+ sum -= *p++;
+ }
+
+ for(n = 1; n <= 4; n++)
+ *prob += n*getprob(newtry,newother,6*n-5,6*n);
+ return(sum);
+}
+instructions()
+{
+ register fd, r;
+ char buf[BUFSIZ];
+
+ if((fd = open(RULES, 0)) < 0) {
+ fprintf(stderr, "back: cannot open %s\n", RULES);
+ return;
+ }
+ while(r = read(fd, buf, BUFSIZ))
+ write(1, buf, r);
+}
+
+getprob(player,playee,start,finish)
+int *player,*playee,start,finish;
+{ /*returns the probability (times 102) that any
+ pieces belonging to 'player' and lying between
+ his points 'start' and 'finish' will be hit
+ by a piece belonging to playee
+ */
+ int k, n, sum;
+
+ sum = 0;
+ for(; start <= finish; start++){
+ if(player[start] == 1){
+ for(k = 1; k <= 12; k++){
+ if((n=25-start-k) < 0)
+ break;
+ if(playee[n] != 0)
+ sum += probability[k];
+ }
+ }
+ }
+ return(sum);
+}
+prtbrd()
+{
+ int k;
+ static char undersc[]="______________________________________________________";
+
+ fprintf(stdout, "White's Home\n%s\r",undersc);
+ for(k = 1; k <= 6; k++)
+ fprintf(stdout, "%4d",k);
+ fprintf(stdout, " ");
+ for(k = 7; k <= 12; k++)
+ fprintf(stdout, "%4d",k);
+ putchar('\n');
+ numline(brown, white, 1, 6);
+ fprintf(stdout, " ");
+ numline(brown, white, 7, 12);
+ putchar('\n');
+ colorline(brown, 'B', white, 'W', 1, 6);
+ fprintf(stdout, " ");
+ colorline(brown, 'B', white, 'W', 7, 12);
+ putchar('\n');
+ if(white[0] != 0)
+ fprintf(stdout, "%28dW\n",white[0]);
+ else
+ putchar('\n');
+ if(brown[0] != 0)
+ fprintf(stdout, "%28dB\n", brown[0]);
+ else
+ putchar('\n');
+ colorline(white, 'W', brown, 'B', 1, 6);
+ fprintf(stdout, " ");
+ colorline(white, 'W', brown, 'B', 7, 12);
+ fprintf(stdout, "\n%s\r",undersc);
+ numline(white, brown, 1, 6);
+ fprintf(stdout, " ");
+ numline(white, brown, 7, 12);
+ putchar('\n');
+ for(k = 24; k >= 19; k--)
+ fprintf(stdout, "%4d",k);
+ fprintf(stdout, " ");
+ for(k = 18; k >= 13; k--)
+ fprintf(stdout, "%4d",k);
+ fprintf(stdout, "\nBrown's Home\n\n\n\n\n");
+}
+numline(upcol,downcol,start,fin)
+int *upcol,*downcol,start,fin;
+{
+ int k, n;
+
+ for(k = start; k <= fin; k++){
+ if((n = upcol[k]) != 0 || (n = downcol[25-k]) != 0)
+ fprintf(stdout, "%4d", n);
+ else
+ fprintf(stdout, " ");
+ }
+}
+colorline(upcol,c1,downcol,c2,start,fin)
+int *upcol,*downcol,start,fin;
+char c1,c2;
+{
+ int k;
+ char c;
+
+ for(k = start; k <= fin; k++){
+ c = ' ';
+ if(upcol[k] != 0)
+ c = c1;
+ if(downcol[25-k] != 0)
+ c = c2;
+ fprintf(stdout, " %c",c);
+ }
+}
diff --git a/backgammon/common_source/board.c b/backgammon/common_source/board.c
new file mode 100644
index 00000000..d21d36a9
--- /dev/null
+++ b/backgammon/common_source/board.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)board.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+static int i, j, k;
+static char ln[60];
+
+wrboard () {
+ register int l;
+ static char bl[] =
+ "| | | |\n";
+ static char sv[] =
+ "| | | | \n";
+
+ fixtty (noech);
+ clear();
+
+ if (tflag) {
+ fboard();
+ goto lastline;
+ }
+
+ writel ("_____________________________________________________\n");
+ writel (bl);
+ strcpy (ln,bl);
+ for (j = 1; j < 50; j += 4) {
+ k = j/4+(j > 24? 12: 13);
+ ln[j+1] = k%10+'0';
+ ln[j] = k/10+'0';
+ if (j == 21)
+ j += 4;
+ }
+ writel (ln);
+ for (i = 0; i < 5; i++) {
+ strcpy (ln,sv);
+ for (j = 1; j < 50; j += 4) {
+ k = j/4+(j > 24? 12: 13);
+ wrbsub ();
+ if (j == 21)
+ j += 4;
+ }
+ if (-board[25] > i)
+ ln[26] = 'w';
+ if (-board[25] > i+5)
+ ln[25] = 'w';
+ if (-board[25] > i+10)
+ ln[27] = 'w';
+ l = 53;
+ if (off[1] > i || (off[1] < 0 && off[1]+15 > i)) {
+ ln[54] = 'r';
+ l = 55;
+ }
+ if (off[1] > i+5 || (off[1] < 0 && off[1]+15 > i+5)) {
+ ln[55] = 'r';
+ l = 56;
+ }
+ if (off[1] > i+10 || (off[1] < 0 && off[1]+15 > i+10)) {
+ ln[56] = 'r';
+ l = 57;
+ }
+ ln[l++] = '\n';
+ ln[l] = '\0';
+ writel (ln);
+ }
+ strcpy (ln,bl);
+ ln[25] = 'B';
+ ln[26] = 'A';
+ ln[27] = 'R';
+ writel (ln);
+ strcpy (ln,sv);
+ for (i = 4; i > -1; i--) {
+ for (j = 1; j < 50; j += 4) {
+ k = ((j > 24? 53: 49)-j)/4;
+ wrbsub();
+ if (j == 21)
+ j += 4;
+ }
+ if (board[0] > i)
+ ln[26] = 'r';
+ if (board[0] > i+5)
+ ln[25] = 'r';
+ if (board[0] > i+10)
+ ln[27] = 'r';
+ l = 53;
+ if (off[0] > i || (off[0] < 0 && off[0]+15 > i)) {
+ ln[54] = 'w';
+ l = 55;
+ }
+ if (off[0] > i+5 || (off[0] < 0 && off[0]+15 > i+5)) {
+ ln[55] = 'w';
+ l = 56;
+ }
+ if (off[0] > i+10 || (off[0] < 0 && off[0]+15 > i+10)) {
+ ln[56] = 'w';
+ l = 57;
+ }
+ ln[l++] = '\n';
+ ln[l] = '\0';
+ writel (ln);
+ }
+ strcpy (ln,bl);
+ for (j = 1; j < 50; j += 4) {
+ k = ((j > 24? 53: 49)-j)/4;
+ ln[j+1] = k%10+'0';
+ if (k > 9)
+ ln[j] = k/10+'0';
+ if (j == 21)
+ j += 4;
+ }
+ writel (ln);
+ writel ("|_______________________|___|_______________________|\n");
+
+lastline:
+ gwrite ();
+ if (tflag)
+ curmove (18,0);
+ else {
+ writec ('\n');
+ writec ('\n');
+ }
+ fixtty(raw);
+}
+
+wrbsub () {
+ register int m;
+ register char d;
+
+ if (board[k] > 0) {
+ m = board[k];
+ d = 'r';
+ } else {
+ m = -board[k];
+ d = 'w';
+ }
+ if (m>i)
+ ln[j+1] = d;
+ if (m>i+5)
+ ln[j] = d;
+ if (m>i+10)
+ ln[j+2] = d;
+}
diff --git a/backgammon/common_source/check.c b/backgammon/common_source/check.c
new file mode 100644
index 00000000..5ef2eb2b
--- /dev/null
+++ b/backgammon/common_source/check.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)check.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+getmove () {
+ register int i, c;
+
+ c = 0;
+ for (;;) {
+ i = checkmove(c);
+
+ switch (i) {
+ case -1:
+ if (movokay(mvlim)) {
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ for (i = 0; i < mvlim; i++)
+ if (h[i])
+ wrhit(g[i]);
+ nexturn();
+ if (*offopp == 15)
+ cturn *= -2;
+ if (tflag && pnum)
+ bflag = pnum;
+ return;
+ }
+
+ case -4:
+ case 0:
+ if (tflag)
+ refresh();
+ if (i != 0 && i != -4)
+ break;
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ writel (*Colorptr);
+ if (i == -4)
+ writel (" must make ");
+ else
+ writel (" can only make ");
+ writec (mvlim+'0');
+ writel (" move");
+ if (mvlim > 1)
+ writec ('s');
+ writec ('.');
+ writec ('\n');
+ break;
+
+ case -3:
+ if (quit())
+ return;
+ }
+
+ if (! tflag)
+ proll ();
+ else {
+ curmove (cturn == -1? 18: 19,39);
+ cline ();
+ c = -1;
+ }
+ }
+}
+
+movokay (mv)
+register int mv;
+
+{
+ register int i, m;
+
+ if (d0)
+ swap;
+
+ for (i = 0; i < mv; i++) {
+
+ if (p[i] == g[i]) {
+ moverr (i);
+ curmove (20,0);
+ writel ("Attempt to move to same location.\n");
+ return (0);
+ }
+
+ if (cturn*(g[i]-p[i]) < 0) {
+ moverr (i);
+ curmove (20,0);
+ writel ("Backwards move.\n");
+ return (0);
+ }
+
+ if (abs(board[bar]) && p[i] != bar) {
+ moverr (i);
+ curmove (20,0);
+ writel ("Men still on bar.\n");
+ return (0);
+ }
+
+ if ( (m = makmove(i)) ) {
+ moverr (i);
+ switch (m) {
+
+ case 1:
+ writel ("Move not rolled.\n");
+ break;
+
+ case 2:
+ writel ("Bad starting position.\n");
+ break;
+
+ case 3:
+ writel ("Destination occupied.\n");
+ break;
+
+ case 4:
+ writel ("Can't remove men yet.\n");
+ }
+ return (0);
+ }
+ }
+ return (1);
+}
diff --git a/backgammon/common_source/fancy.c b/backgammon/common_source/fancy.c
new file mode 100644
index 00000000..6afaa367
--- /dev/null
+++ b/backgammon/common_source/fancy.c
@@ -0,0 +1,748 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)fancy.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char PC; /* padding character */
+char *BC; /* backspace sequence */
+char *CD; /* clear to end of screen sequence */
+char *CE; /* clear to end of line sequence */
+char *CL; /* clear screen sequence */
+char *CM; /* cursor movement instructions */
+char *HO; /* home cursor sequence */
+char *MC; /* column cursor movement map */
+char *ML; /* row cursor movement map */
+char *ND; /* forward cursor sequence */
+char *UP; /* up cursor sequence */
+
+int lHO; /* length of HO */
+int lBC; /* length of BC */
+int lND; /* length of ND */
+int lUP; /* length of UP */
+int CO; /* number of columns */
+int LI; /* number of lines */
+int *linect; /* array of lengths of lines on screen
+ (the actual screen is not stored) */
+
+ /* two letter codes */
+char tcap[] = "bccdceclcmhomcmlndup";
+ /* corresponding strings */
+char **tstr[] = { &BC, &CD, &CE, &CL, &CM, &HO, &MC, &ML, &ND, &UP };
+
+int buffnum; /* pointer to output buffer */
+
+char tbuf[1024]; /* buffer for decoded termcap entries */
+
+int oldb[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+int oldr;
+int oldw;
+ /* "real" cursor positions, so
+ * it knows when to reposition.
+ * These are -1 if curr and curc
+ * are accurate */
+int realr;
+int realc;
+
+void addbuf();
+
+fboard () {
+ register int i, j, l;
+
+ curmove (0,0); /* do top line */
+ for (i = 0; i < 53; i++)
+ fancyc ('_');
+
+ curmove (15,0); /* do botttom line */
+ for (i = 0; i < 53; i++)
+ fancyc ('_');
+
+ l = 1; /* do vertical lines */
+ for (i = 52; i > -1; i -= 28) {
+ curmove ( (l == 1? 1: 15) ,i);
+ fancyc ('|');
+ for (j = 0; j < 14; j++) {
+ curmove (curr+l,curc-1);
+ fancyc ('|');
+ }
+ if (i == 24)
+ i += 32;
+ l = -l; /* alternate directions */
+ }
+
+ curmove (2,1); /* label positions 13-18 */
+ for (i = 13; i < 18; i++) {
+ fancyc ('1');
+ fancyc ((i % 10)+'0');
+ curmove (curr,curc+2);
+ }
+ fancyc ('1');
+ fancyc ('8');
+
+ curmove (2,29); /* label positions 19-24 */
+ fancyc ('1');
+ fancyc ('9');
+ for (i = 20; i < 25; i++) {
+ curmove (curr,curc+2);
+ fancyc ('2');
+ fancyc ((i % 10)+'0');
+ }
+
+ curmove (14,1); /* label positions 12-7 */
+ fancyc ('1');
+ fancyc ('2');
+ for (i = 11; i > 6; i--) {
+ curmove (curr,curc+2);
+ fancyc (i > 9? '1': ' ');
+ fancyc ((i % 10)+'0');
+ }
+
+ curmove (14,30); /* label positions 6-1 */
+ fancyc ('6');
+ for (i = 5; i > 0; i--) {
+ curmove (curr,curc+3);
+ fancyc (i+'0');
+ }
+
+ for (i = 12; i > 6; i--) /* print positions 12-7 */
+ if (board[i])
+ bsect (board[i],13,1+4*(12-i),-1);
+
+ if (board[0]) /* print red men on bar */
+ bsect (board[0],13,25,-1);
+
+ for (i = 6; i > 0; i--) /* print positions 6-1 */
+ if (board[i])
+ bsect (board[i],13,29+4*(6-i),-1);
+
+ l = (off[1] < 0? off[1]+15: off[1]); /* print white's home */
+ bsect (l,3,54,1);
+
+ curmove (8,25); /* print the word BAR */
+ fancyc ('B');
+ fancyc ('A');
+ fancyc ('R');
+
+ for (i = 13; i < 19; i++) /* print positions 13-18 */
+ if (board[i])
+ bsect (board[i],3,1+4*(i-13),1);
+
+ if (board[25]) /* print white's men on bar */
+ bsect (board[25],3,25,1);
+
+ for (i = 19; i < 25; i++) /* print positions 19-24 */
+ if (board[i])
+ bsect (board[i],3,29+4*(i-19),1);
+
+ l = (off[0] < 0? off[0]+15: off[0]); /* print red's home */
+ bsect (-l,13,54,-1);
+
+ for (i = 0; i < 26; i++) /* save board position
+ * for refresh later */
+ oldb[i] = board[i];
+ oldr = (off[1] < 0? off[1]+15: off[1]);
+ oldw = -(off[0] < 0? off[0]+15: off[0]);
+}
+
+/*
+ * bsect (b,rpos,cpos,cnext)
+ * Print the contents of a board position. "b" has the value of the
+ * position, "rpos" is the row to start printing, "cpos" is the column to
+ * start printing, and "cnext" is positive if the position starts at the top
+ * and negative if it starts at the bottom. The value of "cpos" is checked
+ * to see if the position is a player's home, since those are printed
+ * differently.
+ */
+
+bsect (b,rpos,cpos,cnext)
+int b; /* contents of position */
+int rpos; /* row of position */
+int cpos; /* column of position */
+int cnext; /* direction of position */
+
+{
+ register int j; /* index */
+ register int n; /* number of men on position */
+ register int bct; /* counter */
+ int k; /* index */
+ char pc; /* color of men on position */
+
+ n = abs(b); /* initialize n and pc */
+ pc = (b > 0? 'r': 'w');
+
+ if (n < 6 && cpos < 54) /* position cursor at start */
+ curmove (rpos,cpos+1);
+ else
+ curmove (rpos,cpos);
+
+ for (j = 0; j < 5; j++) { /* print position row by row */
+
+ for (k = 0; k < 15; k += 5) /* print men */
+ if (n > j+k)
+ fancyc (pc);
+
+ if (j < 4) { /* figure how far to
+ * back up for next
+ * row */
+ if (n < 6) { /* stop if none left */
+ if (j+1 == n)
+ break;
+ bct = 1; /* single column */
+ } else {
+ if (n < 11) { /* two columns */
+ if (cpos == 54) { /* home pos */
+ if (j+5 >= n)
+ bct = 1;
+ else
+ bct = 2;
+ }
+ if (cpos < 54) { /* not home */
+ if (j+6 >= n)
+ bct = 1;
+ else
+ bct = 2;
+ }
+ } else { /* three columns */
+ if (j+10 >= n)
+ bct = 2;
+ else
+ bct = 3;
+ }
+ }
+ curmove (curr+cnext,curc-bct); /* reposition cursor */
+ }
+ }
+}
+
+refresh() {
+ register int i, r, c;
+
+ r = curr; /* save current position */
+ c = curc;
+
+ for (i = 12; i > 6; i--) /* fix positions 12-7 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],13,1+(12-i)*4,-1);
+ oldb[i] = board[i];
+ }
+
+ if (board[0] != oldb[0]) { /* fix red men on bar */
+ fixpos (oldb[0],board[0],13,25,-1);
+ oldb[0] = board[0];
+ }
+
+ for (i = 6; i > 0; i--) /* fix positions 6-1 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],13,29+(6-i)*4,-1);
+ oldb[i] = board[i];
+ }
+
+ i = -(off[0] < 0? off[0]+15: off[0]); /* fix white's home */
+ if (oldw != i) {
+ fixpos (oldw,i,13,54,-1);
+ oldw = i;
+ }
+
+ for (i = 13; i < 19; i++) /* fix positions 13-18 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],3,1+(i-13)*4,1);
+ oldb[i] = board[i];
+ }
+
+ if (board[25] != oldb[25]) { /* fix white men on bar */
+ fixpos (oldb[25],board[25],3,25,1);
+ oldb[25] = board[25];
+ }
+
+ for (i = 19; i < 25; i++) /* fix positions 19-24 */
+ if (board[i] != oldb[i]) {
+ fixpos (oldb[i],board[i],3,29+(i-19)*4,1);
+ oldb[i] = board[i];
+ }
+
+ i = (off[1] < 0? off[1]+15: off[1]); /* fix red's home */
+ if (oldr != i) {
+ fixpos (oldr,i,3,54,1);
+ oldr = i;
+ }
+
+ curmove (r,c); /* return to saved position */
+ newpos();
+ buflush();
+}
+
+fixpos (old,new,r,c,inc)
+int old, new, r, c, inc;
+
+{
+ register int o, n, nv;
+ int ov, nc;
+ char col;
+
+ if (old*new >= 0) {
+ ov = abs(old);
+ nv = abs(new);
+ col = (old+new > 0? 'r': 'w');
+ o = (ov-1)/5;
+ n = (nv-1)/5;
+ if (o == n) {
+ if (o == 2)
+ nc = c+2;
+ if (o == 1)
+ nc = c < 54? c: c+1;
+ if (o == 0)
+ nc = c < 54? c+1: c;
+ if (ov > nv)
+ fixcol (r+inc*(nv-n*5),nc,abs(ov-nv),' ',inc);
+ else
+ fixcol (r+inc*(ov-o*5),nc,abs(ov-nv),col,inc);
+ return;
+ } else {
+ if (c < 54) {
+ if (o+n == 1) {
+ if (n) {
+ fixcol (r,c,abs(nv-5),col,inc);
+ if (ov != 5)
+ fixcol (r+inc*ov,c+1,abs(ov-5),col,inc);
+ } else {
+ fixcol (r,c,abs(ov-5),' ',inc);
+ if (nv != 5)
+ fixcol (r+inc*nv,c+1,abs(nv-5),' ',inc);
+ }
+ return;
+ }
+ if (n == 2) {
+ if (ov != 10)
+ fixcol (r+inc*(ov-5),c,abs(ov-10),col,inc);
+ fixcol (r,c+2,abs(nv-10),col,inc);
+ } else {
+ if (nv != 10)
+ fixcol (r+inc*(nv-5),c,abs(nv-10),' ',inc);
+ fixcol (r,c+2,abs(ov-10),' ',inc);
+ }
+ return;
+ }
+ if (n > o) {
+ fixcol (r+inc*(ov%5),c+o,abs(5*n-ov),col,inc);
+ if (nv != 5*n)
+ fixcol (r,c+n,abs(5*n-nv),col,inc);
+ } else {
+ fixcol (r+inc*(nv%5),c+n,abs(5*n-nv),' ',inc);
+ if (ov != 5*o)
+ fixcol (r,c+o,abs(5*o-ov),' ',inc);
+ }
+ return;
+ }
+ }
+ nv = abs(new);
+ fixcol (r,c+1,nv,new > 0? 'r': 'w',inc);
+ if (abs(old) <= abs(new))
+ return;
+ fixcol (r+inc*new,c+1,abs(old+new),' ',inc);
+}
+
+fixcol (r,c,l,ch,inc)
+register int l, ch;
+int r, c, inc;
+
+{
+ register int i;
+
+ curmove (r,c);
+ fancyc (ch);
+ for (i = 1; i < l; i++) {
+ curmove (curr+inc,curc-1);
+ fancyc (ch);
+ }
+}
+
+curmove (r,c)
+register int r, c;
+
+{
+ if (curr == r && curc == c)
+ return;
+ if (realr == -1) {
+ realr = curr;
+ realc = curc;
+ }
+ curr = r;
+ curc = c;
+}
+
+newpos () {
+ register int r; /* destination row */
+ register int c; /* destination column */
+ register int mode = -1; /* mode of movement */
+
+ int count = 1000; /* character count */
+ int i; /* index */
+ int j; /* index */
+ int n; /* temporary variable */
+ char *m; /* string containing CM movement */
+
+
+ if (realr == -1) /* see if already there */
+ return;
+
+ r = curr; /* set current and dest. positions */
+ c = curc;
+ curr = realr;
+ curc = realc;
+
+ /* double check position */
+ if (curr == r && curc == c) {
+ realr = realc = -1;
+ return;
+ }
+
+ if (CM) { /* try CM to get there */
+ mode = 0;
+ m = (char *)tgoto (CM,c,r);
+ count = strlen (m);
+ }
+
+ /* try HO and local movement */
+ if (HO && (n = r+c*lND+lHO) < count) {
+ mode = 1;
+ count = n;
+ }
+
+ /* try various LF combinations */
+ if (r >= curr) {
+ /* CR, LF, and ND */
+ if ((n = (r-curr)+c*lND+1) < count) {
+ mode = 2;
+ count = n;
+ }
+ /* LF, ND */
+ if (c >= curc && (n = (r-curr)+(c-curc)*lND) < count) {
+ mode = 3;
+ count = n;
+ }
+ /* LF, BS */
+ if (c < curc && (n = (r-curr)+(curc-c)*lBC) < count) {
+ mode = 4;
+ count = n;
+ }
+ }
+
+ /* try corresponding UP combinations */
+ if (r < curr) {
+ /* CR, UP, and ND */
+ if ((n = (curr-r)*lUP+c*lND+1) < count) {
+ mode = 5;
+ count = n;
+ }
+ /* UP and ND */
+ if (c >= curc && (n = (curr-r)*lUP+(c-curc)*lND) < count) {
+ mode = 6;
+ count = n;
+ }
+ /* UP and BS */
+ if (c < curc && (n = (curr-r)*lUP+(curc-c)*lBC) < count) {
+ mode = 7;
+ count = n;
+ }
+ }
+
+ /* space over */
+ if (curr == r && c > curc && linect[r] < curc && c-curc < count)
+ mode = 8;
+
+ switch (mode) {
+
+ case -1: /* error! */
+ write (2,"\r\nInternal cursor error.\r\n",26);
+ getout();
+
+ /* direct cursor motion */
+ case 0:
+ tputs (m,abs(curr-r),addbuf);
+ break;
+
+ /* relative to "home" */
+ case 1:
+ tputs (HO,r,addbuf);
+ for (i = 0; i < r; i++)
+ addbuf ('\012');
+ for (i = 0; i < c; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* CR and down and over */
+ case 2:
+ addbuf ('\015');
+ for (i = 0; i < r-curr; i++)
+ addbuf ('\012');
+ for (i = 0; i < c; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* down and over */
+ case 3:
+ for (i = 0; i < r-curr; i++)
+ addbuf ('\012');
+ for (i = 0; i < c-curc; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* down and back */
+ case 4:
+ for (i = 0; i < r-curr; i++)
+ addbuf ('\012');
+ for (i = 0; i < curc-c; i++)
+ addbuf ('\010');
+ break;
+
+ /* CR and up and over */
+ case 5:
+ addbuf ('\015');
+ for (i = 0; i < curr-r; i++)
+ tputs (UP,1,addbuf);
+ for (i = 0; i < c; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* up and over */
+ case 6:
+ for (i = 0; i < curr-r; i++)
+ tputs (UP,1,addbuf);
+ for (i = 0; i < c-curc; i++)
+ tputs (ND,1,addbuf);
+ break;
+
+ /* up and back */
+ case 7:
+ for (i = 0; i < curr-r; i++)
+ tputs (UP,1,addbuf);
+ for (i = 0; i < curc-c; i++) {
+ if (BC)
+ tputs (BC,1,addbuf);
+ else
+ addbuf ('\010');
+ }
+ break;
+
+ /* safe space */
+ case 8:
+ for (i = 0; i < c-curc; i++)
+ addbuf (' ');
+ }
+
+ /* fix positions */
+ curr = r;
+ curc = c;
+ realr = -1;
+ realc = -1;
+}
+
+clear () {
+ register int i;
+
+ /* double space if can't clear */
+ if (CL == 0) {
+ writel ("\n\n");
+ return;
+ }
+
+ curr = curc = 0; /* fix position markers */
+ realr = realc = -1;
+ for (i = 0; i < 24; i++) /* clear line counts */
+ linect[i] = -1;
+ buffnum = -1; /* ignore leftover buffer contents */
+ tputs (CL,CO,addbuf); /* put CL in buffer */
+}
+
+tos () { /* home cursor */
+ curmove (0,0);
+}
+
+fancyc (c)
+register char c; /* character to output */
+{
+ register int sp; /* counts spaces in a tab */
+
+ if (c == '\007') { /* bells go in blindly */
+ addbuf (c);
+ return;
+ }
+
+ /* process tabs, use spaces if the
+ * the tab should be erasing things,
+ * otherwise use cursor movement
+ * routines. Note this does not use
+ * hardware tabs at all. */
+ if (c == '\t') {
+ sp = (curc+8) & (~ 7); /* compute spaces */
+ /* check line length */
+ if (linect[curr] >= curc || sp < 4) {
+ for (; sp > curc; sp--)
+ addbuf (' ');
+ curc = sp; /* fix curc */
+ } else
+ curmove (curr,sp);
+ return;
+ }
+
+ /* do newline be calling newline */
+ if (c == '\n') {
+ newline();
+ return;
+ }
+
+ /* ignore any other control chars */
+ if (c < ' ')
+ return;
+
+ /* if an erasing space or non-space,
+ * just add it to buffer. Otherwise
+ * use cursor movement routine, so that
+ * multiple spaces will be grouped
+ * together */
+ if (c > ' ' || linect[curr] >= curc) {
+ newpos (); /* make sure position correct */
+ addbuf (c); /* add character to buffer */
+ /* fix line length */
+ if (c == ' ' && linect[curr] == curc)
+ linect[curr]--;
+ else if (linect[curr] < curc)
+ linect[curr] = curc;
+ curc++; /* fix curc */
+ } else
+ /* use cursor movement routine */
+ curmove (curr,curc+1);
+}
+
+clend() {
+ register int i;
+ register char *s;
+
+
+ if (CD) {
+ tputs (CD,CO-curr,addbuf);
+ for (i = curr; i < LI; i++)
+ linect[i] = -1;
+ return;
+ }
+
+ curmove (i = curr,0);
+ cline();
+ while (curr < LI-1) {
+ curmove (curr+1,0);
+ if (linect[curr] > -1)
+ cline ();
+ }
+ curmove (i,0);
+}
+
+cline () {
+ register int i;
+ register int c;
+ register char *s;
+
+ if (curc > linect[curr])
+ return;
+ newpos ();
+ if (CE) {
+ tputs (CE,1,addbuf);
+ linect[curr] = curc-1;
+ } else {
+ c = curc-1;
+ while (linect[curr] > c) {
+ addbuf (' ');
+ curc++;
+ linect[curr]--;
+ }
+ curmove (curr,c+1);
+ }
+}
+
+newline () {
+ cline();
+ if (curr == LI-1)
+ curmove (begscr,0);
+ else
+ curmove (curr+1,0);
+}
+
+getcaps (s)
+register char *s;
+
+{
+ register char *code; /* two letter code */
+ register char ***cap; /* pointer to cap string */
+ char *bufp; /* pointer to cap buffer */
+ char tentry[1024]; /* temporary uncoded caps buffer */
+
+ tgetent (tentry,s); /* get uncoded termcap entry */
+
+ LI = tgetnum ("li"); /* get number of lines */
+ if (LI == -1)
+ LI = 12;
+ CO = tgetnum ("co"); /* get number of columns */
+ if (CO == -1)
+ CO = 65;
+
+ bufp = tbuf; /* get padding character */
+ tgetstr ("pc",&bufp);
+ if (bufp != tbuf)
+ PC = *tbuf;
+ else
+ PC = 0;
+
+ bufp = tbuf; /* get string entries */
+ cap = tstr;
+ for (code = tcap; *code; code += 2)
+ **cap++ = (char *)tgetstr (code,&bufp);
+
+ /* get pertinent lengths */
+ if (HO)
+ lHO = strlen (HO);
+ if (BC)
+ lBC = strlen (BC);
+ else
+ lBC = 1;
+ if (UP)
+ lUP = strlen (UP);
+ if (ND)
+ lND = strlen (ND);
+ if (LI < 24 || CO < 72 || !(CL && UP && ND))
+ return (0);
+ linect = (int *)calloc (LI+1,sizeof(int));
+ return (1);
+}
diff --git a/backgammon/common_source/init.c b/backgammon/common_source/init.c
new file mode 100644
index 00000000..9d3fce3b
--- /dev/null
+++ b/backgammon/common_source/init.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)init.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <sgtty.h>
+
+/*
+ * variable initialization.
+ */
+
+ /* name of executable object programs */
+char EXEC[] = "/usr/games/backgammon";
+char TEACH[] = "/usr/games/teachgammon";
+
+int pnum = 2; /* color of player:
+ -1 = white
+ 1 = red
+ 0 = both
+ 2 = not yet init'ed */
+int acnt = 0; /* length of args */
+int aflag = 1; /* flag to ask for rules or instructions */
+int bflag = 0; /* flag for automatic board printing */
+int cflag = 0; /* case conversion flag */
+int hflag = 1; /* flag for cleaning screen */
+int mflag = 0; /* backgammon flag */
+int raflag = 0; /* 'roll again' flag for recovered game */
+int rflag = 0; /* recovered game flag */
+int tflag = 0; /* cursor addressing flag */
+int iroll = 0; /* special flag for inputting rolls */
+int rfl = 0;
+
+char *color[] = {"White","Red","white","red"};
diff --git a/backgammon/common_source/odds.c b/backgammon/common_source/odds.c
new file mode 100644
index 00000000..dc780497
--- /dev/null
+++ b/backgammon/common_source/odds.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)odds.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+odds (r1,r2,val)
+register int r1;
+int r2, val;
+{
+ register int i, j;
+
+ if (r1 == 0) {
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 6; j++)
+ table[i][j] = 0;
+ return;
+ } else {
+ r1--;
+ if (r2-- == 0)
+ for (i = 0; i < 6; i++) {
+ table[i][r1] += val;
+ table[r1][i] += val;
+ }
+ else {
+ table[r2][r1] += val;
+ table[r1][r2] += val;
+ }
+ }
+}
+
+count () {
+ register int i;
+ register int j;
+ register int total;
+
+ total = 0;
+ for (i = 0; i < 6; i++)
+ for (j = 0; j < 6; j++)
+ total += table[i][j];
+ return (total);
+}
+
+canhit (i,c)
+int i, c;
+
+{
+ register int j, k, b;
+ int a, d, diff, place, addon, menstuck;
+
+ if (c == 0)
+ odds (0,0,0);
+ if (board[i] > 0) {
+ a = -1;
+ b = 25;
+ } else {
+ a = 1;
+ b = 0;
+ }
+ place = abs (25-b-i);
+ menstuck = abs (board[b]);
+ for (j = b; j != i; j += a) {
+ if (board[j]*a > 0) {
+ diff = abs(j-i);
+ addon = place+((board[j]*a > 2 || j == b)? 5: 0);
+ if ((j == b && menstuck == 1) &&
+ (j != b && menstuck == 0))
+ for (k = 1; k < diff; k++)
+ if (k < 7 && diff-k < 7 &&
+ (board[i+a*k]*a >= 0 ||
+ board[i+a*(diff-k)] >= 0))
+ odds (k,diff-k,addon);
+ if ((j == b || menstuck < 2) && diff < 7)
+ odds (diff,0,addon);
+ }
+ if (j == b && menstuck > 1)
+ break;
+ }
+ return (count());
+}
diff --git a/backgammon/common_source/one.c b/backgammon/common_source/one.c
new file mode 100644
index 00000000..c00f4ca1
--- /dev/null
+++ b/backgammon/common_source/one.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)one.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+makmove (i)
+register int i;
+
+{
+ register int n, d;
+ int max;
+
+ d = d0;
+ n = abs(g[i]-p[i]);
+ max = (*offptr < 0? 7: last());
+ if (board[p[i]]*cturn <= 0)
+ return (checkd(d)+2);
+ if (g[i] != home && board[g[i]]*cturn < -1)
+ return (checkd(d)+3);
+ if (i || D0 == D1) {
+ if (n == max? D1 < n: D1 != n)
+ return (checkd(d)+1);
+ } else {
+ if (n == max? D0 < n && D1 < n: D0 != n && D1 != n)
+ return (checkd(d)+1);
+ if (n == max? D0 < n: D0 != n) {
+ if (d0)
+ return (checkd(d)+1);
+ swap;
+ }
+ }
+ if (g[i] == home && *offptr < 0)
+ return (checkd(d)+4);
+ h[i] = 0;
+ board[p[i]] -= cturn;
+ if (g[i] != home) {
+ if (board[g[i]] == -cturn) {
+ board[home] -= cturn;
+ board[g[i]] = 0;
+ h[i] = 1;
+ if (abs(bar-g[i]) < 7) {
+ (*inopp)--;
+ if (*offopp >= 0)
+ *offopp -= 15;
+ }
+ }
+ board[g[i]] += cturn;
+ if (abs(home-g[i]) < 7 && abs(home-p[i]) > 6) {
+ (*inptr)++;
+ if (*inptr+*offptr == 0)
+ *offptr += 15;
+ }
+ } else {
+ (*offptr)++;
+ (*inptr)--;
+ }
+ return (0);
+}
+
+moverr (i)
+register int i;
+
+{
+ register int j;
+
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ writel ("Error: ");
+ for (j = 0; j <= i; j++) {
+ wrint (p[j]);
+ writec ('-');
+ wrint (g[j]);
+ if (j < i)
+ writec (',');
+ }
+ writel ("... ");
+ movback (i);
+}
+
+
+checkd (d)
+register int d;
+
+{
+ if (d0 != d)
+ swap;
+ return (0);
+}
+
+last () {
+ register int i;
+
+ for (i = home-6*cturn; i != home; i += cturn)
+ if (board[i]*cturn > 0)
+ return (abs(home-i));
+}
+
+movback (i)
+register int i;
+
+{
+ register int j;
+
+ for (j = i-1; j >= 0; j--)
+ backone(j);
+}
+
+backone (i)
+register int i;
+
+{
+ board[p[i]] += cturn;
+ if (g[i] != home) {
+ board[g[i]] -= cturn;
+ if (abs(g[i]-home) < 7 && abs(p[i]-home) > 6) {
+ (*inptr)--;
+ if (*inptr+*offptr < 15 && *offptr >= 0)
+ *offptr -= 15;
+ }
+ } else {
+ (*offptr)--;
+ (*inptr)++;
+ }
+ if (h[i]) {
+ board[home] += cturn;
+ board[g[i]] = -cturn;
+ if (abs(bar-g[i]) < 7) {
+ (*inopp)++;
+ if (*inopp+*offopp == 0)
+ *offopp += 15;
+ }
+ }
+}
diff --git a/backgammon/common_source/save.c b/backgammon/common_source/save.c
new file mode 100644
index 00000000..b91d3ec3
--- /dev/null
+++ b/backgammon/common_source/save.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)save.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+extern int errno;
+
+static char confirm[] = "Are you sure you want to leave now?";
+static char prompt[] = "Enter a file name: ";
+static char exist1[] = "The file '";
+static char exist2[] =
+ "' already exists.\nAre you sure you want to use this file?";
+static char cantuse[] = "\nCan't use ";
+static char saved[] = "This game has been saved on the file '";
+static char type[] = "'.\nType \"backgammon ";
+static char rec[] = "\" to recover your game.\n\n";
+static char cantrec[] = "Can't recover file: ";
+
+save (n)
+register int n;
+
+{
+ register int fdesc;
+ register char *fs;
+ char fname[50];
+
+ if (n) {
+ if (tflag) {
+ curmove (20,0);
+ clend();
+ } else
+ writec ('\n');
+ writel (confirm);
+ if (! yorn(0))
+ return;
+ }
+ cflag = 1;
+ for (;;) {
+ writel (prompt);
+ fs = fname;
+ while ((*fs = readc()) != '\n') {
+ if (*fs == tty.sg_erase) {
+ if (fs > fname) {
+ fs--;
+ if (tflag)
+ curmove (curr,curc-1);
+ else
+ writec (*fs);
+ } else
+ writec ('\007');
+ continue;
+ }
+ writec (*fs++);
+ }
+ *fs = '\0';
+ if ((fdesc = open(fname,2)) == -1 && errno == 2) {
+ if ((fdesc = creat (fname,0700)) != -1)
+ break;
+ }
+ if (fdesc != -1) {
+ if (tflag) {
+ curmove (18,0);
+ clend();
+ } else
+ writec ('\n');
+ writel (exist1);
+ writel (fname);
+ writel (exist2);
+ cflag = 0;
+ close (fdesc);
+ if (yorn (0)) {
+ unlink (fname);
+ fdesc = creat (fname,0700);
+ break;
+ } else {
+ cflag = 1;
+ continue;
+ }
+ }
+ writel (cantuse);
+ writel (fname);
+ writel (".\n");
+ close (fdesc);
+ cflag = 1;
+ }
+ write (fdesc,board,sizeof board);
+ write (fdesc,off,sizeof off);
+ write (fdesc,in,sizeof in);
+ write (fdesc,dice,sizeof dice);
+ write (fdesc,&cturn,sizeof cturn);
+ write (fdesc,&dlast,sizeof dlast);
+ write (fdesc,&pnum,sizeof pnum);
+ write (fdesc,&rscore,sizeof rscore);
+ write (fdesc,&wscore,sizeof wscore);
+ write (fdesc,&gvalue,sizeof gvalue);
+ write (fdesc,&raflag,sizeof raflag);
+ close (fdesc);
+ if (tflag)
+ curmove (18,0);
+ writel (saved);
+ writel (fname);
+ writel (type);
+ writel (fname);
+ writel (rec);
+ if (tflag)
+ clend();
+ getout ();
+}
+
+recover (s)
+char *s;
+
+{
+ register int i;
+ int fdesc;
+
+ if ((fdesc = open (s,0)) == -1)
+ norec (s);
+ read (fdesc,board,sizeof board);
+ read (fdesc,off,sizeof off);
+ read (fdesc,in,sizeof in);
+ read (fdesc,dice,sizeof dice);
+ read (fdesc,&cturn,sizeof cturn);
+ read (fdesc,&dlast,sizeof dlast);
+ read (fdesc,&pnum,sizeof pnum);
+ read (fdesc,&rscore,sizeof rscore);
+ read (fdesc,&wscore,sizeof wscore);
+ read (fdesc,&gvalue,sizeof gvalue);
+ read (fdesc,&raflag,sizeof raflag);
+ close (fdesc);
+ rflag = 1;
+}
+
+norec (s)
+register char *s;
+
+{
+ register char *c;
+
+ tflag = 0;
+ writel (cantrec);
+ c = s;
+ while (*c != '\0')
+ writec (*c++);
+ getout ();
+}
diff --git a/backgammon/common_source/subs.c b/backgammon/common_source/subs.c
new file mode 100644
index 00000000..7917124f
--- /dev/null
+++ b/backgammon/common_source/subs.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)subs.c 5.5 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include <stdio.h>
+#include "back.h"
+
+int buffnum;
+char outbuff[BUFSIZ];
+
+static char plred[] = "Player is red, computer is white.";
+static char plwhite[] = "Player is white, computer is red.";
+static char nocomp[] = "(No computer play.)";
+
+char *descr[] = {
+ "Usage: backgammon [-] [n r w b pr pw pb t3a]\n",
+ "\t-\tgets this list\n\tn\tdon't ask for rules or instructions",
+ "\tr\tplayer is red (implies n)\n\tw\tplayer is white (implies n)",
+ "\tb\ttwo players, red and white (implies n)",
+ "\tpr\tprint the board before red's turn",
+ "\tpw\tprint the board before white's turn",
+ "\tpb\tprint the board before both player's turn",
+ "\tterm\tterminal is a term",
+ "\tsfile\trecover saved game from file",
+ 0
+};
+
+errexit (s)
+register char *s;
+{
+ write (2,"\n",1);
+ perror (s);
+ getout();
+}
+
+strset (s1,s2)
+register char *s1, *s2;
+{
+ while ( (*s1++ = *s2++) != '\0');
+}
+
+addbuf (c)
+register char c;
+
+{
+ buffnum++;
+ if (buffnum == BUFSIZ) {
+ if (write(1,outbuff,BUFSIZ) != BUFSIZ)
+ errexit ("addbuf (write):");
+ buffnum = 0;
+ }
+ outbuff[buffnum] = c;
+}
+
+buflush () {
+ if (buffnum < 0)
+ return;
+ buffnum++;
+ if (write (1,outbuff,buffnum) != buffnum)
+ errexit ("buflush (write):");
+ buffnum = -1;
+}
+
+readc () {
+ char c;
+
+ if (tflag) {
+ cline();
+ newpos();
+ }
+ buflush();
+ if (read(0,&c,1) != 1)
+ errexit ("readc");
+#ifdef WHY_IS_THIS_HARDWIRED_IN_HERE
+ if (c == '\177')
+ getout();
+#endif
+ if (c == '\033' || c == '\015')
+ return ('\n');
+ if (cflag)
+ return (c);
+ if (c == '\014')
+ return ('R');
+ if (c >= 'a' && c <= 'z')
+ return (c & 0137);
+ return (c);
+}
+
+writec (c)
+char c;
+{
+ if (tflag)
+ fancyc (c);
+ else
+ addbuf (c);
+}
+
+writel (l)
+register char *l;
+{
+#ifdef DEBUG
+ register char *s;
+
+ if (trace == NULL)
+ trace = fopen ("bgtrace","w");
+
+ fprintf (trace,"writel: \"");
+ for (s = l; *s; s++) {
+ if (*s < ' ' || *s == '\177')
+ fprintf (trace,"^%c",(*s)^0100);
+ else
+ putc (*s,trace);
+ }
+ fprintf (trace,"\"\n");
+ fflush (trace);
+#endif
+
+ while (*l)
+ writec (*l++);
+}
+
+proll () {
+ if (d0)
+ swap;
+ if (cturn == 1)
+ writel ("Red's roll: ");
+ else
+ writel ("White's roll: ");
+ writec (D0+'0');
+ writec ('\040');
+ writec (D1+'0');
+ if (tflag)
+ cline();
+}
+
+wrint (n)
+int n;
+{
+ register int i, j, t;
+
+ for (i = 4; i > 0; i--) {
+ t = 1;
+ for (j = 0; j<i; j++)
+ t *= 10;
+ if (n > t-1)
+ writec ((n/t)%10+'0');
+ }
+ writec (n%10+'0');
+}
+
+gwrite() {
+ register int r, c;
+
+ if (tflag) {
+ r = curr;
+ c = curc;
+ curmove (16,0);
+ }
+
+ if (gvalue > 1) {
+ writel ("Game value: ");
+ wrint (gvalue);
+ writel (". ");
+ if (dlast == -1)
+ writel (color[0]);
+ else
+ writel (color[1]);
+ writel (" doubled last.");
+ } else {
+ switch (pnum) {
+ case -1: /* player is red */
+ writel (plred);
+ break;
+ case 0: /* player is both colors */
+ writel (nocomp);
+ break;
+ case 1: /* player is white */
+ writel (plwhite);
+ }
+ }
+
+ if (rscore || wscore) {
+ writel (" ");
+ wrscore();
+ }
+
+ if (tflag) {
+ cline();
+ curmove (r,c);
+ }
+}
+
+quit () {
+ register int i;
+
+ if (tflag) {
+ curmove (20,0);
+ clend();
+ } else
+ writec ('\n');
+ writel ("Are you sure you want to quit?");
+ if (yorn (0)) {
+ if (rfl) {
+ writel ("Would you like to save this game?");
+ if (yorn(0))
+ save(0);
+ }
+ cturn = 0;
+ return (1);
+ }
+ return (0);
+}
+
+yorn (special)
+register char special; /* special response */
+{
+ register char c;
+ register int i;
+
+ i = 1;
+ while ( (c = readc()) != 'Y' && c != 'N') {
+ if (special && c == special)
+ return (2);
+ if (i) {
+ if (special) {
+ writel (" (Y, N, or ");
+ writec (special);
+ writec (')');
+ } else
+ writel (" (Y or N)");
+ i = 0;
+ } else
+ writec ('\007');
+ }
+ if (c == 'Y')
+ writel (" Yes.\n");
+ else
+ writel (" No.\n");
+ if (tflag)
+ buflush();
+ return (c == 'Y');
+}
+
+wrhit (i)
+register int i;
+{
+ writel ("Blot hit on ");
+ wrint (i);
+ writec ('.');
+ writec ('\n');
+}
+
+nexturn () {
+ register int c;
+
+ cturn = -cturn;
+ c = cturn/abs(cturn);
+ home = bar;
+ bar = 25-bar;
+ offptr += c;
+ offopp -= c;
+ inptr += c;
+ inopp -= c;
+ Colorptr += c;
+ colorptr += c;
+}
+
+getarg (arg)
+register char ***arg;
+
+{
+ register char **s;
+
+ /* process arguments here. dashes are ignored, nbrw are ignored
+ if the game is being recovered */
+
+ s = *arg;
+ while (s[0][0] == '-') {
+ switch (s[0][1]) {
+
+ /* don't ask if rules or instructions needed */
+ case 'n':
+ if (rflag)
+ break;
+ aflag = 0;
+ args[acnt++] = 'n';
+ break;
+
+ /* player is both read and white */
+ case 'b':
+ if (rflag)
+ break;
+ pnum = 0;
+ aflag = 0;
+ args[acnt++] = 'b';
+ break;
+
+ /* player is red */
+ case 'r':
+ if (rflag)
+ break;
+ pnum = -1;
+ aflag = 0;
+ args[acnt++] = 'r';
+ break;
+
+ /* player is white */
+ case 'w':
+ if (rflag)
+ break;
+ pnum = 1;
+ aflag = 0;
+ args[acnt++] = 'w';
+ break;
+
+ /* print board after move according to following character */
+ case 'p':
+ if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b')
+ break;
+ args[acnt++] = 'p';
+ args[acnt++] = s[0][2];
+ if (s[0][2] == 'r')
+ bflag = 1;
+ if (s[0][2] == 'w')
+ bflag = -1;
+ if (s[0][2] == 'b')
+ bflag = 0;
+ break;
+
+ case 't':
+ if (s[0][2] == '\0') { /* get terminal caps */
+ s++;
+ tflag = getcaps (*s);
+ } else
+ tflag = getcaps (&s[0][2]);
+ break;
+
+ case 's':
+ s++;
+ /* recover file */
+ recover (s[0]);
+ break;
+ }
+ s++;
+ }
+ if (s[0] != 0)
+ recover(s[0]);
+}
+
+init () {
+ register int i;
+ for (i = 0; i < 26;)
+ board[i++] = 0;
+ board[1] = 2;
+ board[6] = board[13] = -5;
+ board[8] = -3;
+ board[12] = board[19] = 5;
+ board[17] = 3;
+ board[24] = -2;
+ off[0] = off[1] = -15;
+ in[0] = in[1] = 5;
+ gvalue = 1;
+ dlast = 0;
+}
+
+wrscore () {
+ writel ("Score: ");
+ writel (color[1]);
+ writec (' ');
+ wrint (rscore);
+ writel (", ");
+ writel (color[0]);
+ writec (' ');
+ wrint (wscore);
+}
+
+fixtty (mode)
+int mode;
+{
+ if (tflag)
+ newpos();
+ buflush();
+ tty.sg_flags = mode;
+ if (stty (0,&tty) < 0)
+ errexit("fixtty");
+}
+
+getout () {
+ /* go to bottom of screen */
+ if (tflag) {
+ curmove (23,0);
+ cline();
+ } else
+ writec ('\n');
+
+ /* fix terminal status */
+ fixtty (old);
+ exit();
+}
+roll () {
+ register char c;
+ register int row;
+ register int col;
+
+ if (iroll) {
+ if (tflag) {
+ row = curr;
+ col = curc;
+ curmove (17,0);
+ } else
+ writec ('\n');
+ writel ("ROLL: ");
+ c = readc();
+ if (c != '\n') {
+ while (c < '1' || c > '6')
+ c = readc();
+ D0 = c-'0';
+ writec (' ');
+ writec (c);
+ c = readc();
+ while (c < '1' || c > '6')
+ c = readc();
+ D1 = c-'0';
+ writec (' ');
+ writec (c);
+ if (tflag) {
+ curmove (17,0);
+ cline();
+ curmove (row,col);
+ } else
+ writec ('\n');
+ return;
+ }
+ if (tflag) {
+ curmove (17,0);
+ cline();
+ curmove (row,col);
+ } else
+ writec ('\n');
+ }
+ D0 = rnum(6)+1;
+ D1 = rnum(6)+1;
+ d0 = 0;
+}
diff --git a/backgammon/common_source/table.c b/backgammon/common_source/table.c
new file mode 100644
index 00000000..9555e8dd
--- /dev/null
+++ b/backgammon/common_source/table.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)table.c 5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "back.h"
+
+char *help2[] = {
+ " Enter moves as <s>-<f> or <s>/<r> where <s> is the starting",
+ "position, <f> is the finishing position, and <r> is the roll.",
+ "Remember, each die roll must be moved separately.",
+ 0
+};
+
+struct state {
+ char ch;
+ int fcode;
+ int newst;
+};
+
+struct state atmata[] = {
+
+ 'R', 1, 0, '?', 7, 0, 'Q', 0, -3, 'B', 8, 25,
+ '9', 2, 25, '8', 2, 25, '7', 2, 25, '6', 2, 25,
+ '5', 2, 25, '4', 2, 25, '3', 2, 25, '2', 2, 19,
+ '1', 2, 15, '0', 2, 25, '.', 0, 0, '9', 2, 25,
+ '8', 2, 25, '7', 2, 25, '6', 2, 25, '5', 2, 25,
+
+ '4', 2, 25, '3', 2, 25, '2', 2, 25, '1', 2, 25,
+ '0', 2, 25, '/', 0, 32, '-', 0, 39, '.', 0, 0,
+ '/', 5, 32, ' ', 6, 3, ',', 6, 3, '\n', 0, -1,
+ '6', 3, 28, '5', 3, 28, '4', 3, 28, '3', 3, 28,
+ '2', 3, 28, '1', 3, 28, '.', 0, 0, 'H', 9, 61,
+
+ '9', 4, 61, '8', 4, 61, '7', 4, 61, '6', 4, 61,
+ '5', 4, 61, '4', 4, 61, '3', 4, 61, '2', 4, 53,
+ '1', 4, 51, '0', 4, 61, '.', 0, 0, '9', 4, 61,
+ '8', 4, 61, '7', 4, 61, '6', 4, 61, '5', 4, 61,
+ '4', 4, 61, '3', 4, 61, '2', 4, 61, '1', 4, 61,
+
+ '0', 4, 61, ' ', 6, 3, ',', 6, 3, '-', 5, 39,
+ '\n', 0, -1, '.', 0, 0
+};
+
+checkmove (ist)
+
+int ist;
+
+{
+ register int j, n;
+ register char c;
+ char a;
+
+domove:
+ if (ist == 0) {
+ if (tflag)
+ curmove (curr,32);
+ else
+ writel ("\t\t");
+ writel ("Move: ");
+ }
+ ist = mvl = ncin = 0;
+ for (j = 0; j < 5; j++)
+ p[j] = g[j] = -1;
+
+dochar:
+ c = readc();
+
+ if (c == 'S') {
+ raflag = 0;
+ save (1);
+ if (tflag) {
+ curmove (cturn == -1? 18: 19,39);
+ ist = -1;
+ goto domove;
+ } else {
+ proll ();
+ ist = 0;
+ goto domove;
+ }
+ }
+
+ if (c == tty.sg_erase && ncin > 0) {
+ if (tflag)
+ curmove (curr,curc-1);
+ else {
+ if (tty.sg_erase == '\010')
+ writel ("\010 \010");
+ else
+ writec (cin[ncin-1]);
+ }
+ ncin--;
+ n = rsetbrd();
+ if (n == 0) {
+ n = -1;
+ if (tflag)
+ refresh();
+ }
+ if ((ist = n) > 0)
+ goto dochar;
+ goto domove;
+ }
+
+ if (c == tty.sg_kill && ncin > 0) {
+ if (tflag) {
+ refresh();
+ curmove (curr,39);
+ ist = -1;
+ goto domove;
+ } else if (tty.sg_erase == '\010') {
+ for (j = 0; j < ncin; j++)
+ writel ("\010 \010");
+ ist = -1;
+ goto domove;
+ } else {
+ writec ('\\');
+ writec ('\n');
+ proll ();
+ ist = 0;
+ goto domove;
+ }
+ }
+
+ n = dotable(c,ist);
+ if (n >= 0) {
+ cin[ncin++] = c;
+ if (n > 2)
+ if ((! tflag) || c != '\n')
+ writec (c);
+ ist = n;
+ if (n)
+ goto dochar;
+ else
+ goto domove;
+ }
+
+ if (n == -1 && mvl >= mvlim)
+ return(0);
+ if (n == -1 && mvl < mvlim-1)
+ return(-4);
+
+ if (n == -6) {
+ if (! tflag) {
+ if (movokay(mvl+1)) {
+ wrboard();
+ movback (mvl+1);
+ }
+ proll ();
+ writel ("\t\tMove: ");
+ for (j = 0; j < ncin;)
+ writec (cin[j++]);
+ } else {
+ if (movokay(mvl+1)) {
+ refresh();
+ movback (mvl+1);
+ } else
+ curmove (cturn == -1? 18:19,ncin+39);
+ }
+ ist = n = rsetbrd();
+ goto dochar;
+ }
+
+ if (n != -5)
+ return(n);
+ writec ('\007');
+ goto dochar;
+}
+
+dotable (c,i)
+char c;
+register int i;
+
+{
+ register int a, j;
+ int test;
+
+ test = (c == 'R');
+
+ while ( (a = atmata[i].ch) != '.') {
+ if (a == c || (test && a == '\n')) {
+ switch (atmata[i].fcode) {
+
+ case 1:
+ wrboard();
+ if (tflag) {
+ curmove (cturn == -1? 18: 19,0);
+ proll ();
+ writel ("\t\t");
+ } else
+ proll ();
+ break;
+
+ case 2:
+ if (p[mvl] == -1)
+ p[mvl] = c-'0';
+ else
+ p[mvl] = p[mvl]*10+c-'0';
+ break;
+
+ case 3:
+ if (g[mvl] != -1) {
+ if (mvl < mvlim)
+ mvl++;
+ p[mvl] = p[mvl-1];
+ }
+ g[mvl] = p[mvl]+cturn*(c-'0');
+ if (g[mvl] < 0)
+ g[mvl] = 0;
+ if (g[mvl] > 25)
+ g[mvl] = 25;
+ break;
+
+ case 4:
+ if (g[mvl] == -1)
+ g[mvl] = c-'0';
+ else
+ g[mvl] = g[mvl]*10+c-'0';
+ break;
+
+ case 5:
+ if (mvl < mvlim)
+ mvl++;
+ p[mvl] = g[mvl-1];
+ break;
+
+ case 6:
+ if (mvl < mvlim)
+ mvl++;
+ break;
+
+ case 7:
+ if (tflag)
+ curmove (20,0);
+ else
+ writec ('\n');
+ text (help2);
+ if (tflag) {
+ curmove (cturn == -1? 18: 19,39);
+ } else {
+ writec ('\n');
+ proll();
+ writel ("\t\tMove: ");
+ }
+ break;
+
+ case 8:
+ p[mvl] = bar;
+ break;
+
+ case 9:
+ g[mvl] = home;
+ }
+
+ if (! test || a != '\n')
+ return (atmata[i].newst);
+ else
+ return (-6);
+ }
+
+ i++;
+ }
+
+ return (-5);
+}
+
+rsetbrd () {
+ register int i, j, n;
+
+ n = 0;
+ mvl = 0;
+ for (i = 0; i < 4; i++)
+ p[i] = g[i] = -1;
+ for (j = 0; j < ncin; j++)
+ n = dotable (cin[j],n);
+ return (n);
+}