PD Terminfo/Curses (part 11 of 11)
sources at genrad.UUCP
sources at genrad.UUCP
Sat Dec 22 08:41:21 AEST 1984
This is part of a distribution of a public domain version of terminfo/curses
It is a rather large distribution, so I have broken it up into 11 modules
(each less than 64K long.) Each shar format module should end with the line
"exit". This code is completely public domain, originally written by Pavel
Curtis of Cornell University. This version has some small improvements and
bug fixes.
This unit contains:
The demo program "mille".
----------------- cut here ----------------
: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
echo 'Making directory "=test"'
mkdir =test
echo 'Making directory "=test/=mille"'
mkdir =test/=mille
echo 'x - =test/=mille/Makefile'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/Makefile
HEADERS=mille.h
CFILES= comp.c end.c extern.c init.c mille.c misc.c move.c print.c \
roll.c save.c types.c varpush.c
OBJS= comp.o end.o extern.o init.o mille.o misc.o move.o print.o \
roll.o save.o types.o varpush.o
POBJS= comp.po end.po extern.po init.po mille.po misc.po move.po \
roll.po print.po save.po types.po varpush.po
LIBS= ../../=src/libpcurses.a
CFLAGS= -O -DSTANDOUT -I../../=src
X.SUFFIXES: .po .i
X.c.po:
rm -f x.c ; ln $*.c x.c
${CC} ${CFLAGS} -pg -c x.c
mv x.o $*.po
X.c.i:
${CC} ${CFLAGS} -P $*.c
mille: ${OBJS}
${CC} ${CFLAGS} -n -o mille ${OBJS} ${LIBS}
install: mille
cp mille /usr/games
pmb: ${POBJS}
${CC} ${CFLAGS} -n -pg -o pmb ${POBJS} $(LIBS)
mille.po: mille.c
rm -f x.c ; ln mille.c x.c
${CC} ${CFLAGS} -DPROF -p -c x.c
mv x.o mille.po
table: table.o extern.o
${CC} ${CFLAGS} -i -o table table.o extern.o
readdump: readdump.o extern.o varpush.o
${CC} ${CFLAGS} -i -o readdump readdump.o extern.o varpush.o
ctags:
ctags ${HEADERS} ${CFILES}
ed - tags < :ctfix
sort tags -o tags
lint:
lint -hxb ${CFILES} > lint.out
mille.ar:
ar ruv mille.ar Makefile tags ${HEADERS} ${CFILES}
tar:
tar crvf mille.tar Makefile tags :ctfix ${HEADERS} ${CFILES}
lpr:
pr Makefile ${HEADERS} ${CFILES} tags | lpr ; lpq
//go.sysin dd *
echo 'x - =test/=mille/comp.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/comp.c
# include "mille.h"
# define V_VALUABLE 40
calcmove() {
reg CARD card;
reg int *value;
reg PLAY *pp, *op;
reg bool foundend, cango, canstop, foundlow;
reg unsgn int i, count200, badcount, nummin, nummax, diff;
reg int curmin, curmax;
reg CARD safe, oppos;
int valbuf[HAND_SZ], count[NUM_CARDS];
bool playit[HAND_SZ];
wmove(Score, ERR_Y, ERR_X); /* get rid of error messages */
wclrtoeol(Score);
pp = &Player[COMP];
op = &Player[PLAYER];
safe = 0;
cango = 0;
canstop = FALSE;
foundend = FALSE;
for (i = 0; i < NUM_CARDS; i++)
count[i] = 0;
for (i = 0; i < HAND_SZ; i++) {
card = pp->hand[i];
switch (card) {
case C_STOP: case C_CRASH:
case C_FLAT: case C_EMPTY:
if (playit[i] = canplay(pp, op, card))
canstop = TRUE;
goto norm;
case C_LIMIT:
if ((playit[i] = canplay(pp, op, card))
&& Numseen[C_25] == Numcards[C_25]
&& Numseen[C_50] == Numcards[C_50])
canstop = TRUE;
goto norm;
case C_25: case C_50: case C_75:
case C_100: case C_200:
if ((playit[i] = canplay(pp, op, card))
&& pp->mileage + Value[card] == End)
foundend = TRUE;
goto norm;
default:
playit[i] = canplay(pp, op, card);
norm:
if (playit[i])
++cango;
break;
case C_GAS_SAFE: case C_DRIVE_SAFE:
case C_SPARE_SAFE: case C_RIGHT_WAY:
if (pp->battle == opposite(card)
|| (pp->speed == C_LIMIT && card == C_RIGHT_WAY)) {
Movetype = M_PLAY;
Card_no = i;
return;
}
++safe;
playit[i] = TRUE;
break;
}
++count[card];
}
if (pp->hand[0] == C_INIT && Topcard > Deck) {
Movetype = M_DRAW;
return;
}
if (Debug)
fprintf(outf, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n", cango, canstop, safe);
if (foundend)
foundend = !check_ext(TRUE);
for (i = 0; safe && i < HAND_SZ; i++) {
if (issafety(pp->hand[i])) {
if (onecard(op) || (foundend && cango && !canstop)) {
if (Debug)
fprintf(outf, "CALCMOVE: onecard(op) = %d, foundend = %d\n", onecard(op), foundend);
playsafe:
Movetype = M_PLAY;
Card_no = i;
return;
}
oppos = opposite(pp->hand[i]);
if (Numseen[oppos] == Numcards[oppos])
goto playsafe;
else if (!cango
&& (op->can_go || !pp->can_go || Topcard < Deck)) {
card = (Topcard - Deck) - roll(1, 10);
if ((!pp->mileage) != (!op->mileage))
card -= 7;
if (Debug)
fprintf(outf, "CALCMOVE: card = %d, DECK_SZ / 4 = %d\n", card, DECK_SZ / 4);
if (card < DECK_SZ / 4)
goto playsafe;
}
safe--;
playit[i] = cango;
}
}
if (!pp->can_go && !isrepair(pp->battle))
Numneed[opposite(pp->battle)]++;
redoit:
foundlow = (cango || count[C_END_LIMIT] != 0
|| Numseen[C_LIMIT] == Numcards[C_LIMIT]
|| pp->safety[S_RIGHT_WAY] != S_UNKNOWN);
foundend = FALSE;
count200 = pp->nummiles[C_200];
badcount = 0;
curmax = -1;
curmin = 101;
nummin = -1;
nummax = -1;
value = valbuf;
for (i = 0; i < HAND_SZ; i++) {
card = pp->hand[i];
if (issafety(card) || playit[i] == (cango != 0)) {
if (Debug)
fprintf(outf, "CALCMOVE: switch(\"%s\")\n", C_name[card]);
switch (card) {
case C_25: case C_50:
diff = End - pp->mileage;
/* avoid getting too close */
if (Topcard > Deck && cango && diff <= 100
&& diff / Value[card] > count[card]
&& (card == C_25 || diff % 50 == 0)) {
if (card == C_50 && diff - 50 == 25
&& count[C_25] > 0)
goto okay;
*value = 0;
if (--cango <= 0)
goto redoit;
break;
}
okay:
*value = (Value[card] >> 3);
if (pp->speed == C_LIMIT)
++*value;
else
--*value;
if (!foundlow
&& (card == C_50 || count[C_50] == 0)) {
*value = (pp->mileage ? 10 : 20);
foundlow = TRUE;
}
goto miles;
case C_200:
if (++count200 > 2) {
*value = 0;
break;
}
case C_75: case C_100:
*value = (Value[card] >> 3);
if (pp->speed == C_LIMIT)
--*value;
else
++*value;
miles:
if (pp->mileage + Value[card] > End)
*value = (End == 700 ? card : 0);
else if (pp->mileage + Value[card] == End) {
*value = (foundend ? card : V_VALUABLE);
foundend = TRUE;
}
break;
case C_END_LIMIT:
if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
*value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 1);
else if (pp->speed == C_LIMIT && End - pp->mileage <= 50)
*value = 1;
else if (pp->speed == C_LIMIT
|| Numseen[C_LIMIT] != Numcards[C_LIMIT]) {
safe = S_RIGHT_WAY;
oppos = C_LIMIT;
goto repair;
}
else {
*value = 0;
--count[C_END_LIMIT];
}
break;
case C_REPAIRS: case C_SPARE: case C_GAS:
safe = safety(card) - S_CONV;
oppos = opposite(card);
if (pp->safety[safe] != S_UNKNOWN)
*value = (pp->safety[safe] == S_PLAYED ? -1 : 1);
else if (pp->battle != oppos
&& (Numseen[oppos] == Numcards[oppos] || Numseen[oppos] + count[card] > Numcards[oppos])) {
*value = 0;
--count[card];
}
else {
repair:
*value = Numcards[oppos] * 6;
*value += (Numseen[card] - Numseen[oppos]);
if (!cango)
*value /= (count[card]*count[card]);
count[card]--;
}
break;
case C_GO:
if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
*value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 2);
else if (pp->can_go
&& Numgos + count[C_GO] == Numneed[C_GO]) {
*value = 0;
--count[C_GO];
}
else {
*value = Numneed[C_GO] * 3;
*value += (Numseen[C_GO] - Numgos);
*value /= (count[C_GO] * count[C_GO]);
count[C_GO]--;
}
break;
case C_LIMIT:
if (op->mileage + 50 >= End) {
*value = (End == 700 && !cango);
break;
}
if (canstop || (cango && !op->can_go))
*value = 1;
else {
*value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 2 : 3);
safe = S_RIGHT_WAY;
oppos = C_END_LIMIT;
goto normbad;
}
break;
case C_CRASH: case C_EMPTY: case C_FLAT:
safe = safety(card) - S_CONV;
oppos = opposite(card);
*value = (pp->safety[safe]!=S_UNKNOWN ? 3 : 4);
normbad:
if (op->safety[safe] == S_PLAYED)
*value = -1;
else {
*value *= (Numneed[oppos] + Numseen[oppos] + 2);
if (!pp->mileage || foundend || onecard(op))
*value += 5;
if (op->mileage == 0 || onecard(op))
*value += 5;
if (op->speed == C_LIMIT)
*value -= 3;
if (cango && pp->safety[safe] != S_UNKNOWN)
*value += 3;
if (!cango)
*value /= ++badcount;
}
break;
case C_STOP:
if (op->safety[S_RIGHT_WAY] == S_PLAYED)
*value = -1;
else {
*value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 3 : 4);
*value *= (Numcards[C_STOP] + Numseen[C_GO]);
if (!pp->mileage || foundend || onecard(op))
*value += 5;
if (!cango)
*value /= ++badcount;
if (op->mileage == 0)
*value += 5;
if ((card == C_LIMIT
&& op->speed == C_LIMIT) || (!op->can_go))
*value -= 5;
if (cango && pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
*value += 5;
}
break;
case C_GAS_SAFE: case C_DRIVE_SAFE:
case C_SPARE_SAFE: case C_RIGHT_WAY:
*value = cango ? 0 : 101;
break;
case C_INIT:
*value = 0;
}
}
else
*value = cango ? 0 : 101;
if (card != C_INIT) {
if (*value >= curmax) {
nummax = i;
curmax = *value;
}
if (*value <= curmin) {
nummin = i;
curmin = *value;
}
}
if (Debug)
mvprintw(i+6,2,"%3d %-14s",*value,C_name[pp->hand[i]]);
value++;
}
if (!pp->can_go && !isrepair(pp->battle))
Numneed[opposite(pp->battle)]++;
if (cango) {
mvaddstr(MOVE_Y + 1, MOVE_X, "PLAY\n");
if (Debug)
getmove();
if (!Debug || Movetype == M_DRAW) {
Movetype = M_PLAY;
Card_no = nummax;
}
}
else {
mvaddstr(MOVE_Y + 1, MOVE_X, "DISCARD\n");
if (Debug)
getmove();
if (!Debug || Movetype == M_DRAW) {
Movetype = M_DISCARD;
Card_no = nummin;
}
}
mvprintw(MOVE_Y + 2, MOVE_X, "%16s", C_name[pp->hand[Card_no]]);
}
onecard(pp)
reg PLAY *pp; {
reg CARD bat, spd, card;
bat = pp->battle;
spd = pp->speed;
card = -1;
if (pp->can_go || ((isrepair(bat) || bat == C_STOP
|| spd == C_LIMIT) && Numseen[S_RIGHT_WAY] != 0)
|| Numseen[safety(bat)] != 0)
switch (End - pp->mileage) {
case 200:
if (pp->nummiles[C_200] == 2)
return FALSE;
card = C_200;
case 100:
case 75:
if (card == -1)
card = (End - pp->mileage == 75 ? C_75 : C_100);
if (spd == C_LIMIT)
return Numseen[S_RIGHT_WAY] == 0;
case 50:
case 25:
if (card == -1)
card = (End - pp->mileage == 25 ? C_25 : C_50);
return Numseen[card] != Numcards[card];
}
return FALSE;
}
canplay(pp, op, card)
reg PLAY *pp, *op;
reg CARD card; {
switch (card) {
case C_200:
if (pp->nummiles[C_200] == 2)
break;
case C_75: case C_100:
if (pp->speed == C_LIMIT)
break;
case C_50:
if (pp->mileage + Value[card] > End)
break;
case C_25:
if (pp->can_go)
return TRUE;
break;
case C_EMPTY: case C_FLAT: case C_CRASH:
case C_STOP:
if (op->can_go && op->safety[safety(card) - S_CONV] != S_PLAYED)
return TRUE;
break;
case C_LIMIT:
if (op->speed != C_LIMIT && op->safety[S_RIGHT_WAY] != S_PLAYED
&& op->mileage + 50 < End)
return TRUE;
break;
case C_GAS: case C_SPARE: case C_REPAIRS:
if (pp->battle == opposite(card))
return TRUE;
break;
case C_GO:
if (!pp->can_go
&& (isrepair(pp->battle) || pp->battle == C_STOP))
return TRUE;
break;
case C_END_LIMIT:
if (pp->speed == C_LIMIT)
return TRUE;
}
return FALSE;
}
//go.sysin dd *
echo 'x - =test/=mille/end.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/end.c
# include "mille.h"
X/*
* print out the score as if it was final, and add the totals for
* the end-of-games points to the user who deserves it (if any).
*/
finalscore(pp)
reg PLAY *pp; {
reg int temp, tot, num;
num = pp - Player;
temp = num * 6 + 21 + 3;
for (tot = 5; tot <= 9; tot++)
mvaddch(tot, temp, '0');
if (pp->mileage == End) {
temp -= 2;
mvaddstr(5, temp, "40");
tot = SC_TRIP;
if (pp->nummiles[C_200] == 0) {
mvaddstr(6, temp, "30");
tot = SC_TRIP + SC_SAFE;
}
if (Topcard <= Deck) {
mvaddstr(7, temp, "30");
tot += SC_DELAY;
}
if (End == 1000) {
mvaddstr(8, temp, "20");
tot += SC_EXTENSION;
}
if (Player[other(num)].mileage == 0) {
mvaddstr(9, temp, "50");
tot += SC_SHUT_OUT;
}
pp->total += tot;
pp->hand_tot += tot;
}
}
# ifdef EXTRAP
static int Last_tot[2]; /* last tot used for extrapolate */
X/*
* print out the score as if it was final, and add the totals for
* the end-of-games points to the user who deserves it (if any).
*/
extrapolate(pp)
reg PLAY *pp; {
reg int x, num, tot, count;
num = pp - Player;
tot += SC_TRIP + SC_DELAY + SC_EXT;
x = num * 6 + 21 + 3;
for (tot = 5; tot <= 9; tot++)
mvaddch(tot, x, '0');
x -= 2;
pp = &Player[other(num)];
for (count = 0, tot = 0; tot < NUM_SAFE; tot++)
if (pp->safety[tot] != S_PLAYED)
count += SC_SAFE;
mvprintw(3, x, "%3d", count);
tot += count;
if (count == 400) {
mvaddstr(4, x, "30");
tot += SC_ALL_SAFE;
}
pp = &Player[num];
for (count = 0, tot = 0; tot < NUM_SAFE; tot++)
if (pp->safety[tot] != S_PLAYED)
count += SC_COUP / 10;
mvprintw(4, x - 1, "%3d", count);
tot += count;
tot += 1000 - pp->mileage;
mvaddstr(5, x, "40");
mvaddstr(7, x, "30");
mvaddstr(8, x, "20");
if (pp->nummiles[C_200] == 0) {
mvaddstr(6, x, "30");
tot = SC_TRIP + SC_SAFE;
}
if (Player[other(num)].mileage == 0) {
mvaddstr(9, x, "50");
tot += SC_SHUT_OUT;
}
pp->total += tot;
pp->hand_tot += tot;
Last_tot[num] = tot;
}
undoex() {
reg PLAY *pp;
reg int i;
i = 0;
for (pp = Player; pp < &Player[2]; pp++) {
pp->total -= Last_tot[i];
pp->hand_tot -= Last_tot[i++];
}
}
# endif
//go.sysin dd *
echo 'x - =test/=mille/extern.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/extern.c
# include "mille.h"
bool Debug, /* set if debugging code on */
Finished, /* set if current hand is finished */
Next, /* set if changing players */
On_exit, /* set if game saved on exiting */
Order, /* set if hand should be sorted */
Saved; /* set if game just saved */
char *C_fmt = "%-18.18s", /* format for printing cards */
*Fromfile = NULL, /* startup file for game */
Initstr[100], /* initial string for error field */
*_cn[NUM_CARDS] = { /* Card name buffer */
"",
"25",
"50",
"75",
"100",
"200",
"Out of Gas",
"Flat Tire",
"Accident",
"Stop",
"Speed Limit",
"Gasoline",
"Spare Tire",
"Repairs",
"Go",
"End of Limit",
"Extra Tank",
"Puncture Proof",
"Driving Ace",
"Right of Way"
},
**C_name = &_cn[1]; /* Card names */
int Card_no, /* Card number for current move */
End, /* End value for current hand */
Handstart = COMP, /* Player who starts hand */
Movetype, /* Current move type */
Play, /* Current player */
Numgos, /* Number of Go cards used by computer */
Window = W_SMALL, /* Current window wanted */
Numseen[NUM_CARDS], /* Number of cards seen in current hand */
Value[NUM_MILES] = { /* Value of mileage cards */
25, 50, 75, 100, 200
},
Numcards[NUM_CARDS] = { /* Number of cards in deck */
10, /* C_25 */
10, /* C_50 */
10, /* C_75 */
12, /* C_100 */
4, /* C_200 */
2, /* C_EMPTY */
2, /* C_FLAT */
2, /* C_CRASH */
4, /* C_STOP */
3, /* C_LIMIT */
6, /* C_GAS */
6, /* C_SPARE */
6, /* C_REPAIRS */
14, /* C_GO */
6, /* C_END_LIMIT */
1, /* C_GAS_SAFE */
1, /* C_SPARE_SAFE */
1, /* C_DRIVE_SAFE */
1, /* C_RIGHT_WAY */
0 /* C_INIT */
};
Numneed[NUM_CARDS] = { /* number of cards needed per hand */
0, /* C_25 */
0, /* C_50 */
0, /* C_75 */
0, /* C_100 */
0, /* C_200 */
2, /* C_EMPTY */
2, /* C_FLAT */
2, /* C_CRASH */
4, /* C_STOP */
3, /* C_LIMIT */
2, /* C_GAS */
2, /* C_SPARE */
2, /* C_REPAIRS */
10, /* C_GO */
3, /* C_END_LIMIT */
1, /* C_GAS_SAFE */
1, /* C_SPARE_SAFE */
1, /* C_DRIVE_SAFE */
1, /* C_RIGHT_WAY */
0 /* C_INIT */
};
CARD Discard, /* Top of discard pile */
*Topcard, /* Pointer to next card to be picked */
Opposite[NUM_CARDS] = { /* Opposites of each card */
C_25, C_50, C_75, C_100, C_200, C_GAS, C_SPARE,
C_REPAIRS, C_GO, C_END_LIMIT, C_EMPTY, C_FLAT, C_CRASH,
C_STOP, C_LIMIT, C_EMPTY, C_FLAT, C_CRASH, C_STOP, C_INIT
},
Deck[DECK_SZ] = { /* Current deck */
C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25,
C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50,
C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75,
C_100, C_100, C_100, C_100, C_100, C_100, C_100, C_100, C_100,
C_100, C_100, C_100,
C_200, C_200, C_200, C_200,
C_EMPTY, C_EMPTY,
C_FLAT, C_FLAT,
C_CRASH, C_CRASH,
C_STOP, C_STOP, C_STOP, C_STOP,
C_LIMIT, C_LIMIT, C_LIMIT,
C_GAS, C_GAS, C_GAS, C_GAS, C_GAS, C_GAS,
C_SPARE, C_SPARE, C_SPARE, C_SPARE, C_SPARE, C_SPARE,
C_REPAIRS, C_REPAIRS, C_REPAIRS, C_REPAIRS, C_REPAIRS,
C_REPAIRS,
C_END_LIMIT, C_END_LIMIT, C_END_LIMIT, C_END_LIMIT, C_END_LIMIT,
C_END_LIMIT,
C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO,
C_GO, C_GO, C_GO, C_GO,
C_GAS_SAFE, C_SPARE_SAFE, C_DRIVE_SAFE, C_RIGHT_WAY
};
XFILE *outf;
PLAY Player[2]; /* Player descriptions */
WINDOW *Board, /* Playing field screen */
*Miles, /* Mileage screen */
*Score; /* Score screen */
//go.sysin dd *
echo 'x - =test/=mille/init.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/init.c
# include "mille.h"
init() {
reg PLAY *pp;
reg int i, j;
reg CARD card;
for (j = 0; j < C_RIGHT_WAY; j++)
Numseen[j] = 0;
Numgos = 0;
for (i = 0; i < 2; i++) {
pp = &Player[i];
pp->hand[0] = C_INIT;
for (j = 0; j < NUM_SAFE; j++) {
pp->safety[j] = S_UNKNOWN;
pp->coups[j] = FALSE;
}
for (j = 1; j < HAND_SZ; j++) {
pp->hand[j] = *--Topcard;
if (i == COMP) {
account(card = *Topcard);
if (issafety(card))
pp->safety[card - S_CONV] = S_IN_HAND;
}
}
pp->mileage = 0;
pp->hand_tot = 0;
pp->safescore = 0;
pp->coupscore = 0;
pp->can_go = FALSE;
pp->speed = C_INIT;
pp->battle = C_INIT;
pp->new_speed = FALSE;
pp->new_battle = FALSE;
for (j = 0; j < NUM_MILES; j++)
pp->nummiles[j] = 0;
}
if (Order)
sort(Player[PLAYER].hand);
Discard = C_INIT;
Finished = FALSE;
End = 700;
}
shuffle() {
reg int i, r;
reg CARD temp;
for (i = 0; i < DECK_SZ; i++) {
r = roll(1, DECK_SZ) - 1;
if (r < 0 || r > DECK_SZ - 1) {
fprintf(stderr, "shuffle: card no. error: %d\n", r);
die();
}
temp = Deck[r];
Deck[r] = Deck[i];
Deck[i] = temp;
}
Topcard = &Deck[DECK_SZ];
}
newboard() {
werase(Board);
werase(Score);
mvaddstr(5, 0, "--HAND--");
mvaddch(6, 0, 'P');
mvaddch(7, 0, '1');
mvaddch(8, 0, '2');
mvaddch(9, 0, '3');
mvaddch(10, 0, '4');
mvaddch(11, 0, '5');
mvaddch(12, 0, '6');
mvaddstr(13, 0, "--BATTLE--");
mvaddstr(15, 0, "--SPEED--");
mvaddstr(5, 20, "--DECK--");
mvaddstr(7, 20, "--DISCARD--");
mvaddstr(13, 20, "--BATTLE--");
mvaddstr(15, 20, "--SPEED--");
wmove(Miles, 0, 0);
if (winch(Miles) != '-') {
werase(Miles);
mvwaddstr(Miles, 0, 0, "--MILEAGE--");
mvwaddstr(Miles, 0, 41, "--MILEAGE--");
}
else {
wmove(Miles, 1, 0);
wclrtobot(Miles);
}
newscore();
stdscr = Board;
}
newscore() {
reg int i;
stdscr = Score;
move(0, 22);
if (inch() != 'Y') {
erase();
mvaddstr(0, 22, "You Comp Value");
mvaddstr(1, 2, "Milestones Played");
mvaddstr(2, 8, "Each Safety");
mvaddstr(3, 5, "All 4 Safeties");
mvaddstr(4, 3, "Each Coup Fourre");
mvaddstr(2, 37, "100");
mvaddstr(3, 37, "300");
mvaddstr(4, 37, "300");
}
else {
move(5, 1);
clrtobot();
}
for (i = 0; i < SCORE_Y; i++)
mvaddch(i, 0, '|');
move(SCORE_Y - 1, 1);
while (addch('_') != ERR)
continue;
if (Window == W_FULL || Finished) {
mvaddstr(5, 5, "Trip Completed");
mvaddstr(6, 10, "Safe Trip");
mvaddstr(7, 5, "Delayed Action");
mvaddstr(8, 10, "Extension");
mvaddstr(9, 11, "Shut-Out");
mvaddstr(10, 21, "---- ---- -----");
mvaddstr(11, 9, "Hand Total");
mvaddstr(12, 20, "----- -----");
mvaddstr(13, 6, "Overall Total");
mvaddstr(14, 15, "Games");
mvaddstr(5, 37, "400");
mvaddstr(6, 37, "300");
mvaddstr(7, 37, "300");
mvaddstr(8, 37, "200");
mvaddstr(9, 37, "500");
}
else {
mvaddstr(5, 21, "---- ---- -----");
mvaddstr(6, 9, "Hand Total");
mvaddstr(7, 20, "----- -----");
mvaddstr(8, 6, "Overall Total");
mvaddstr(9, 15, "Games");
mvaddstr(11, 2, "p: pick");
mvaddstr(12, 2, "u: use #");
mvaddstr(13, 2, "d: discard #");
mvaddstr(14, 2, "w: toggle window");
mvaddstr(11, 21, "q: quit");
mvaddstr(12, 21, "o: order hand");
mvaddstr(13, 21, "s: save");
mvaddstr(14, 21, "r: reprint");
}
stdscr = Board;
}
//go.sysin dd *
echo 'x - =test/=mille/mille.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/mille.c
# include "mille.h"
# include <signal.h>
# include <term.h>
int rub();
char _sobuf[BUFSIZ];
main(ac, av)
reg int ac;
reg char *av[]; {
reg bool restore;
# if 0
if (getuid() == GURP) {
printf("%s: Permission denied\n", av[0]);
exit(1);
}
# endif
if (strcmp(av[0], "a.out") == 0) {
outf = fopen("q", "w");
setbuf(outf, 0);
Debug = TRUE;
}
restore = FALSE;
# ifdef pdp11
if (geteuid() != ARNOLD)
maxusers(MAXUSERS, NULL);
# endif
switch (ac) {
case 2:
rest_f(av[1]);
restore = TRUE;
case 1:
break;
default:
printf("usage: milles [ restore_file ]\n");
exit(-1);
/* NOTREACHED */
}
setbuf(stdout, _sobuf);
Play = PLAYER;
initscr();
if (! cursor_address) {
printf("Sorry. Need cursor addressing to play mille\n");
exit(-1);
}
delwin(stdscr);
stdscr = Board = newwin(BOARD_Y, BOARD_X, 0, 0);
Score = newwin(SCORE_Y, SCORE_X, 0, 40);
Miles = newwin(MILES_Y, MILES_X, 17, 0);
leaveok(Score, TRUE);
leaveok(Miles, TRUE);
clearok(curscr, TRUE);
# ifndef PROF
srand(getpid());
# else
srand(0);
# endif
crmode();
noecho();
nonl();
signal(SIGINT, rub);
for (;;) {
if (!restore || (Player[PLAYER].total >= 5000
|| Player[COMP].total >= 5000)) {
if (Player[COMP].total < Player[PLAYER].total)
Player[PLAYER].games++;
else if (Player[COMP].total > Player[PLAYER].total)
Player[COMP].games++;
Player[COMP].total = 0;
Player[PLAYER].total = 0;
}
do {
if (!restore)
Handstart = Play = other(Handstart);
if (!restore || On_exit) {
shuffle();
init();
}
newboard();
if (restore)
mvwaddstr(Score, ERR_Y, ERR_X, Initstr);
prboard();
do {
domove();
if (Finished)
newscore();
prboard();
} while (!Finished);
check_more();
restore = On_exit = FALSE;
} while (Player[COMP].total < 5000
&& Player[PLAYER].total < 5000);
}
}
X/*
* Routine to trap rubouts, and make sure they really want to
* quit.
*/
rub() {
signal(SIGINT, 1);
if (getyn("Really? "))
die();
signal(SIGINT, rub);
}
X/*
* Time to go beddy-by
*/
die() {
signal(SIGINT, 1);
if (outf)
fflush(outf);
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
exit(1);
}
//go.sysin dd *
echo 'x - =test/=mille/mille.h'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/mille.h
# include <ctype.h>
# include <curses.h>
X/*
* Miscellaneous constants
*/
# define unsgn unsigned
# define reg register
# define CARD short
# ifdef vax
# define ARNOLD 78 /* my uid */
# else
# define ARNOLD 24601 /* my uid */
# endif
# define GURP 28672 /* bad uid */
# define MAXUSERS 35 /* max # of users for startup */
# define HAND_SZ 7 /* number of cards in a hand */
# define DECK_SZ 101 /* number of cards in decks */
# define NUM_SAFE 4 /* number of saftey cards */
# define NUM_MILES 5 /* number of milestones types */
# define NUM_CARDS 20 /* number of types of cards */
# define BOARD_Y 17 /* size of board screen */
# define BOARD_X 40
# define MILES_Y 7 /* size of mileage screen */
# define MILES_X 80
# define SCORE_Y 17 /* size of score screen */
# define SCORE_X 40
# define MOVE_Y 10 /* Where to print move prompt */
# define MOVE_X 20
# define ERR_Y 15 /* Where to print errors */
# define ERR_X 5
# define EXT_Y 4 /* Where to put Extension */
# define EXT_X 9
# define PLAYER 0
# define COMP 1
# define W_SMALL 0 /* Small (initial) window */
# define W_FULL 1 /* Full (final) window */
X/*
* Move types
*/
# define M_DISCARD 0
# define M_DRAW 1
# define M_PLAY 2
# define M_ORDER 3
X/*
* Scores
*/
# define SC_SAFETY 100
# define SC_ALL_SAFE 300
# define SC_COUP 300
# define SC_TRIP 400
# define SC_SAFE 300
# define SC_DELAY 300
# define SC_EXTENSION 200
# define SC_SHUT_OUT 500
X/*
* safety descriptions
*/
# define S_UNKNOWN 0 /* location of safety unknown */
# define S_IN_HAND 1 /* safety in player's hand */
# define S_PLAYED 2 /* safety has been played */
# define S_GAS_SAFE 0 /* Gas safety card index */
# define S_SPARE_SAFE 1 /* Tire safety card index */
# define S_DRIVE_SAFE 2 /* Driveing safety card index */
# define S_RIGHT_WAY 3 /* Right-of-Way card index */
# define S_CONV 15 /* conversion from C_ to S_ */
X/*
* card numbers
*/
# define C_INIT -1
# define C_25 0
# define C_50 1
# define C_75 2
# define C_100 3
# define C_200 4
# define C_EMPTY 5
# define C_FLAT 6
# define C_CRASH 7
# define C_STOP 8
# define C_LIMIT 9
# define C_GAS 10
# define C_SPARE 11
# define C_REPAIRS 12
# define C_GO 13
# define C_END_LIMIT 14
# define C_GAS_SAFE 15
# define C_SPARE_SAFE 16
# define C_DRIVE_SAFE 17
# define C_RIGHT_WAY 18
typedef struct {
bool coups[NUM_SAFE];
bool can_go;
bool new_battle;
bool new_speed;
short safety[NUM_SAFE];
short nummiles[NUM_MILES];
CARD hand[HAND_SZ];
CARD battle;
CARD speed;
int mileage;
int hand_tot;
int safescore;
int coupscore;
int total;
int games;
} PLAY;
X/*
* macros
*/
# define other(x) (1 - x)
# define nextplay() (Play = other(Play))
# define nextwin(x) (1 - x)
# define opposite(x) (Opposite[x])
# define issafety(x) (x >= C_GAS_SAFE)
X/*
* externals
*/
extern bool Debug, Finished, Next, On_exit, Order, Saved;
extern char *C_fmt, **C_name, *Fromfile, Initstr[];
extern int Card_no, End, Handstart, Movetype, Numcards[], Numgos,
Numneed[], Numseen[NUM_CARDS], Play, Value[], Window;
extern CARD Deck[DECK_SZ], Discard, Opposite[NUM_CARDS], *Topcard;
extern FILE *outf;
extern PLAY Player[2];
extern WINDOW *Board, *Miles, *Score;
X/*
* functions
*/
CARD getcard();
//go.sysin dd *
echo 'x - =test/=mille/misc.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/misc.c
#include "mille.h"
#include "unctrl.h"
#define NUMSAFE 4
X/* VARARGS1 */
error(str, arg)
char *str;
{
stdscr = Score;
mvprintw(ERR_Y, ERR_X, str, arg);
clrtoeol();
putchar('');
refresh();
stdscr = Board;
return FALSE;
}
CARD
getcard()
{
reg char c, c1;
for (;;) {
while ((c = getch()) == '\n' || c == '\r' || c == ' ')
continue;
if (islower(c))
c = toupper(c);
if (c == killchar() || c == erasechar())
return -1;
addstr(unctrl(c));
clrtoeol();
switch (c) {
case '1': case '2': case '3':
case '4': case '5': case '6':
c -= '0';
break;
case '0': case 'P': case 'p':
c = 0;
break;
default:
putchar('');
addch('\b');
if (!isprint(c))
addch('\b');
c = -1;
break;
}
refresh();
if (c >= 0) {
while ((c1=getch()) != '\r' && c1 != '\n' && c1 != ' ')
if (c1 == killchar())
return -1;
else if (c1 == erasechar()) {
addch('\b');
clrtoeol();
refresh();
goto cont;
}
else
write(0, "", 1);
return c;
}
cont: ;
}
}
check_ext(forcomp)
reg bool forcomp; {
if (End == 700)
if (Play == PLAYER) {
if (getyn("Extension? ")) {
extend:
if (!forcomp)
End = 1000;
return TRUE;
}
else {
done:
if (!forcomp)
Finished = TRUE;
return FALSE;
}
}
else {
reg PLAY *pp, *op;
reg int i, safe, miles;
pp = &Player[COMP];
op = &Player[PLAYER];
for (safe = 0, i = 0; i < NUMSAFE; i++)
if (pp->safety[i] != S_UNKNOWN)
safe++;
if (safe < 2)
goto done;
if (op->mileage == 0 || onecard(op)
|| (op->can_go && op->mileage >= 500))
goto done;
for (miles = 0, i = 0; i < NUMSAFE; i++)
if (op->safety[i] != S_PLAYED
&& pp->safety[i] == S_UNKNOWN)
miles++;
if (miles + safe == NUMSAFE)
goto extend;
for (miles = 0, i = 0; i < HAND_SZ; i++)
if ((safe = pp->hand[i]) <= C_200)
miles += Value[safe];
if (miles + (Topcard - Deck) * 3 > 1000)
goto extend;
goto done;
}
else
goto done;
}
X/*
* Get a yes or no answer to the given question. Saves are
* also allowed. Return TRUE if the answer was yes, FALSE if no.
*/
getyn(prompt)
reg char *prompt; {
reg char c;
Saved = FALSE;
for (;;) {
leaveok(Board, FALSE);
mvaddstr(MOVE_Y, MOVE_X, prompt);
clrtoeol();
refresh();
switch (c = getch()) {
case 'n': case 'N':
addch('N');
refresh();
leaveok(Board, TRUE);
return FALSE;
case 'y': case 'Y':
addch('Y');
refresh();
leaveok(Board, TRUE);
return TRUE;
case 's': case 'S':
addch('S');
refresh();
Saved = save();
continue;
default:
addstr(unctrl(c));
refresh();
putchar('');
break;
}
}
}
X/*
* Check to see if more games are desired. If not, and game
* came from a saved file, make sure that they don't want to restore
* it. Exit appropriately.
*/
check_more() {
raw(); /* Flush input */
noraw();
On_exit = TRUE;
if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000)
if (getyn("Another game? "))
return;
else {
/*
* must do accounting normally done in main()
*/
if (Player[PLAYER].total > Player[COMP].total)
Player[PLAYER].games++;
else if (Player[PLAYER].total < Player[COMP].total)
Player[COMP].games++;
Player[COMP].total = 0;
Player[PLAYER].total = 0;
}
else
if (getyn("Another hand? "))
return;
if (!Saved && getyn("Save game? "))
if (!save())
return;
die();
}
//go.sysin dd *
echo 'x - =test/=mille/move.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/move.c
#include "mille.h"
#include "unctrl.h"
#define CTRL(c) (c - 'A' + 1)
char *Movenames[] = {
"M_DISCARD", "M_DRAW", "M_PLAY", "M_ORDER"
};
domove()
{
reg PLAY *pp;
reg int i, j;
reg bool goodplay;
pp = &Player[Play];
if (Play == PLAYER)
getmove();
else
calcmove();
Next = FALSE;
goodplay = TRUE;
switch (Movetype) {
case M_DISCARD:
if (haspicked(pp)) {
if (pp->hand[Card_no] == C_INIT)
if (Card_no == 6)
Finished = TRUE;
else
error("no card there");
else {
Discard = pp->hand[Card_no];
pp->hand[Card_no] = C_INIT;
Next = TRUE;
if (Play == PLAYER)
account(Discard);
}
}
else
error("must pick first");
break;
case M_PLAY:
goodplay = playcard(pp);
break;
case M_DRAW:
Card_no = 0;
if (Topcard <= Deck)
error("no more cards");
else if (haspicked(pp))
error("already picked");
else {
pp->hand[0] = *--Topcard;
if (Debug)
fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
acc:
if (Play == COMP) {
account(*Topcard);
if (issafety(*Topcard))
pp->safety[*Topcard-S_CONV] = S_IN_HAND;
}
if (pp->hand[1] == C_INIT && Topcard > Deck) {
Card_no = 1;
pp->hand[1] = *--Topcard;
if (Debug)
fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
goto acc;
}
pp->new_battle = FALSE;
pp->new_speed = FALSE;
}
break;
case M_ORDER:
break;
}
/*
* move blank card to top by one of two methods. If the
* computer's hand was sorted, the randomness for picking
* between equally valued cards would be lost
*/
if (Order && Movetype != M_DRAW && goodplay && pp == &Player[PLAYER])
sort(pp->hand);
else
for (i = 1; i < HAND_SZ; i++)
if (pp->hand[i] == C_INIT) {
for (j = 0; pp->hand[j] == C_INIT; j++)
if (j >= HAND_SZ) {
j = 0;
break;
}
pp->hand[i] = pp->hand[j];
pp->hand[j] = C_INIT;
}
if (Topcard <= Deck)
check_go();
if (Next)
nextplay();
}
X/*
* Check and see if either side can go. If they cannot,
* the game is over
*/
check_go() {
reg CARD card;
reg PLAY *pp, *op;
reg int i;
for (pp = Player; pp < &Player[2]; pp++) {
op = (pp == &Player[COMP] ? &Player[PLAYER] : &Player[COMP]);
for (i = 0; i < HAND_SZ; i++) {
card = pp->hand[i];
if (issafety(card) || canplay(pp, op, card)) {
if (Debug) {
fprintf(outf, "CHECK_GO: can play %s (%d), ", C_name[card], card);
fprintf(outf, "issafety(card) = %d, ", issafety(card));
fprintf(outf, "canplay(pp, op, card) = %d\n", canplay(pp, op, card));
}
return;
}
else if (Debug)
fprintf(outf, "CHECK_GO: cannot play %s\n",
C_name[card]);
}
}
Finished = TRUE;
}
playcard(pp)
reg PLAY *pp;
{
reg int v;
reg CARD card;
/*
* check and see if player has picked
*/
switch (pp->hand[Card_no]) {
default:
if (!haspicked(pp))
mustpick:
return error("must pick first");
case C_GAS_SAFE: case C_SPARE_SAFE:
case C_DRIVE_SAFE: case C_RIGHT_WAY:
break;
}
card = pp->hand[Card_no];
if (Debug)
fprintf(outf, "PLAYCARD: Card = %s\n", C_name[card]);
Next = FALSE;
switch (card) {
case C_200:
if (pp->nummiles[C_200] == 2)
return error("only two 200's per hand");
case C_100: case C_75:
if (pp->speed == C_LIMIT)
return error("limit of 50");
case C_50:
if (pp->mileage + Value[card] > End)
return error("puts you over %d", End);
case C_25:
if (!pp->can_go)
return error("cannot move now");
pp->nummiles[card]++;
v = Value[card];
pp->total += v;
pp->hand_tot += v;
if ((pp->mileage += v) == End)
check_ext(FALSE);
break;
case C_GAS: case C_SPARE: case C_REPAIRS:
if (pp->battle != opposite(card))
return error("can't play \"%s\"", C_name[card]);
pp->battle = card;
if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
pp->can_go = TRUE;
break;
case C_GO:
if (pp->battle != C_INIT && pp->battle != C_STOP
&& !isrepair(pp->battle))
return error("cannot play \"Go\" on a \"%s\"",
C_name[pp->battle]);
pp->battle = C_GO;
pp->can_go = TRUE;
break;
case C_END_LIMIT:
if (pp->speed != C_LIMIT)
return error("not limited");
pp->speed = C_END_LIMIT;
break;
case C_EMPTY: case C_FLAT: case C_CRASH:
case C_STOP:
pp = &Player[other(Play)];
if (!pp->can_go)
return error("opponent cannot go");
else if (pp->safety[safety(card) - S_CONV] == S_PLAYED)
protected:
return error("opponent is protected");
pp->battle = card;
pp->new_battle = TRUE;
pp->can_go = FALSE;
pp = &Player[Play];
break;
case C_LIMIT:
pp = &Player[other(Play)];
if (pp->speed == C_LIMIT)
return error("opponent has limit");
if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
goto protected;
pp->speed = C_LIMIT;
pp->new_speed = TRUE;
pp = &Player[Play];
break;
case C_GAS_SAFE: case C_SPARE_SAFE:
case C_DRIVE_SAFE: case C_RIGHT_WAY:
if (pp->battle == opposite(card)
|| (card == C_RIGHT_WAY && pp->speed == C_LIMIT)) {
if (!(card == C_RIGHT_WAY && !isrepair(pp->battle))) {
pp->battle = C_GO;
pp->can_go = TRUE;
}
if (card == C_RIGHT_WAY && pp->speed == C_LIMIT)
pp->speed = C_INIT;
if (pp->new_battle
|| (pp->new_speed && card == C_RIGHT_WAY)) {
pp->coups[card - S_CONV] = TRUE;
pp->total += SC_COUP;
pp->hand_tot += SC_COUP;
pp->coupscore += SC_COUP;
}
}
/*
* if not coup, must pick first
*/
else if (pp->hand[0] == C_INIT && Topcard > Deck)
goto mustpick;
pp->safety[card - S_CONV] = S_PLAYED;
pp->total += SC_SAFETY;
pp->hand_tot += SC_SAFETY;
if ((pp->safescore += SC_SAFETY) == NUM_SAFE * SC_SAFETY) {
pp->total += SC_ALL_SAFE;
pp->hand_tot += SC_ALL_SAFE;
}
if (card == C_RIGHT_WAY) {
if (pp->speed == C_LIMIT)
pp->speed = C_INIT;
if (pp->battle == C_STOP || pp->battle == C_INIT) {
pp->can_go = TRUE;
pp->battle = C_INIT;
}
if (!pp->can_go && isrepair(pp->battle))
pp->can_go = TRUE;
}
Next = -1;
break;
case C_INIT:
error("no card there");
Next = -1;
break;
}
if (pp == &Player[PLAYER])
account(card);
pp->hand[Card_no] = C_INIT;
Next = (Next == -1 ? FALSE : TRUE);
return TRUE;
}
getmove()
{
reg char c, *sp;
static char moveprompt[] = ">>:Move:";
#ifdef EXTRAP
static bool last_ex = FALSE; /* set if last command was E */
if (last_ex) {
undoex();
prboard();
last_ex = FALSE;
}
#endif
for (;;) {
stand(MOVE_Y, MOVE_X, moveprompt);
clrtoeol();
move(MOVE_Y, MOVE_X + sizeof moveprompt);
leaveok(Board, FALSE);
refresh();
while ((c = getch()) == killchar() || c == erasechar())
continue;
if (islower(c))
c = toupper(c);
if (isprint(c) && !isspace(c)) {
addch(c);
refresh();
}
switch (c)
{
case 'P': /* Pick */
Movetype = M_DRAW;
goto ret;
case 'U': /* Use Card */
case 'D': /* Discard Card */
if ((Card_no = getcard()) < 0)
break;
Movetype = (c == 'U' ? M_PLAY : M_DISCARD);
goto ret;
case 'O': /* Order */
Order = !Order;
Movetype = M_ORDER;
goto ret;
case 'Q': /* Quit */
rub(); /* Same as a rubout */
break;
case 'W': /* Window toggle */
Window = nextwin(Window);
newscore();
prscore(TRUE);
wrefresh(Score);
break;
case 'R': /* Redraw screen */
case CTRL('L'):
clearok(curscr, TRUE);
newboard();
prboard();
break;
case 'S': /* Save game */
On_exit = FALSE;
save();
break;
case 'E': /* Extrapolate */
#ifdef EXTRAP
if (last_ex)
break;
Finished = TRUE;
if (Window != W_FULL)
newscore();
prscore(FALSE);
wrefresh(Score);
last_ex = TRUE;
Finished = FALSE;
#else
error("%c: command not implemented", c);
#endif
break;
case '\r': /* Ignore RETURNs and */
case '\n': /* Line Feeds */
case ' ': /* and Spaces */
break;
case 'Z': /* Debug code */
if (geteuid() == ARNOLD) {
if (!Debug && outf == NULL) {
char buf[40];
over:
mvaddstr(MOVE_Y, MOVE_X, "file: ");
clrtoeol();
leaveok(Board, FALSE);
refresh();
sp = buf;
while ((*sp = getch()) != '\n') {
if (*sp == killchar())
goto over;
else if (*sp == erasechar()) {
if (--sp < buf)
sp = buf;
else {
addch('\b');
if (*sp < ' ')
addch('\b');
clrtoeol();
}
}
else
addstr(unctrl(*sp++));
refresh();
}
*sp = '\0';
leaveok(Board, TRUE);
if ((outf = fopen(buf, "w")) == NULL)
perror(buf);
setbuf(outf, 0);
}
Debug = !Debug;
break;
}
/* FALLTHROUGH */
default:
error("unknown command: %s", unctrl(c));
break;
}
}
ret:
leaveok(Board, TRUE);
}
X/*
* return whether or not the player has picked
*/
haspicked(pp)
reg PLAY *pp; {
reg int card;
if (Topcard <= Deck)
return TRUE;
switch (pp->hand[Card_no]) {
case C_GAS_SAFE: case C_SPARE_SAFE:
case C_DRIVE_SAFE: case C_RIGHT_WAY:
card = 1;
break;
default:
card = 0;
break;
}
return (pp->hand[card] != C_INIT);
}
account(card)
reg CARD card; {
reg CARD oppos;
if (card == C_INIT)
return;
++Numseen[card];
if (Play == COMP)
switch (card) {
case C_GAS_SAFE:
case C_SPARE_SAFE:
case C_DRIVE_SAFE:
oppos = opposite(card);
Numgos += Numcards[oppos] - Numseen[oppos];
break;
case C_CRASH:
case C_FLAT:
case C_EMPTY:
case C_STOP:
Numgos++;
break;
}
}
sort(hand)
reg CARD *hand;
{
reg CARD *cp, *tp;
reg int j;
reg CARD temp;
cp = hand;
hand += HAND_SZ;
for ( ; cp < &hand[-1]; cp++)
for (tp = cp + 1; tp < hand; tp++)
if (*cp > *tp) {
temp = *cp;
*cp = *tp;
*tp = temp;
}
}
//go.sysin dd *
echo 'x - =test/=mille/print.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/print.c
# include "mille.h"
# define COMP_STRT 20
# define CARD_STRT 2
prboard() {
reg PLAY *pp;
reg int i, j, k, temp;
for (k = 0; k < 2; k++) {
pp = &Player[k];
temp = k * COMP_STRT + CARD_STRT;
for (i = 0; i < NUM_SAFE; i++)
if (pp->safety[i] == S_PLAYED) {
mvaddstr(i, temp, C_name[i + S_CONV]);
if (pp->coups[i])
mvaddch(i, temp - CARD_STRT, '*');
}
mvprintw(14, temp, C_fmt, C_name[pp->battle]);
mvprintw(16, temp, C_fmt, C_name[pp->speed]);
for (i = C_25; i <= C_200; ) {
reg char *name;
reg int end;
name = C_name[i];
temp = k * 40;
end = pp->nummiles[i++];
for (j = 0; j < end; j++)
mvwaddstr(Miles, i, (j << 2) + temp, name);
}
}
prscore(TRUE);
temp = CARD_STRT;
pp = &Player[PLAYER];
for (i = 0; i < HAND_SZ; i++)
mvprintw(i + 6, temp, C_fmt, C_name[pp->hand[i]]);
mvprintw(6, COMP_STRT + CARD_STRT, "%2d", Topcard - Deck);
mvprintw(8, COMP_STRT + CARD_STRT, C_fmt, C_name[Discard]);
if (End == 1000) {
static char ext[] = "Extension";
stand(EXT_Y, EXT_X, ext);
}
wrefresh(Board);
wrefresh(Miles);
wrefresh(Score);
}
X/*
* Put str at (y,x) in standout mode
*/
stand(y, x, str)
reg int y, x;
reg char *str; {
standout();
mvaddstr(y, x, str);
standend();
return TRUE;
}
prscore(for_real)
reg bool for_real; {
reg PLAY *pp;
reg int x;
reg char *Score_fmt = "%4d";
stdscr = Score;
for (pp = Player; pp < &Player[2]; pp++) {
x = (pp - Player) * 6 + 21;
mvprintw(1, x, Score_fmt, pp->mileage);
mvprintw(2, x, Score_fmt, pp->safescore);
if (pp->safescore == 400)
mvaddstr(3, x + 1, "300");
else
mvaddch(3, x + 3, '0');
mvprintw(4, x, Score_fmt, pp->coupscore);
if (Window == W_FULL || Finished) {
#ifdef EXTRAP
if (for_real)
finalscore(pp);
else
extrapolate(pp);
#else
finalscore(pp);
#endif
mvprintw(11, x, Score_fmt, pp->hand_tot);
mvprintw(13, x, Score_fmt, pp->total);
mvprintw(14, x, Score_fmt, pp->games);
}
else {
mvprintw(6, x, Score_fmt, pp->hand_tot);
mvprintw(8, x, Score_fmt, pp->total);
mvprintw(9, x, Score_fmt, pp->games);
}
}
stdscr = Board;
}
//go.sysin dd *
echo 'x - =test/=mille/roll.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/roll.c
X/*
* This routine rolls ndie nside-sided dice.
*/
# define reg register
# ifndef vax
# define MAXRAND 32767L
roll(ndie, nsides)
int ndie, nsides; {
reg long tot;
reg unsigned n, r;
tot = 0;
n = ndie;
while (n--)
tot += rand();
return (int) ((tot * (long) nsides) / ((long) MAXRAND + 1)) + ndie;
}
# else
roll(ndie, nsides)
reg int ndie, nsides; {
reg int tot, r;
reg double num_sides;
num_sides = nsides;
tot = 0;
while (ndie--)
tot += (r = rand()) * (num_sides / 017777777777) + 1;
return tot;
}
# endif
//go.sysin dd *
echo 'x - =test/=mille/save.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/save.c
#include "mille.h"
#include "unctrl.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
typedef struct stat STAT;
typedef struct tm TIME;
char *ctime();
int read(), write();
X/*
* This routine saves the current game for use at a later date
*/
extern int errno;
extern char *sys_errlist[];
save() {
reg char *sp;
reg int outf;
reg TIME *tp;
char buf[80];
TIME tme;
STAT junk;
tp = &tme;
if (Fromfile && getyn("Same file? "))
strcpy(buf, Fromfile);
else {
over:
mvaddstr(MOVE_Y, MOVE_X, "file: ");
clrtoeol();
leaveok(Board, FALSE);
refresh();
#ifdef UNDEFINED
sp = buf;
while ((*sp = getch()) != '\n') {
if (*sp == killchar())
goto over;
else if (*sp == erasechar()) {
if (--sp < buf)
sp = buf;
else {
addch('\b');
/*
* if the previous char was a control
* char, cover up two characters.
*/
if (*sp < ' ')
addch('\b');
clrtoeol();
}
}
else
addstr(unctrl(*sp++));
refresh();
}
*sp = '\0';
#else
getstr(buf);
#endif
leaveok(Board, TRUE);
}
/*
* check for existing files, and confirm overwrite if needed
*/
if (sp == buf || (!Fromfile && stat(buf, &junk) > -1
&& getyn("Overwrite File? ") == FALSE))
return FALSE;
if ((outf = creat(buf, 0644)) < 0) {
error(sys_errlist[errno]);
return FALSE;
}
mvwaddstr(Score, ERR_Y, ERR_X, buf);
wrefresh(Score);
time(tp); /* get current time */
strcpy(buf, ctime(tp));
for (sp = buf; *sp != '\n'; sp++)
continue;
*sp = '\0';
varpush(outf, write);
close(outf);
wprintw(Score, " [%s]", buf);
wclrtoeol(Score);
wrefresh(Score);
return TRUE;
}
X/*
* This does the actual restoring. It returns TRUE if the
* backup was made on exiting, in which case certain things must
* be cleaned up before the game starts.
*/
rest_f(file)
reg char *file; {
reg char *sp;
reg int inf;
char buf[80];
STAT sbuf;
if ((inf = open(file, 0)) < 0) {
perror(file);
exit(1);
}
if (fstat(inf, &sbuf) < 0) { /* get file stats */
perror(file);
exit(1);
}
varpush(inf, read);
close(inf);
strcpy(buf, ctime(&sbuf.st_mtime));
for (sp = buf; *sp != '\n'; sp++)
continue;
*sp = '\0';
/*
* initialize some necessary values
*/
sprintf(Initstr, "%s [%s]\n", file, buf);
Fromfile = file;
return !On_exit;
}
//go.sysin dd *
echo 'x - =test/=mille/table.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/table.c
# define DEBUG
# include "mille.h"
main() {
reg int i, j, count;
printf(" %16s -> %5s %5s %4s %s\n", "Card", "cards", "count", "need", "opposite");
for (i = 0; i < NUM_CARDS - 1; i++) {
for (j = 0, count = 0; j < DECK_SZ; j++)
if (Deck[j] == i)
count++;
printf("%2d %16s -> %5d %5d %4d %s\n", i, C_name[i], Numcards[i], count, Numneed[i], C_name[opposite(i)]);
}
}
//go.sysin dd *
echo 'x - =test/=mille/types.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/types.c
# include "mille.h"
isrepair(card)
reg CARD card; {
return card == C_GAS || card == C_SPARE || card == C_REPAIRS || card == C_INIT;
}
safety(card)
reg CARD card; {
switch (card) {
case C_EMPTY:
case C_GAS:
case C_GAS_SAFE:
return C_GAS_SAFE;
case C_FLAT:
case C_SPARE:
case C_SPARE_SAFE:
return C_SPARE_SAFE;
case C_CRASH:
case C_REPAIRS:
case C_DRIVE_SAFE:
return C_DRIVE_SAFE;
case C_GO:
case C_STOP:
case C_RIGHT_WAY:
case C_LIMIT:
case C_END_LIMIT:
return C_RIGHT_WAY;
}
/* NOTREACHED */
}
//go.sysin dd *
echo 'x - =test/=mille/unctrl.h'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/unctrl.h
# include <stdio.h>
# define unctrl(ch) (_unctrl[ch])
extern char *_unctrl[];
//go.sysin dd *
echo 'x - =test/=mille/varpush.c'
sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/varpush.c
# include "mille.h"
int read(), write();
X/*
* push variables around via the routine func() on the file
* channel file. func() is either read or write.
*/
varpush(file, func)
reg int file;
reg int (*func)(); {
int temp;
(*func)(file, &Debug, sizeof Debug);
(*func)(file, &Finished, sizeof Finished);
(*func)(file, &Order, sizeof Order);
(*func)(file, &End, sizeof End);
(*func)(file, &On_exit, sizeof On_exit);
(*func)(file, &Handstart, sizeof Handstart);
(*func)(file, &Numgos, sizeof Numgos);
(*func)(file, Numseen, sizeof Numseen);
(*func)(file, &Play, sizeof Play);
(*func)(file, &Window, sizeof Window);
(*func)(file, Deck, sizeof Deck);
(*func)(file, &Discard, sizeof Discard);
(*func)(file, Player, sizeof Player);
if (func == read) {
read(file, &temp, sizeof temp);
Topcard = &Deck[temp];
if (Debug) {
char buf[80];
over:
printf("Debug file:");
gets(buf);
if ((outf = fopen(buf, "w")) == NULL) {
perror(buf);
goto over;
}
if (strcmp(buf, "/dev/null") != 0)
setbuf(outf, 0);
}
}
else {
temp = Topcard - Deck;
write(file, &temp, sizeof temp);
}
}
//go.sysin dd *
exit
More information about the Mod.sources
mailing list