Init
This commit is contained in:
56
games/backgammon/Makefile
Normal file
56
games/backgammon/Makefile
Normal file
@@ -0,0 +1,56 @@
|
||||
#
|
||||
# @(#)Makefile 1.1 94/10/31 SMI; from UCB 5.2 85/09/07
|
||||
#
|
||||
#
|
||||
# Copyright (c) 1980 Regents of the University of California.
|
||||
# All rights reserved. The Berkeley software License Agreement
|
||||
# specifies the terms and conditions for redistribution.
|
||||
#
|
||||
|
||||
DESTDIR=
|
||||
CFLAGS= -O -DV7
|
||||
OBJS= allow.o board.o check.o extra.o fancy.o init.o main.o move.o\
|
||||
odds.o one.o save.o subs.o table.o text.o message.o
|
||||
TOBJS= allow.o board.o check.o data.o fancy.o init.o odds.o one.o save.o subs.o\
|
||||
table.o teach.o ttext1.o ttext2.o tutor.o
|
||||
SRCS= allow.c board.c check.c data.c extra.c fancy.c init.c main.c\
|
||||
move.c odds.c one.c save.c subs.c table.c teach.c text.c ttext1.c\
|
||||
ttext2.c tutor.c message.c
|
||||
|
||||
.DEFAULT:
|
||||
sccs get -G $@ $@
|
||||
|
||||
all: backgammon teachgammon
|
||||
|
||||
# Backgammon program
|
||||
backgammon: $(OBJS)
|
||||
-rm -f backgammon
|
||||
$(CC) -o backgammon $(OBJS) -ltermlib
|
||||
|
||||
# Backgammon rules and tutorial
|
||||
teachgammon: ${TOBJS}
|
||||
-rm -f teachgammon
|
||||
$(CC) -o teachgammon $(TOBJS) -ltermlib
|
||||
|
||||
# Header files back.h and tutor.h
|
||||
allow.o board.o check.o extra.o fancy.o main.o move.o odds.o one.o save.o\
|
||||
subs.o table.o teach.o text.o ttext1.o ttext2.o: back.h
|
||||
data.o tutor.o: back.h tutor.h
|
||||
|
||||
# Update message.
|
||||
message.o: FRC proto.message.c Mesgfix
|
||||
rm -f message.c
|
||||
cp proto.message.c message.c
|
||||
chmod 644 message.c
|
||||
ex - message.c < Mesgfix
|
||||
${CC} -c ${CFLAGS} message.c
|
||||
|
||||
FRC:
|
||||
|
||||
# Installation
|
||||
install: all
|
||||
install -s backgammon ${DESTDIR}/usr/games/backgammon
|
||||
install -s teachgammon ${DESTDIR}/usr/games/teachgammon
|
||||
|
||||
clean:
|
||||
rm -f ${OBJS} ${TOBJS} backgammon teachgammon message.c
|
||||
24
games/backgammon/Mesgfix
Normal file
24
games/backgammon/Mesgfix
Normal file
@@ -0,0 +1,24 @@
|
||||
3!date
|
||||
g/Sun /s//Sunday, /
|
||||
g/Mon /s//Monday, /
|
||||
g/Tue /s//Tuesday, /
|
||||
g/Wed /s//Wednesday, /
|
||||
g/Thu /s//Thursday, /
|
||||
g/Fri /s//Friday, /
|
||||
g/Sat /s//Saturday, /
|
||||
g/Jan /s//January /
|
||||
g/Feb /s//February /
|
||||
g/Mar /s//March /
|
||||
g/Apr /s//April /
|
||||
g/Jun /s//June /
|
||||
g/Jul /s//July /
|
||||
g/Aug /s//August /
|
||||
g/Sep /s//September /
|
||||
g/Oct /s//October /
|
||||
g/Nov /s//November /
|
||||
g/Dec /s//December /
|
||||
g/ /s// /
|
||||
3s/ ..:..:.. .../,/
|
||||
3s/^/ "Last update on /
|
||||
3s/$/.",/
|
||||
wq
|
||||
76
games/backgammon/allow.c
Normal file
76
games/backgammon/allow.c
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)allow.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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);
|
||||
}
|
||||
94
games/backgammon/back.h
Normal file
94
games/backgammon/back.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/* @(#)back.h 1.1 94/10/31 SMI; from UCB 4.2 82/11/22 */
|
||||
|
||||
#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 */
|
||||
143
games/backgammon/board.c
Normal file
143
games/backgammon/board.c
Normal file
@@ -0,0 +1,143 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)board.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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;
|
||||
}
|
||||
125
games/backgammon/check.c
Normal file
125
games/backgammon/check.c
Normal file
@@ -0,0 +1,125 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)check.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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);
|
||||
}
|
||||
282
games/backgammon/data.c
Normal file
282
games/backgammon/data.c
Normal file
@@ -0,0 +1,282 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)data.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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
|
||||
}
|
||||
};
|
||||
220
games/backgammon/extra.c
Normal file
220
games/backgammon/extra.c
Normal file
@@ -0,0 +1,220 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)extra.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#include "back.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
FILE *trace;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dble()
|
||||
* Have the current player double and ask opponent to accept.
|
||||
*/
|
||||
|
||||
dble () {
|
||||
register int resp; /* response to y/n */
|
||||
|
||||
for (;;) {
|
||||
writel (" doubles."); /* indicate double */
|
||||
|
||||
if (cturn == -pnum) { /* see if computer accepts */
|
||||
if (dblgood()) { /* guess not */
|
||||
writel (" Declined.\n");
|
||||
nexturn();
|
||||
cturn *= -2; /* indicate loss */
|
||||
return;
|
||||
} else { /* computer accepts */
|
||||
writel (" Accepted.\n");
|
||||
gvalue *= 2; /* double game value */
|
||||
dlast = cturn;
|
||||
if (tflag)
|
||||
gwrite();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* ask if player accepts */
|
||||
writel (" Does ");
|
||||
writel (cturn == 1? color[2]: color[3]);
|
||||
writel (" accept?");
|
||||
|
||||
/* get response from yorn,
|
||||
* a "2" means he said "p"
|
||||
* for print board. */
|
||||
if ((resp = yorn ('R')) == 2) {
|
||||
writel (" Reprint.\n");
|
||||
buflush();
|
||||
wrboard();
|
||||
writel (*Colorptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check response */
|
||||
if (resp) {
|
||||
/* accepted */
|
||||
gvalue *= 2;
|
||||
dlast = cturn;
|
||||
if (tflag)
|
||||
gwrite();
|
||||
return;
|
||||
}
|
||||
|
||||
nexturn (); /* declined */
|
||||
cturn *= -2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dblgood ()
|
||||
* Returns 1 if the computer would double in this position. This
|
||||
* is not an exact science. The computer will decline a double that he
|
||||
* would have made. Accumulated judgments are kept in the variable n,
|
||||
* which is in "pips", i.e., the position of each man summed over all
|
||||
* men, with opponent's totals negative. Thus, n should have a positive
|
||||
* value of 7 for each move ahead, or a negative value of 7 for each one
|
||||
* behind.
|
||||
*/
|
||||
|
||||
dblgood () {
|
||||
register int n; /* accumulated judgment */
|
||||
register int OFFC = *offptr; /* no. of computer's men off */
|
||||
register int OFFO = *offopp; /* no. of player's men off */
|
||||
|
||||
#ifdef DEBUG
|
||||
register int i;
|
||||
if (trace == NULL)
|
||||
trace = fopen ("bgtrace","w");
|
||||
#endif
|
||||
|
||||
/* get real pip value */
|
||||
n = eval()*cturn;
|
||||
#ifdef DEBUG
|
||||
fputs ("\nDoubles:\nBoard: ",trace);
|
||||
for (i = 0; i < 26; i++)
|
||||
fprintf (trace," %d",board[i]);
|
||||
fprintf (trace,"\n\tpip = %d, ",n);
|
||||
#endif
|
||||
|
||||
/* below adjusts pip value
|
||||
* according to position
|
||||
* judgments */
|
||||
|
||||
/* check men moving off
|
||||
* board */
|
||||
if (OFFC > -15 || OFFO > -15) {
|
||||
if (OFFC < 0 && OFFO < 0) {
|
||||
OFFC += 15;
|
||||
OFFO += 15;
|
||||
n +=((OFFC-OFFO)*7)/2;
|
||||
} else if (OFFC < 0) {
|
||||
OFFC += 15;
|
||||
n -= OFFO*7/2;
|
||||
} else if (OFFO < 0) {
|
||||
OFFO += 15;
|
||||
n += OFFC*7/2;
|
||||
}
|
||||
if (OFFC < 8 && OFFO > 8)
|
||||
n -= 7;
|
||||
if (OFFC < 10 && OFFO > 10)
|
||||
n -= 7;
|
||||
if (OFFC < 12 && OFFO > 12)
|
||||
n -= 7;
|
||||
if (OFFO < 8 && OFFC > 8)
|
||||
n += 7;
|
||||
if (OFFO < 10 && OFFC > 10)
|
||||
n += 7;
|
||||
if (OFFO < 12 && OFFC > 12)
|
||||
n += 7;
|
||||
n += ((OFFC-OFFO)*7)/2;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (trace,"off = %d, ",n);
|
||||
#endif
|
||||
|
||||
/* see if men are trapped */
|
||||
n -= freemen(bar);
|
||||
n += freemen(home);
|
||||
n += trapped(home,-cturn);
|
||||
n -= trapped(bar,cturn);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (trace,"free = %d\n",n);
|
||||
fprintf (trace,"\tOFFC = %d, OFFO = %d\n",OFFC,OFFO);
|
||||
fflush (trace);
|
||||
#endif
|
||||
|
||||
/* double if 2-3 moves ahead */
|
||||
if (n > 10+rnum(7))
|
||||
return(1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
freemen (b)
|
||||
int b;
|
||||
|
||||
{
|
||||
register int i, inc, lim;
|
||||
|
||||
odds(0,0,0);
|
||||
if (board[b] == 0)
|
||||
return (0);
|
||||
inc = (b == 0? 1: -1);
|
||||
lim = (b == 0? 7: 18);
|
||||
for (i = b+inc; i != lim; i += inc)
|
||||
if (board[i]*inc < -1)
|
||||
odds(abs(b-i),0,abs(board[b]));
|
||||
if (abs(board[b]) == 1)
|
||||
return ((36-count())/5);
|
||||
return (count()/5);
|
||||
}
|
||||
|
||||
trapped (n,inc)
|
||||
int n, inc;
|
||||
|
||||
{
|
||||
register int i, j, k;
|
||||
int c, l, ct;
|
||||
|
||||
ct = 0;
|
||||
l = n+7*inc;
|
||||
for (i = n+inc; i != l; i += inc) {
|
||||
odds (0,0,0);
|
||||
c = abs(i-l);
|
||||
if (board[i]*inc > 0) {
|
||||
for (j = c; j < 13; j++)
|
||||
if (board[i+inc*j]*inc < -1) {
|
||||
if (j < 7)
|
||||
odds (j,0,1);
|
||||
for (k = 1; k < 7 && k < j; k++)
|
||||
if (j-k < 7)
|
||||
odds (k,j-k,1);
|
||||
}
|
||||
ct += abs(board[i])*(36-count());
|
||||
}
|
||||
}
|
||||
return (ct/5);
|
||||
}
|
||||
|
||||
eval () {
|
||||
|
||||
register int i, j;
|
||||
|
||||
for (j = i = 0; i < 26; i++)
|
||||
j += (board[i] >= 0 ? i*board[i] : (25-i)*board[i]);
|
||||
|
||||
if (off[1] >= 0)
|
||||
j += 25*off[1];
|
||||
else
|
||||
j += 25*(off[1]+15);
|
||||
|
||||
if (off[0] >= 0)
|
||||
j -= 25*off[0];
|
||||
else
|
||||
j -= 25*(off[0]+15);
|
||||
return (j);
|
||||
}
|
||||
719
games/backgammon/fancy.c
Normal file
719
games/backgammon/fancy.c
Normal file
@@ -0,0 +1,719 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)fancy.c 1.1 94/10/31 SMI"; /* from UCB 4.2 82/11/22 */
|
||||
#endif
|
||||
|
||||
#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;
|
||||
|
||||
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 */
|
||||
int addbuf(); /* add a char to the output buffer */
|
||||
char *tgoto();
|
||||
|
||||
|
||||
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 = 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;
|
||||
int addbuff();
|
||||
|
||||
/* 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;
|
||||
int addbuf();
|
||||
|
||||
|
||||
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;
|
||||
int addbuf();
|
||||
|
||||
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 */
|
||||
char *tgetstr();
|
||||
|
||||
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++ = 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);
|
||||
}
|
||||
32
games/backgammon/init.c
Normal file
32
games/backgammon/init.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)init.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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"};
|
||||
554
games/backgammon/main.c
Normal file
554
games/backgammon/main.c
Normal file
@@ -0,0 +1,554 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)main.c 1.1 94/10/31 SMI"; /* from UCB 4.2 82/11/22 */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "back.h"
|
||||
|
||||
#define MVPAUSE 5 /* time to sleep when stuck */
|
||||
#define MAXUSERS 35 /* maximum number of users */
|
||||
|
||||
char *instr[]; /* text of instructions */
|
||||
char *message[]; /* update message */
|
||||
char ospeed; /* tty output speed */
|
||||
|
||||
char *helpm[] = { /* help message */
|
||||
"Enter a space or newline to roll, or",
|
||||
" R to reprint the board\tD to double",
|
||||
" S to save the game\tQ to quit",
|
||||
0
|
||||
};
|
||||
|
||||
char *contin[] = { /* pause message */
|
||||
"(Type a newline to continue.)",
|
||||
"",
|
||||
0
|
||||
};
|
||||
|
||||
static char user1a[] =
|
||||
"Sorry, you cannot play backgammon when there are more than ";
|
||||
static char user1b[] =
|
||||
" users\non the system.";
|
||||
static char user2a[] =
|
||||
"\nThere are now more than ";
|
||||
static char user2b[] =
|
||||
" users on the system, so you cannot play\nanother game. ";
|
||||
static char rules[] = "\nDo you want the rules of the game?";
|
||||
static char noteach[] = "Teachgammon not available!\n\007";
|
||||
static char need[] = "Do you need instructions for this program?";
|
||||
static char askcol[] =
|
||||
"Enter 'r' to play red, 'w' to play white, 'b' to play both:";
|
||||
static char rollr[] = "Red rolls a ";
|
||||
static char rollw[] = ". White rolls a ";
|
||||
static char rstart[] = ". Red starts.\n";
|
||||
static char wstart[] = ". White starts.\n";
|
||||
static char toobad1[] = "Too bad, ";
|
||||
static char unable[] = " is unable to use that roll.\n";
|
||||
static char toobad2[] = ". Too bad, ";
|
||||
static char cantmv[] = " can't move.\n";
|
||||
static char bgammon[] = "Backgammon! ";
|
||||
static char gammon[] = "Gammon! ";
|
||||
static char again[] = ".\nWould you like to play again?";
|
||||
static char svpromt[] = "Would you like to save this game?";
|
||||
|
||||
static char password[] = "losfurng";
|
||||
static char pbuf[10];
|
||||
|
||||
main (argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
{
|
||||
register int i; /* non-descript index */
|
||||
register int l; /* non-descript index */
|
||||
register char c; /* non-descript character storage */
|
||||
long t; /* time for random num generator */
|
||||
|
||||
/* initialization */
|
||||
bflag = 2; /* default no board */
|
||||
signal (2,getout); /* trap interrupts */
|
||||
if (gtty (0,&tty) == -1) /* get old tty mode */
|
||||
errexit ("backgammon(gtty)");
|
||||
old = tty.sg_flags;
|
||||
#ifdef V7
|
||||
raw = ((noech = old & ~ECHO) | CBREAK); /* set up modes */
|
||||
#else
|
||||
raw = ((noech = old & ~ECHO) | RAW); /* set up modes */
|
||||
#endif
|
||||
ospeed = tty.sg_ospeed; /* for termlib */
|
||||
|
||||
/* check user count */
|
||||
# ifdef CORY
|
||||
if (ucount() > MAXUSERS) {
|
||||
writel (user1a);
|
||||
wrint (MAXUSERS);
|
||||
writel (user1b);
|
||||
getout();
|
||||
}
|
||||
# endif
|
||||
|
||||
/* get terminal
|
||||
* capabilities, and
|
||||
* decide if it can
|
||||
* cursor address */
|
||||
tflag = getcaps (getenv ("TERM"));
|
||||
/* use whole screen
|
||||
* for text */
|
||||
if (tflag)
|
||||
begscr = 0;
|
||||
t = time(0);
|
||||
srandom(t); /* 'random' seed */
|
||||
|
||||
#ifdef V7
|
||||
while (*++argv != 0) /* process arguments */
|
||||
#else
|
||||
while (*++argv != -1) /* process arguments */
|
||||
#endif
|
||||
getarg (&argv);
|
||||
args[acnt] = '\0';
|
||||
if (tflag) { /* clear screen */
|
||||
noech &= ~(CRMOD|XTABS);
|
||||
raw &= ~(CRMOD|XTABS);
|
||||
clear();
|
||||
}
|
||||
fixtty (raw); /* go into raw mode */
|
||||
|
||||
/* check if restored
|
||||
* game and save flag
|
||||
* for later */
|
||||
if (rfl = rflag) {
|
||||
text (message); /* print message */
|
||||
text (contin);
|
||||
wrboard(); /* print board */
|
||||
/* if new game, pretend
|
||||
* to be a non-restored
|
||||
* game */
|
||||
if (cturn == 0)
|
||||
rflag = 0;
|
||||
} else {
|
||||
rscore = wscore = 0; /* zero score */
|
||||
text (message); /* update message
|
||||
* without pausing */
|
||||
|
||||
if (aflag) { /* print rules */
|
||||
writel (rules);
|
||||
if (yorn(0)) {
|
||||
|
||||
fixtty (old); /* restore tty */
|
||||
execl (TEACH,"backgammon",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 ();
|
||||
exit(0);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
522
games/backgammon/move.c
Normal file
522
games/backgammon/move.c
Normal file
@@ -0,0 +1,522 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)move.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#include "back.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
FILE *trace;
|
||||
static char tests[20];
|
||||
#endif
|
||||
|
||||
struct BOARD { /* structure of game position */
|
||||
int b_board[26]; /* board position */
|
||||
int b_in[2]; /* men in */
|
||||
int b_off[2]; /* men off */
|
||||
int b_st[4], b_fn[4]; /* moves */
|
||||
|
||||
struct BOARD *b_next; /* forward queue pointer */
|
||||
};
|
||||
|
||||
struct BOARD *freeq = (struct BOARD *)-1;
|
||||
struct BOARD *checkq = (struct BOARD *)-1;
|
||||
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();
|
||||
|
||||
/* fix dice */
|
||||
if (d0) swap;
|
||||
|
||||
/* 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 == (struct BOARD *)-1) { /* check if queue empty */
|
||||
checkq = p = new;
|
||||
p->b_next = (struct BOARD *)-1;
|
||||
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 != (struct BOARD *)-1) { /* 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 = (struct BOARD *)-1;
|
||||
}
|
||||
|
||||
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 == (struct BOARD *)-1) {
|
||||
new = (struct BOARD *)calloc (1,sizeof (struct BOARD));
|
||||
if (new == 0) {
|
||||
writel ("\nOut of memory\n");
|
||||
getout();
|
||||
}
|
||||
new->b_next = (struct BOARD *)-1;
|
||||
return (new);
|
||||
}
|
||||
|
||||
new = freeq;
|
||||
freeq = freeq->b_next;
|
||||
return (new);
|
||||
}
|
||||
|
||||
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 */
|
||||
brdcopy (checkq);
|
||||
next = checkq->b_next;
|
||||
makefree (checkq);
|
||||
checkq = next;
|
||||
movcmp();
|
||||
} while (checkq != (struct BOARD *)-1);
|
||||
|
||||
brdcopy (now);
|
||||
}
|
||||
|
||||
brdcopy (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));
|
||||
}
|
||||
}
|
||||
80
games/backgammon/odds.c
Normal file
80
games/backgammon/odds.c
Normal file
@@ -0,0 +1,80 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)odds.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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());
|
||||
}
|
||||
136
games/backgammon/one.c
Normal file
136
games/backgammon/one.c
Normal file
@@ -0,0 +1,136 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)one.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
5
games/backgammon/proto.message.c
Normal file
5
games/backgammon/proto.message.c
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Don't touch this file without checking Mesgfix */
|
||||
char *message[] = {
|
||||
/* this line gets replace with the date */
|
||||
0
|
||||
};
|
||||
147
games/backgammon/save.c
Normal file
147
games/backgammon/save.c
Normal file
@@ -0,0 +1,147 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)save.c 1.1 94/10/31 SMI"; /* from UCB 4.2 82/11/27 */
|
||||
#endif
|
||||
|
||||
#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 ();
|
||||
}
|
||||
447
games/backgammon/subs.c
Normal file
447
games/backgammon/subs.c
Normal file
@@ -0,0 +1,447 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)subs.c 1.1 94/10/31 SMI"; /* from UCB 4.2 82/11/27 */
|
||||
#endif
|
||||
|
||||
#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");
|
||||
if (c == '\177')
|
||||
getout();
|
||||
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;
|
||||
{
|
||||
extern int errno;
|
||||
|
||||
if (tflag)
|
||||
newpos();
|
||||
buflush();
|
||||
tty.sg_flags = mode;
|
||||
if (stty (0,&tty) < 0) {
|
||||
write (2,"\n",1);
|
||||
perror ("fixtty");
|
||||
exit(errno);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
275
games/backgammon/table.c
Normal file
275
games/backgammon/table.c
Normal file
@@ -0,0 +1,275 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)table.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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);
|
||||
}
|
||||
130
games/backgammon/teach.c
Normal file
130
games/backgammon/teach.c
Normal file
@@ -0,0 +1,130 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)teach.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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 char *s;
|
||||
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();
|
||||
exit(0);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
99
games/backgammon/text.c
Normal file
99
games/backgammon/text.c
Normal file
@@ -0,0 +1,99 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)text.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#include "back.h"
|
||||
|
||||
char *instr[] = {
|
||||
" If you did not notice by now, this program reacts to things as",
|
||||
"soon as you type them, without waiting for a newline. This means that",
|
||||
"the special characters RUBOUT, ESC, and CONTROL-D, will not perform",
|
||||
"their special functions during most of this program. The program",
|
||||
"should usually stop when a RUBOUT is typed, but occasionally it will",
|
||||
"ignore RUBOUTs until it is waiting for input.\n",
|
||||
" These instructions are presented in small chunks designed not to",
|
||||
"roll off the top of your screen. When the characters '-->' are print-",
|
||||
"ed, no more data will be printed until a space or newline is typed.",
|
||||
"In this way, you can finish one section before continuing to another.",
|
||||
"Like this:",
|
||||
"",
|
||||
" The two sides are colored 'red' and 'white.' The computer may play",
|
||||
"one side, or if there are two players, the computer can merely act as",
|
||||
"a gamekeeper, letting the players make the moves. Once you tell the",
|
||||
"computer what color(s) you want to play, the decision remains in ef-",
|
||||
"fect until you quit the program, even if you play more than one game,",
|
||||
"since the program keeps a running score.\n",
|
||||
" The program will prompt for a move in one of two ways. If the",
|
||||
"player has the opportunity to double, then merely his color will be",
|
||||
"typed out. The player can now do one of several things. He can dou-",
|
||||
"ble by typing a 'd', he can roll by typing a space (' ') or newline,",
|
||||
"or if he is not sure, he can reprint the board by typing a 'r'.\n",
|
||||
" If the player cannot double, his roll will be thrust in front of",
|
||||
"him, followed by the request 'Move:', asking for a move but not giving",
|
||||
"him the chance to double. He can still ask for the board by typing",
|
||||
"'r'. In either of these two states, the player can quit by typing 'q'",
|
||||
"or save the game by typing 's'. In either case, the player will be",
|
||||
"asked to verify, in case there was some error. The program then ends",
|
||||
"immediately, after first saving the file if so requested.",
|
||||
"",
|
||||
" A player can move one of his men using two forms of input. The",
|
||||
"first form is <s>-<f>, where <s> is the starting position, and <f> is",
|
||||
"the finishing position of the player's man. For example, if white",
|
||||
"wanted to move a piece from position 13 to position 8, his move could",
|
||||
"be entered as 13-8. The second form is <s>/<r> where <s> is the",
|
||||
"starting position, an <r> is the roll actually made. Hence, white",
|
||||
"could have entered as 13/5 instead of 13-8.\n",
|
||||
" A player must move each roll of the dice separately. For example,",
|
||||
"if a player rolled 4 3, and wanted to move from 13 to 6, he could",
|
||||
"enter it as 13/4,9/3 or 13/3,10/4 or 13-10,10-6 or 13-9,9-6, but not",
|
||||
"13-6. The last two entries can be shortened to 13-10-6 and 13-9-6.",
|
||||
"If you want to move more than one piece from the same position, such",
|
||||
"as 13-10,13-9, you can abbreviate this using the <s>/<r> format as by",
|
||||
"entering more than one <r>, or 13/34. A player can use both forms for",
|
||||
"the same roll, e.g. 13/3,13-9, and separates individual moves by ei-",
|
||||
"ther a comma or a space. The letter 'b' represents the bar, and the",
|
||||
"letter 'h' represents a player's home. You could also enter the",
|
||||
"number that would be in the position of the bar, 25 or 0 as appropri-",
|
||||
"ate. Use a newline at the end of your moves for a turn.",
|
||||
"",
|
||||
" As you type in your move, if a character does not make sense under",
|
||||
"the above constrictions, a bell will sound instead of the character,",
|
||||
"and it will be ignored. You may kill lines and erase characters as",
|
||||
"you would normally, but don't be surprised if they look different than",
|
||||
"usual. Also, if you have entered one or more of your rolls, and you",
|
||||
"wish to see what the move looks like so far, type a 'r' to see what it",
|
||||
"looks like. This cannot be done in the middle of a move (e.g., after",
|
||||
"a '-' or '/'). After the printing board, the program will go back to",
|
||||
"inputting your move and you can backspace or kill just as if you had",
|
||||
"just typed in your input.\n",
|
||||
" Now you should be ready to begin the game. Good luck!",
|
||||
"",
|
||||
0};
|
||||
|
||||
|
||||
text (t)
|
||||
char **t;
|
||||
|
||||
{
|
||||
register int i;
|
||||
register char *s, *a;
|
||||
|
||||
fixtty (noech);
|
||||
while (*t != 0) {
|
||||
s = a = *t;
|
||||
for (i = 0; *a != '\0'; i--)
|
||||
a++;
|
||||
if (i) {
|
||||
writel (s);
|
||||
writec ('\n');
|
||||
} else {
|
||||
writel ("-->");
|
||||
fixtty (raw);
|
||||
while ((i = readc()) != ' ' && i != '\n');
|
||||
fixtty (noech);
|
||||
clear();
|
||||
}
|
||||
t++;
|
||||
}
|
||||
fixtty (raw);
|
||||
}
|
||||
151
games/backgammon/ttext1.c
Normal file
151
games/backgammon/ttext1.c
Normal file
@@ -0,0 +1,151 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)ttext1.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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};
|
||||
160
games/backgammon/ttext2.c
Normal file
160
games/backgammon/ttext2.c
Normal file
@@ -0,0 +1,160 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)ttext2.c 1.1 94/10/31 SMI"; /* from UCB 4.2 82/10/24 */
|
||||
#endif
|
||||
|
||||
#include "back.h"
|
||||
|
||||
char *prompt, *opts, *list[];
|
||||
|
||||
char *doubl[] = {
|
||||
"\nDoubling:",
|
||||
"\n If a player thinks he is in a good position, he may double the",
|
||||
"value of the game. However, his opponent may not accept the pro-",
|
||||
"posal and forfeit the game before the price gets too high. A",
|
||||
"player must double before he rolls, and once his double has been",
|
||||
"accepted, he cannot double again, until his opponent has doubled.",
|
||||
"Thus, unless the game swings back and forth in advantage between",
|
||||
"the two players a great deal, the value of the game should be",
|
||||
"low. At any rate, the value of the game will never go above 64,",
|
||||
"or six doubles. However, if a player wins a backgammon at 64",
|
||||
"points, he wins 192 points!",
|
||||
"",
|
||||
0};
|
||||
|
||||
char *stragy[] = {
|
||||
"\nStrategy:",
|
||||
"\n Some general hints when playing: Try not to leave men open",
|
||||
"unless absolutely necessary. Also, it is good to make as many",
|
||||
"points as possible. Often, two men from different positions can",
|
||||
"be brought together to form a new point. Although walls (six",
|
||||
"points in a row) are difficult to form, many points nestled close-",
|
||||
"ly together produce a formidable barrier. Also, while it is good",
|
||||
"to move back men forward, doing so lessens the opportunity for you",
|
||||
"to hit men. Finally, remember that once the two player's have",
|
||||
"passed each other on the board, there is no chance of either team",
|
||||
"being hit, so the game reduces to a race off the board. Addi-",
|
||||
"tional hints on strategy are presented in the practice game.",
|
||||
"",
|
||||
0};
|
||||
|
||||
char *prog[] = {
|
||||
"\nThe Program and How It Works:",
|
||||
"\n A general rule of thumb is when you don't know what to do,",
|
||||
"type a question mark, and you should get some help. When it is",
|
||||
"your turn, only your color will be printed out, with nothing",
|
||||
"after it. You may double by typing a 'd', but if you type a",
|
||||
"space or newline, you will get your roll. (Remember, you must",
|
||||
"double before you roll.) Also, typing a 'r' will reprint the",
|
||||
"board, and a 'q' will quit the game. The program will type",
|
||||
"'Move:' when it wants your move, and you may indicate each die's",
|
||||
"move with <s>-<f>, where <s> is the starting position and <f> is",
|
||||
"the finishing position, or <s>/<r> where <r> is the roll made.",
|
||||
"<s>-<f1>-<f2> is short for <s>-<f1>,<f1>-<f2> and <s>/<r1><r2> is",
|
||||
"short for <s>/<r1>,<s>/<r2>. Moves may be separated by a comma",
|
||||
"or a space.",
|
||||
"",
|
||||
"\n While typing, any input which does not make sense will not be",
|
||||
"echoed, and a bell will sound instead. Also, backspacing and",
|
||||
"killing lines will echo differently than normal. You may examine",
|
||||
"the board by typing a 'r' if you have made a partial move, or be-",
|
||||
"fore you type a newline, to see what the board looks like. You",
|
||||
"must end your move with a newline. If you cannot double, your",
|
||||
"roll will always be printed, and you will not be given the oppor-",
|
||||
"tunity to double. Home and bar are represented by the appropri-",
|
||||
"ate number, 0 or 25 as the case may be, or by the letters 'h' or",
|
||||
"'b' as appropriate. You may also type 'r' or 'q' when the program",
|
||||
"types 'Move:', which has the same effect as above. Finally, you",
|
||||
"will get to decide if you want to play red or white (or both if you",
|
||||
"want to play a friend) at the beginning of the session, and you",
|
||||
"will not get to change your mind later, since the computer keeps",
|
||||
"score.",
|
||||
"",
|
||||
0};
|
||||
|
||||
char *lastch[] = {
|
||||
"\nTutorial (Practice Game):",
|
||||
"\n This tutorial, for simplicity's sake, will let you play one",
|
||||
"predetermined game. All the rolls have been pre-arranged, and",
|
||||
"only one response will let you advance to the next move.",
|
||||
"Although a given roll will may have several legal moves, the tu-",
|
||||
"torial will only accept one (not including the same moves in a",
|
||||
"different order), claiming that that move is 'best.' Obviously,",
|
||||
"a subjective statement. At any rate, be patient with it and have",
|
||||
"fun learning about backgammon. Also, to speed things up a lit-",
|
||||
"tle, doubling will not take place in the tutorial, so you will",
|
||||
"never get that opportunity, and quitting only leaves the tutori-",
|
||||
"al, not the game. You will still be able to play backgammon",
|
||||
"after quitting.",
|
||||
"\n This is your last chance to look over the rules before the tu-",
|
||||
"torial starts.",
|
||||
"",
|
||||
0};
|
||||
|
||||
text (txt)
|
||||
char **txt;
|
||||
|
||||
{
|
||||
char **begin;
|
||||
char *a;
|
||||
char b;
|
||||
char *c;
|
||||
int i;
|
||||
|
||||
fixtty (noech);
|
||||
begin = txt;
|
||||
while (*txt) {
|
||||
a = *(txt++);
|
||||
if (*a != '\0') {
|
||||
c = a;
|
||||
for (i = 0; *(c++) != '\0'; i--);
|
||||
writel (a);
|
||||
writec ('\n');
|
||||
} else {
|
||||
fixtty (raw);
|
||||
writel (prompt);
|
||||
for (;;) {
|
||||
if ((b = readc()) == '?') {
|
||||
if (tflag) {
|
||||
if (begscr) {
|
||||
curmove (18,0);
|
||||
clend();
|
||||
} else
|
||||
clear();
|
||||
} else
|
||||
writec ('\n');
|
||||
text (list);
|
||||
writel (prompt);
|
||||
continue;
|
||||
}
|
||||
i = 0;
|
||||
if (b == '\n')
|
||||
break;
|
||||
while (i < 11) {
|
||||
if (b == opts[i])
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
if (i == 11)
|
||||
writec ('\007');
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (tflag) {
|
||||
if (begscr) {
|
||||
curmove (18,0);
|
||||
clend();
|
||||
} else
|
||||
clear();
|
||||
} else
|
||||
writec ('\n');
|
||||
if (i)
|
||||
return(i);
|
||||
fixtty (noech);
|
||||
if (tflag)
|
||||
curmove (curr,0);
|
||||
begin = txt;
|
||||
}
|
||||
}
|
||||
fixtty (raw);
|
||||
return (0);
|
||||
}
|
||||
122
games/backgammon/tutor.c
Normal file
122
games/backgammon/tutor.c
Normal file
@@ -0,0 +1,122 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)tutor.c 1.1 94/10/31 SMI"; /* from UCB 4.1 82/05/11 */
|
||||
#endif
|
||||
|
||||
#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);
|
||||
}
|
||||
12
games/backgammon/tutor.h
Normal file
12
games/backgammon/tutor.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/* @(#)tutor.h 1.1 94/10/31 SMI; from UCB 4.1 82/05/11 */
|
||||
|
||||
struct situatn {
|
||||
int brd[26];
|
||||
int roll1;
|
||||
int roll2;
|
||||
int mp[4];
|
||||
int mg[4];
|
||||
int new1;
|
||||
int new2;
|
||||
char *(*com[8]);
|
||||
};
|
||||
Reference in New Issue
Block a user