Initial revision

git-svn-id: file:///srv/svn/joey/bsdgames-trunk@5086 a4a2c43b-8ac3-0310-8836-e0e880c912e2
This commit is contained in:
joey
1999-09-08 23:56:51 +00:00
commit 03272d67da
623 changed files with 243457 additions and 0 deletions

13
mille/Makefile.bsd Normal file
View File

@@ -0,0 +1,13 @@
# $NetBSD: Makefile,v 1.9 1998/02/18 22:37:31 jtc Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= mille
SRCS= comp.c end.c extern.c init.c mille.c misc.c move.c print.c \
roll.c save.c types.c varpush.c
DPADD= ${LIBCURSES}
LDADD= -lcurses
MAN= mille.6
HIDEGAME=hidegame
.include <bsd.prog.mk>

10
mille/Makefrag Normal file
View File

@@ -0,0 +1,10 @@
# Makefrag - makefile fragment for mille
mille_DIRS := $(GAMESDIR) $(MAN6DIR)
mille_all: mille/mille mille/mille.6
mille_install: mille_all
$(INSTALL_BINARY) mille/mille $(INSTALL_PREFIX)$(GAMESDIR)/mille
$(HIDE_GAME) mille
$(INSTALL_MANUAL) mille/mille.6

489
mille/comp.c Normal file
View File

@@ -0,0 +1,489 @@
/* $NetBSD: comp.c,v 1.5 1997/10/12 00:53:45 lukem Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)comp.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: comp.c,v 1.5 1997/10/12 00:53:45 lukem Exp $");
#endif
#endif /* not lint */
# include "mille.h"
/*
* @(#)comp.c 1.1 (Berkeley) 4/1/82
*/
# define V_VALUABLE 40
void
calcmove()
{
CARD card;
int *value;
PLAY *pp, *op;
bool foundend, cango, canstop, foundlow;
unsgn int i, count200, badcount, nummin, nummax, diff;
int curmin, curmax;
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;
/* Try for a Coup Forre, and see what we have. */
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)) != 0)
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;
}
if (card >= 0)
++count[card];
}
/* No Coup Forre. Draw to fill hand, then restart, as needed. */
if (pp->hand[0] == C_INIT && Topcard > Deck) {
Movetype = M_DRAW;
return;
}
#ifdef DEBUG
if (Debug)
fprintf(outf, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n",
cango, canstop, safe);
#endif
if (foundend)
foundend = !check_ext(TRUE);
for (i = 0; safe && i < HAND_SZ; i++) {
if (is_safety(pp->hand[i])) {
if (onecard(op) || (foundend && cango && !canstop)) {
#ifdef DEBUG
if (Debug)
fprintf(outf,
"CALCMOVE: onecard(op) = %d, foundend = %d\n",
onecard(op), foundend);
#endif
playsafe:
Movetype = M_PLAY;
Card_no = i;
return;
}
oppos = opposite(pp->hand[i]);
if (Numseen[oppos] == Numcards[oppos] &&
!(pp->hand[i] == C_RIGHT_WAY &&
Numseen[C_LIMIT] != Numcards[C_LIMIT]))
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;
#ifdef DEBUG
if (Debug)
fprintf(outf,
"CALCMOVE: card = %d, DECK_SZ / 4 = %d\n",
card, DECK_SZ / 4);
#endif
if (card < DECK_SZ / 4)
goto playsafe;
}
safe--;
playit[i] = cango;
}
}
if (!pp->can_go && !is_repair(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 (is_safety(card) || playit[i] == (cango != 0)) {
#ifdef DEBUG
if (Debug)
fprintf(outf, "CALCMOVE: switch(\"%s\")\n",
C_name[card]);
#endif
switch (card) {
case C_25: case C_50:
diff = End - pp->mileage;
/* avoid getting too close */
if (Topcard > Deck && cango && diff <= 100
&& (int)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;
break;
}
}
else
*value = cango ? 0 : 101;
if (card != C_INIT) {
if (*value >= curmax) {
nummax = i;
curmax = *value;
}
if (*value <= curmin) {
nummin = i;
curmin = *value;
}
}
#ifdef DEBUG
if (Debug)
mvprintw(i + 6, 2, "%3d %-14s", *value,
C_name[pp->hand[i]]);
#endif
value++;
}
if (!pp->can_go && !is_repair(pp->battle))
Numneed[opposite(pp->battle)]++;
if (cango) {
play_it:
mvaddstr(MOVE_Y + 1, MOVE_X, "PLAY\n");
Movetype = M_PLAY;
Card_no = nummax;
}
else {
if (is_safety(pp->hand[nummin])) { /* NEVER discard a safety */
nummax = nummin;
goto play_it;
}
mvaddstr(MOVE_Y + 1, MOVE_X, "DISCARD\n");
Movetype = M_DISCARD;
Card_no = nummin;
}
mvprintw(MOVE_Y + 2, MOVE_X, "%16s", C_name[pp->hand[Card_no]]);
}
/*
* Return true if the given player could conceivably win with his next card.
*/
int
onecard(pp)
const PLAY *pp;
{
CARD bat, spd, card;
bat = pp->battle;
spd = pp->speed;
card = -1;
if (pp->can_go || ((is_repair(bat) || bat == C_STOP || spd == C_LIMIT) &&
Numseen[S_RIGHT_WAY] != 0) ||
(bat >= 0 && Numseen[safety(bat)] != 0))
switch (End - pp->mileage) {
case 200:
if (pp->nummiles[C_200] == 2)
return FALSE;
card = C_200;
/* FALLTHROUGH */
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;
}
int
canplay(pp, op, card)
const PLAY *pp, *op;
CARD card;
{
switch (card) {
case C_200:
if (pp->nummiles[C_200] == 2)
break;
/* FALLTHROUGH */
case C_75: case C_100:
if (pp->speed == C_LIMIT)
break;
/* FALLTHROUGH */
case C_50:
if (pp->mileage + Value[card] > End)
break;
/* FALLTHROUGH */
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 &&
(is_repair(pp->battle) || pp->battle == C_STOP))
return TRUE;
break;
case C_END_LIMIT:
if (pp->speed == C_LIMIT)
return TRUE;
}
return FALSE;
}

155
mille/end.c Normal file
View File

@@ -0,0 +1,155 @@
/* $NetBSD: end.c,v 1.6 1997/10/12 00:53:51 lukem Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)end.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: end.c,v 1.6 1997/10/12 00:53:51 lukem Exp $");
#endif
#endif /* not lint */
# include "mille.h"
/*
* @(#)end.c 1.1 (Berkeley) 4/1/82
*/
/*
* 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).
*/
void
finalscore(pp)
PLAY *pp;
{
int temp, tot, num;
if (pp->was_finished == Finished)
return;
pp->was_finished = Finished;
num = pp - Player;
temp = num * 6 + 21 + 1;
for (tot = 5; tot <= 9; tot++)
mvaddstr(tot, temp, " 0");
if (pp->mileage == End) {
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 */
/*
* 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

179
mille/extern.c Normal file
View File

@@ -0,0 +1,179 @@
/* $NetBSD: extern.c,v 1.5 1997/10/12 00:53:55 lukem Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)extern.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: extern.c,v 1.5 1997/10/12 00:53:55 lukem Exp $");
#endif
#endif /* not lint */
# include "mille.h"
/*
* @(#)extern.c 1.1 (Berkeley) 4/1/82
*/
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 Initstr[100]; /* initial string for error field */
const char *C_fmt = "%-18.18s", /* format for printing cards */
*Fromfile = NULL, /* startup file for game */
*const _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"
},
*const *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 */
const int 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 */
};
int 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 */
Sh_discard, /* Last discard card shown */
*Topcard; /* Pointer to next card to be picked */
const CARD 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
};
CARD 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
};
FILE *outf;
PLAY Player[2]; /* Player descriptions */
WINDOW *Board, /* Playing field screen */
*Miles, /* Mileage screen */
*Score; /* Score screen */

261
mille/init.c Normal file
View File

@@ -0,0 +1,261 @@
/* $NetBSD: init.c,v 1.7 1997/10/12 00:53:59 lukem Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: init.c,v 1.7 1997/10/12 00:53:59 lukem Exp $");
#endif
#endif /* not lint */
# include "mille.h"
/*
* @(#)init.c 1.1 (Berkeley) 4/1/82
*/
void
init()
{
PLAY *pp;
int i, j;
CARD card;
memset(Numseen, 0, sizeof Numseen);
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 (is_safety(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;
}
void
shuffle()
{
int i, r;
CARD temp;
for (i = 0; i < DECK_SZ; i++) {
r = roll(1, DECK_SZ) - 1;
if (r < 0 || r > DECK_SZ - 1) {
warnx("shuffle: card no. error: %d", r);
die(1);
}
temp = Deck[r];
Deck[r] = Deck[i];
Deck[i] = temp;
}
Topcard = &Deck[DECK_SZ];
}
void
newboard()
{
int i;
PLAY *pp;
static int first = TRUE;
if (first) {
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--");
mvwaddstr(Miles, 0, 0, "--MILEAGE--");
mvwaddstr(Miles, 0, 41, "--MILEAGE--");
Sh_discard = -1;
for (pp = Player; pp <= &Player[COMP]; pp++) {
for (i = 0; i < HAND_SZ; i++)
pp->sh_hand[i] = -1;
pp->sh_battle = -1;
pp->sh_speed = -1;
pp->sh_mileage = -1;
}
first = FALSE;
}
else {
for (i = 0; i < 5; i++) {
move(i, 0);
clrtoeol();
}
wmove(Miles, 1, 0);
wclrtobot(Miles);
wmove(Board, MOVE_Y + 1, MOVE_X);
wclrtoeol(Board);
wmove(Board, MOVE_Y + 2, MOVE_X);
wclrtoeol(Board);
}
Sh_discard = -1;
for (pp = Player; pp <= &Player[COMP]; pp++) {
for (i = 0; i < NUM_SAFE; i++)
pp->sh_safety[i] = FALSE;
for (i = 0; i < NUM_MILES; i++)
pp->sh_nummiles[i] = 0;
pp->sh_safescore = -1;
}
newscore();
}
void
newscore()
{
int i, new;
PLAY *pp;
static int was_full = -1;
static int last_win = -1;
if (was_full < 0)
was_full = (Window != W_FULL);
stdscr = Score;
move(0, 22);
new = FALSE;
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");
new = TRUE;
}
else if ((Window == W_FULL || Finished) ^ was_full) {
move(5, 1);
clrtobot();
new = TRUE;
}
else if (Window != last_win)
new = TRUE;
if (new) {
for (i = 0; i < SCORE_Y; i++)
mvaddch(i, 0, '|');
move(SCORE_Y - 1, 1);
for (i = 0; i < SCORE_X; i++)
addch('_');
for (pp = Player; pp <= &Player[COMP]; pp++) {
pp->sh_hand_tot = -1;
pp->sh_total = -1;
pp->sh_games = -1;
pp->sh_safescore = -1;
}
}
Player[PLAYER].was_finished = !Finished;
Player[COMP].was_finished = !Finished;
if (Window == W_FULL || Finished) {
if (!was_full || new) {
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
if (was_full || new) {
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");
if (!Order)
mvaddstr(12, 21, "o: order hand");
else
mvaddstr(12, 21, "o: stop ordering");
mvaddstr(13, 21, "s: save");
mvaddstr(14, 21, "r: reprint");
}
stdscr = Board;
was_full = (Window == W_FULL || Finished);
last_win = Window;
}

382
mille/mille.6 Normal file
View File

@@ -0,0 +1,382 @@
.\" $NetBSD: mille.6,v 1.6 1997/10/12 00:54:03 lukem Exp $
.\"
.\" Copyright (c) 1983, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)mille.6 8.3 (Berkeley) 6/1/94
.\"
.TH MILLE 6 "June 1, 1994"
.UC 4
.SH NAME
mille \- play Mille Bornes
.SH SYNOPSIS
.B mille
[ file ]
.SH DESCRIPTION
.I Mille
plays a two-handed game reminiscent of
the Parker Brother's game of Mille Bornes with you.
The rules are described below.
If a file name is given on the command line,
the game saved in that file is started.
.PP
When a game is started up,
the bottom of the score window will contain a list of commands.
They are:
.IP P
Pick a card from the deck.
This card is placed in the `P' slot in your hand.
.IP D
Discard a card from your hand.
To indicate which card, type the number of the card in the hand
(or \*(lqP\*(rq for the just-picked card) followed by a <RETURN> or <SPACE>.
The <RETURN or <SPACE> is required to allow recovery from typos
which can be very expensive, like discarding safeties.
.IP U
Use a card.
The card is again indicated by its number, followed by a <RETURN> or <SPACE>.
.IP O
Toggle ordering the hand.
By default off, if turned on it will sort the cards in your hand appropriately.
This is not recommended for the impatient on slow terminals.
.IP Q
Quit the game.
This will ask for confirmation, just to be sure.
Hitting <DELETE> (or <RUBOUT>) is equivalent.
.IP S
Save the game in a file.
If the game was started from a file,
you will be given an opportunity to save it on the same file.
If you don't wish to, or you did not start from a file,
you will be asked for the file name.
If you type a <RETURN> without a name,
the save will be terminated and the game resumed.
.IP R
Redraw the screen from scratch.
The command ^L (control `L') will also work.
.IP W
Toggle window type.
This switches the score window between the startup window
(with all the command names) and the end-of-game window.
Using the end-of-game window
saves time by eliminating the switch at the end of the game
to show the final score.
Recommended for hackers and other miscreants.
.PP
If you make a mistake, an error message will be printed
on the last line of the score window, and a bell will beep.
.PP
At the end of each hand or game,
you will be asked if you wish to play another.
If not, it will ask you if you want to save the game.
If you do, and the save is unsuccessful,
play will be resumed as if you had said you wanted to play another hand/game.
This allows you to use the
.RB \*(lq S \*(rq
command to reattempt the save.
.SH AUTHOR
Ken Arnold
.br
(The game itself is a product of Parker Brothers, Inc.)
.SH "SEE ALSO"
curses(3X),
.I "Screen Updating and Cursor Movement Optimization:"
.IR "A Library Package" ,
Ken Arnold
.SH CARDS
.PP
Here is some useful information.
The number in parentheses after the card name
is the number of that card in the deck:
.sp
.nf
.ne 10
.ta \w'Speed Limit (3)'u+3n \w'Speed Limit (3)'u+\w'End of Limit (6)'u+6n
Hazard Repair Safety
.sp
Out of Gas (2) Gasoline (6) Extra Tank (1)
Flat Tire (2) Spare Tire (6) Puncture Proof (1)
Accident (2) Repairs (6) Driving Ace (1)
Stop (4) Go (14) Right of Way (1)
Speed Limit (3) End of Limit (6)
.sp
.ce
25 \- (10), 50 \- (10), 75 \- (10), 100 \- (12), 200 \- (4)
.sp
.fi
.DT
.SH RULES
.PP
.BR Object :
The point of this game is to get a total of 5000 points in several hands.
Each hand is a race to put down exactly 700 miles before your opponent does.
Beyond the points gained by putting down milestones,
there are several other ways of making points.
.PP
.BR Overview :
The game is played with a deck of 101 cards.
.I Distance
cards represent a number of miles traveled.
They come in denominations of 25, 50, 75, 100, and 200.
When one is played,
it adds that many miles to the player's trip so far this hand.
.I Hazard
cards are used to prevent your opponent from putting down Distance cards.
They can only be played if your opponent has a
.I Go
card on top of the Battle pile.
The cards are
.IR "Out of Gas" ,
.IR "Accident" ,
.IR "Flat Tire" ,
.IR "Speed Limit" ,
and
.IR "Stop" .
.I Remedy
cards fix problems caused by Hazard cards played on you by your opponent.
The cards are
.IR "Gasoline" ,
.IR "Repairs" ,
.IR "Spare Tire" ,
.IR "End of Limit" ,
and
.IR "Go" .
.I Safety
cards prevent your opponent from putting specific Hazard cards on you
in the first place.
They are
.IR "Extra Tank" ,
.IR "Driving Ace" ,
.IR "Puncture Proof" ,
and
.IR "Right of Way" ,
and there are only one of each in the deck.
.PP
.BR "Board Layout" :
The board is split into several areas.
From top to bottom, they are:
.B "SAFETY AREA"
(unlabeled): This is where the safeties will be placed as they are played.
.BR HAND :
These are the cards in your hand.
.BR BATTLE :
This is the Battle pile.
All the Hazard and Remedy Cards are played here, except the
.I "Speed Limit"
and
.I "End of Limit"
cards. Only the top card is displayed, as it is the only effective one.
.BR SPEED :
The Speed pile. The
.I "Speed Limit"
and
.I "End of Limit"
cards are played here
to control the speed at which the player is allowed to put down miles.
.BR MILEAGE :
Miles are placed here.
The total of the numbers shown here is the distance traveled so far.
.PP
.BR Play :
The first pick alternates between the two players.
Each turn usually starts with a pick from the deck.
The player then plays a card, or if this is not possible or desirable,
discards one. Normally, a play or discard of a single card
constitutes a turn. If the card played is a safety, however,
the same player takes another turn immediately.
.PP
This repeats until one of the players reaches 700 points or the deck runs out.
If someone reaches 700, they have the option of going for an
.IR Extension ,
which means that the play continues until someone reaches 1000 miles.
.PP
.BR "Hazard and Remedy Cards" :
Hazard Cards are played on your opponent's Battle and Speed piles.
Remedy Cards are used for undoing the effects of your opponent's nastiness.
.PP
.RB "\ \ \ \ " Go
(Green Light)
must be the top card on your Battle pile for you to play any mileage,
unless you have played the
.I "Right of Way"
card (see below).
.br
.RB "\ \ \ \ " Stop
is played on your opponent's
.I Go
card to prevent them from playing mileage until they play a
.I Go
card.
.br
.RB "\ \ \ \ " "Speed Limit"
is played on your opponent's Speed pile.
Until they play an
.I "End of Limit"
they can only play 25 or 50 mile cards, presuming their
.I Go
card allows them to do even that.
.br
.RB "\ \ \ \ " "End of Limit"
is played on your Speed pile to nullify a
.I "Speed Limit"
played by your opponent.
.br
.RB "\ \ \ \ " "Out of Gas"
is played on your opponent's
.I Go
card. They must then play a
.I Gasoline
card, and then a
.I Go
card before they can play any more mileage.
.br
.RB "\ \ \ \ " "Flat Tire"
is played on your opponent's
.I Go
card. They must then play a
.I "Spare Tire"
card, and then a
.I Go
card before they can play any more mileage.
.br
.ne 1i
.RB "\ \ \ \ " "Accident"
is played on your opponent's
.I Go
card. They must then play a
.I Repairs
card, and then a
.I Go
card before they can play any more mileage.
.br
.PP
.BR "Safety Cards" :
Safety cards prevent your opponent
from playing the corresponding Hazard cards on you for the rest of the hand.
It cancels an attack in progress, and
.IR "always entitles the player to an extra turn" .
.br
.RB "\ \ \ \ " "Right of Way"
prevents your opponent from playing both
.I Stop
and
.I "Speed Limit"
cards on you. It also acts as a permanent
.I Go
card for the rest of the hand, so you can play mileage
as long as there is not a Hazard card on top of your Battle pile.
In this case only, your opponent can play Hazard cards directly on a Remedy card
other than a Go card.
.br
.RB "\ \ \ \ " "Extra Tank"
When played, your opponent cannot play an
.I "Out of Gas"
on your Battle Pile.
.br
.RB "\ \ \ \ " "Puncture Proof"
When played, your opponent cannot play a
.I "Flat Tire"
on your Battle Pile.
.br
.RB "\ \ \ \ " "Driving Ace"
When played, your opponent cannot play an
.I Accident
on your Battle Pile.
.PP
.BR "Distance Cards" :
Distance cards are played when you have a
.I Go
card on your Battle pile,
or a Right of Way in your Safety area and are not stopped by a Hazard Card.
They can be played in any combination that totals exactly 700 miles,
except that
.IR "you cannot play more than two 200 mile cards in one hand" .
A hand ends whenever one player gets exactly 700 miles or the deck runs out.
In that case, play continues until neither someone reaches 700,
or neither player can use any cards in their hand.
If the trip is completed after the deck runs out, this is called
.IR "Delayed Action" .
.PP
.BR "Coup Fourr\o'\(aae'" :
This is a French fencing term for a counter-thrust move as part of a parry
to an opponent's attack.
In current French colloquial language it means a sneaky, underhanded blow.
In Mille Bornes, it is used as follows:
If an opponent plays a Hazard card,
and you have the corresponding Safety in your hand,
you play it immediately, even
.I before
you draw. This immediately removes the Hazard card from your Battle pile,
and protects you from that card for the rest of the game. This
gives you more points (see \*(lqScoring\*(rq below).
.PP
.BR Scoring :
Scores are totaled at the end of each hand,
whether or not anyone completed the trip.
The terms used in the Score window have the following meanings:
.br
.RB "\ \ \ \ " "Milestones Played" :
Each player scores as many miles as they played before the trip ended.
.br
.RB "\ \ \ \ " "Each Safety" :
100 points for each safety in the Safety area.
.br
.RB "\ \ \ \ " "All 4 Safeties" :
300 points if all four safeties are played.
.br
.RB "\ \ \ \ " "Each Coup Fourr\o'\(aae'" :
300 points for each Coup Fourr\o'\(aae' accomplished.
.PP
The following bonus scores can apply only to the winning player.
.br
.RB "\ \ \ \ " "Trip Completed" :
400 points bonus for completing the trip to 700 or 1000.
.br
.RB "\ \ \ \ " "Safe Trip" :
300 points bonus for completing the trip without using any 200 mile cards.
.br
.RB "\ \ \ \ " "Delayed Action" :
300 points bonus for finishing after the deck was exhausted.
.br
.RB "\ \ \ \ " "Extension" :
200 points bonus for completing a 1000 mile trip.
.br
.RB "\ \ \ \ " "Shut-Out" :
500 points bonus for completing the trip
before your opponent played any mileage cards.
.PP
Running totals are also kept for the current score for each player
for the hand
.RB ( "Hand Total" ),
the game
.RB ( "Overall Total" ),
and number of games won
.RB ( Games ).

171
mille/mille.c Normal file
View File

@@ -0,0 +1,171 @@
/* $NetBSD: mille.c,v 1.6 1997/10/12 00:54:07 lukem Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1982, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)mille.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: mille.c,v 1.6 1997/10/12 00:54:07 lukem Exp $");
#endif
#endif /* not lint */
# include "mille.h"
# include <signal.h>
# ifdef attron
# include <term.h>
# endif attron
/*
* @(#)mille.c 1.3 (Berkeley) 5/10/83
*/
int
main(ac, av)
int ac;
char *av[];
{
bool restore;
/* Revoke setgid privileges */
setregid(getgid(), getgid());
if (strcmp(av[0], "a.out") == 0) {
outf = fopen("q", "w");
setbuf(outf, (char *)NULL);
Debug = TRUE;
}
restore = FALSE;
switch (ac) {
case 2:
rest_f(av[1]);
restore = TRUE;
case 1:
break;
default:
printf("usage: milles [ restore_file ]\n");
exit(-1);
/* NOTREACHED */
}
Play = PLAYER;
initscr();
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);
#ifdef attron
idlok(Board, TRUE);
idlok(Score, TRUE);
idlok(Miles, TRUE);
#endif
leaveok(Score, TRUE);
leaveok(Miles, TRUE);
clearok(curscr, TRUE);
# ifndef PROF
srandom(getpid());
# else
srandom(0);
# endif
crmode();
noecho();
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);
}
}
/*
* Routine to trap rubouts, and make sure they really want to
* quit.
*/
void
rub(dummy)
int dummy __attribute__((unused));
{
(void)signal(SIGINT, SIG_IGN);
if (getyn(REALLYPROMPT))
die(0);
(void)signal(SIGINT, rub);
}
/*
* Time to go beddy-by
*/
void
die(code)
int code;
{
(void)signal(SIGINT, SIG_IGN);
if (outf)
fflush(outf);
mvcur(0, COLS - 1, LINES - 1, 0);
endwin();
exit(code);
}

278
mille/mille.h Normal file
View File

@@ -0,0 +1,278 @@
/* $NetBSD: mille.h,v 1.9 1998/09/13 15:27:29 hubertf Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mille.h 8.1 (Berkeley) 5/31/93
*/
# include <sys/types.h>
# include <sys/uio.h>
# include <sys/stat.h>
# include <ctype.h>
# include <err.h>
# include <errno.h>
# include <curses.h>
# include <fcntl.h>
# include <stdlib.h>
# include <string.h>
# include <termios.h>
# include <unistd.h>
/*
* @(#)mille.h 1.1 (Berkeley) 4/1/82
*/
/*
* Miscellaneous constants
*/
# define unsgn unsigned
# define CARD short
# 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 */
/*
* Move types
*/
# define M_DISCARD 0
# define M_DRAW 1
# define M_PLAY 2
# define M_ORDER 3
/*
* 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
/*
* safety descriptions
*/
# undef S_UNKNOWN
# undef S_IN_HAND
# undef S_PLAYED
# undef S_GAS_SAFE
# undef S_SPARE_SAFE
# undef S_DRIVE_SAFE
# undef S_RIGHT_WAY
# undef S_CONV
# 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_ */
/*
* 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
/*
* prompt types
*/
# define MOVEPROMPT 0
# define REALLYPROMPT 1
# define ANOTHERHANDPROMPT 2
# define ANOTHERGAMEPROMPT 3
# define SAVEGAMEPROMPT 4
# define SAMEFILEPROMPT 5
# define FILEPROMPT 6
# define EXTENSIONPROMPT 7
# define OVERWRITEFILEPROMPT 8
# ifdef SYSV
# define srandom(x) srand(x)
# define random() rand()
# endif /* SYSV */
typedef struct {
bool coups[NUM_SAFE];
bool can_go;
bool new_battle;
bool new_speed;
short safety[NUM_SAFE];
short sh_safety[NUM_SAFE];
short nummiles[NUM_MILES];
short sh_nummiles[NUM_MILES];
CARD hand[HAND_SZ];
CARD sh_hand[HAND_SZ];
CARD battle;
CARD sh_battle;
CARD speed;
CARD sh_speed;
int mileage;
int sh_mileage;
int hand_tot;
int sh_hand_tot;
int safescore;
int sh_safescore;
int coupscore;
int total;
int sh_total;
int games;
int sh_games;
int was_finished;
} PLAY;
/*
* macros
*/
# define other(x) (1 - x)
# define nextplay() (Play = other(Play))
# define nextwin(x) (1 - x)
# define opposite(x) (Opposite[x])
# define is_safety(x) (x >= C_GAS_SAFE)
/*
* externals
*/
extern bool Debug, Finished, Next, On_exit, Order, Saved;
extern char Initstr[];
extern const char *C_fmt, *const *C_name, *Fromfile;
extern int Card_no, End, Handstart, Movetype, Numgos,
Numneed[], Numseen[NUM_CARDS], Play, Window;
extern const int Numcards[], Value[];
extern CARD Deck[DECK_SZ], Discard, Sh_discard, *Topcard;
extern const CARD Opposite[NUM_CARDS];
extern FILE *outf;
extern PLAY Player[2];
extern WINDOW *Board, *Miles, *Score;
/*
* functions
*/
void account __P((CARD));
void calcmove __P((void));
int canplay __P((const PLAY *, const PLAY *, CARD));
int check_ext __P((bool));
void check_go __P((void));
void check_more __P((void));
void die __P((int)) __attribute__((__noreturn__));
void domove __P((void));
bool error __P((const char *, ...));
void extrapolate __P((PLAY *));
void finalscore __P((PLAY *));
CARD getcard __P((void));
void getmove __P((void));
int getyn __P((int));
int haspicked __P((const PLAY *));
void init __P((void));
int is_repair __P((CARD));
int main __P((int, char **));
void newboard __P((void));
void newscore __P((void));
int onecard __P((const PLAY *));
int playcard __P((PLAY *));
void prboard __P((void));
void prompt __P((int));
void prscore __P((bool));
int readch __P((void));
bool rest_f __P((const char *));
int roll __P((int, int));
void rub __P((int));
int safety __P((CARD));
bool save __P((void));
void show_card __P((int, int, CARD, CARD *));
void show_score __P((int, int, int, int *));
void shuffle __P((void));
void sort __P((CARD *));
void undoex __P((int));
#if defined(__linux__) && !defined(__GLIBC__)
bool varpush __P((int, ssize_t __P((int, const struct iovec *, size_t))));
#else
bool varpush __P((int, ssize_t __P((int, const struct iovec *, int))));
#endif

282
mille/misc.c Normal file
View File

@@ -0,0 +1,282 @@
/* $NetBSD: misc.c,v 1.7 1998/07/26 16:11:40 mycroft Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: misc.c,v 1.7 1998/07/26 16:11:40 mycroft Exp $");
#endif
#endif /* not lint */
#include <sys/file.h>
#include <termios.h>
#if __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "mille.h"
#ifndef unctrl
#include "unctrl.h"
#endif
# ifdef attron
# include <term.h>
# endif attron
/*
* @(#)misc.c 1.2 (Berkeley) 3/28/83
*/
#define NUMSAFE 4
bool
#if __STDC__
error(const char *str, ...)
#else
error(str, va_alist)
const char *str;
va_dcl
#endif
{
va_list ap;
#if __STDC__
va_start(ap, str);
#else
va_start(ap);
#endif
wmove(Score, ERR_Y, ERR_X);
vwprintw(Score, str, ap);
clrtoeol();
putchar('\07');
refresh();
va_end(ap);
return FALSE;
}
CARD
getcard()
{
int c, c1;
for (;;) {
while ((c = readch()) == '\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('\07');
addch('\b');
if (!isprint(c))
addch('\b');
c = -1;
break;
}
refresh();
if (c >= 0) {
while ((c1=readch()) != '\r' && c1 != '\n' && c1 != ' ')
if (c1 == killchar())
return -1;
else if (c1 == erasechar()) {
addch('\b');
clrtoeol();
refresh();
goto cont;
}
else
write(0, "\07", 1);
return c;
}
cont: ;
}
}
int
check_ext(forcomp)
bool forcomp;
{
if (End == 700)
if (Play == PLAYER) {
if (getyn(EXTENSIONPROMPT)) {
extend:
if (!forcomp)
End = 1000;
return TRUE;
}
else {
done:
if (!forcomp)
Finished = TRUE;
return FALSE;
}
}
else {
PLAY *pp, *op;
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;
}
/*
* Get a yes or no answer to the given question. Saves are
* also allowed. Return TRUE if the answer was yes, FALSE if no.
*/
int
getyn(promptno)
int promptno;
{
char c;
Saved = FALSE;
for (;;) {
leaveok(Board, FALSE);
prompt(promptno);
clrtoeol();
refresh();
switch (c = readch()) {
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;
case CTRL('L'):
wrefresh(curscr);
break;
default:
addstr(unctrl(c));
refresh();
putchar('\07');
break;
}
}
}
/*
* 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.
*/
void
check_more()
{
On_exit = TRUE;
if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000)
if (getyn(ANOTHERGAMEPROMPT))
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(ANOTHERHANDPROMPT))
return;
if (!Saved && getyn(SAVEGAMEPROMPT))
if (!save())
return;
die(0);
}
int
readch()
{
int cnt;
static char c;
for (cnt = 0; read(0, &c, 1) <= 0; cnt++)
if (cnt > 100)
exit(1);
return c;
}

574
mille/move.c Normal file
View File

@@ -0,0 +1,574 @@
/* $NetBSD: move.c,v 1.7 1997/10/12 00:54:21 lukem Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: move.c,v 1.7 1997/10/12 00:54:21 lukem Exp $");
#endif
#endif /* not lint */
#include <termios.h>
#include "mille.h"
#ifndef unctrl
#include "unctrl.h"
#endif
# ifdef attron
# include <term.h>
# endif attron
/*
* @(#)move.c 1.2 (Berkeley) 3/28/83
*/
#undef CTRL
#define CTRL(c) (c - 'A' + 1)
void
domove()
{
PLAY *pp;
int i, j;
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 {
if (is_safety(pp->hand[Card_no])) {
error("discard a safety?");
goodplay = FALSE;
break;
}
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;
#ifdef DEBUG
if (Debug)
fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
#endif
acc:
if (Play == COMP) {
account(*Topcard);
if (is_safety(*Topcard))
pp->safety[*Topcard-S_CONV] = S_IN_HAND;
}
if (pp->hand[1] == C_INIT && Topcard > Deck) {
Card_no = 1;
pp->hand[1] = *--Topcard;
#ifdef DEBUG
if (Debug)
fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
#endif
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();
}
/*
* Check and see if either side can go. If they cannot,
* the game is over
*/
void
check_go()
{
CARD card;
PLAY *pp, *op;
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 (is_safety(card) || canplay(pp, op, card)) {
#ifdef DEBUG
if (Debug) {
fprintf(outf, "CHECK_GO: can play %s (%d), ", C_name[card], card);
fprintf(outf, "is_safety(card) = %d, ", is_safety(card));
fprintf(outf, "canplay(pp, op, card) = %d\n", canplay(pp, op, card));
}
#endif
return;
}
#ifdef DEBUG
else if (Debug)
fprintf(outf, "CHECK_GO: cannot play %s\n",
C_name[card]);
#endif
}
}
Finished = TRUE;
}
int
playcard(pp)
PLAY *pp;
{
int v;
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];
#ifdef DEBUG
if (Debug)
fprintf(outf, "PLAYCARD: Card = %s\n", C_name[card]);
#endif
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
&& !is_repair(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 && !is_repair(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 && is_repair(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 == (bool)-1 ? FALSE : TRUE);
return TRUE;
}
void
getmove()
{
char c;
#ifdef EXTRAP
static bool last_ex = FALSE; /* set if last command was E */
if (last_ex) {
undoex();
prboard();
last_ex = FALSE;
}
#endif
for (;;) {
prompt(MOVEPROMPT);
leaveok(Board, FALSE);
refresh();
while ((c = readch()) == 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;
if (Window == W_SMALL) {
if (!Order)
mvwaddstr(Score, 12, 21,
"o: order hand");
else
mvwaddstr(Score, 12, 21,
"o: stop ordering");
wclrtoeol(Score);
}
Movetype = M_ORDER;
goto ret;
case 'Q': /* Quit */
rub(0); /* 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'):
wrefresh(curscr);
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 ' ': /* Spaces */
case '\0': /* and nulls */
break;
#ifdef DEBUG
case 'Z': /* Debug code */
if (!Debug && outf == NULL) {
char buf[MAXPATHLEN];
prompt(FILEPROMPT);
leaveok(Board, FALSE);
refresh();
sp = buf;
while ((*sp = readch()) != '\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)
warn("%s", buf);
setbuf(outf, (char *)NULL);
}
Debug = !Debug;
break;
#endif
default:
error("unknown command: %s", unctrl(c));
break;
}
}
ret:
leaveok(Board, TRUE);
}
/*
* return whether or not the player has picked
*/
int
haspicked(pp)
const PLAY *pp;
{
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);
}
void
account(card)
CARD card;
{
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;
}
}
void
prompt(promptno)
int promptno;
{
static const char *const names[] = {
">>:Move:",
"Really?",
"Another hand?",
"Another game?",
"Save game?",
"Same file?",
"file:",
"Extension?",
"Overwrite file?",
};
static int last_prompt = -1;
if (promptno == last_prompt)
move(MOVE_Y, MOVE_X + strlen(names[promptno]) + 1);
else {
move(MOVE_Y, MOVE_X);
if (promptno == MOVEPROMPT)
standout();
addstr(names[promptno]);
if (promptno == MOVEPROMPT)
standend();
addch(' ');
last_prompt = promptno;
}
clrtoeol();
}
void
sort(hand)
CARD *hand;
{
CARD *cp, *tp;
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;
}
}

180
mille/print.c Normal file
View File

@@ -0,0 +1,180 @@
/* $NetBSD: print.c,v 1.6 1997/10/12 00:54:24 lukem Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)print.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: print.c,v 1.6 1997/10/12 00:54:24 lukem Exp $");
#endif
#endif /* not lint */
# include "mille.h"
/*
* @(#)print.c 1.1 (Berkeley) 4/1/82
*/
# define COMP_STRT 20
# define CARD_STRT 2
void
prboard()
{
PLAY *pp;
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 && !pp->sh_safety[i]) {
mvaddstr(i, temp, C_name[i + S_CONV]);
if (pp->coups[i])
mvaddch(i, temp - CARD_STRT, '*');
pp->sh_safety[i] = TRUE;
}
show_card(14, temp, pp->battle, &pp->sh_battle);
show_card(16, temp, pp->speed, &pp->sh_speed);
for (i = C_25; i <= C_200; i++) {
const char *name;
int end;
if (pp->nummiles[i] == pp->sh_nummiles[i])
continue;
name = C_name[i];
temp = k * 40;
end = pp->nummiles[i];
for (j = pp->sh_nummiles[i]; j < end; j++)
mvwaddstr(Miles, i + 1, (j << 2) + temp, name);
pp->sh_nummiles[i] = end;
}
}
prscore(TRUE);
temp = CARD_STRT;
pp = &Player[PLAYER];
for (i = 0; i < HAND_SZ; i++)
show_card(i + 6, temp, pp->hand[i], &pp->sh_hand[i]);
mvprintw(6, COMP_STRT + CARD_STRT, "%2d", Topcard - Deck);
show_card(8, COMP_STRT + CARD_STRT, Discard, &Sh_discard);
if (End == 1000) {
move(EXT_Y, EXT_X);
standout();
addstr("Extension");
standend();
}
wrefresh(Board);
wrefresh(Miles);
wrefresh(Score);
}
/*
* show_card:
* Show the given card if it is different from the last one shown
*/
void
show_card(y, x, c, lc)
int y, x;
CARD c, *lc;
{
if (c == *lc)
return;
mvprintw(y, x, C_fmt, C_name[c]);
*lc = c;
}
static char Score_fmt[] = "%4d";
void
prscore(for_real)
bool for_real;
{
PLAY *pp;
int x;
stdscr = Score;
for (pp = Player; pp < &Player[2]; pp++) {
x = (pp - Player) * 6 + 21;
show_score(1, x, pp->mileage, &pp->sh_mileage);
if (pp->safescore != pp->sh_safescore) {
mvprintw(2, x, Score_fmt, pp->safescore);
if (pp->safescore == 400)
mvaddstr(3, x + 1, "300");
else
mvaddstr(3, x + 1, " 0");
mvprintw(4, x, Score_fmt, pp->coupscore);
pp->sh_safescore = pp->safescore;
}
if (Window == W_FULL || Finished) {
#ifdef EXTRAP
if (for_real)
finalscore(pp);
else
extrapolate(pp);
#else
finalscore(pp);
#endif
show_score(11, x, pp->hand_tot, &pp->sh_hand_tot);
show_score(13, x, pp->total, &pp->sh_total);
show_score(14, x, pp->games, &pp->sh_games);
}
else {
show_score(6, x, pp->hand_tot, &pp->sh_hand_tot);
show_score(8, x, pp->total, &pp->sh_total);
show_score(9, x, pp->games, &pp->sh_games);
}
}
stdscr = Board;
}
/*
* show_score:
* Show a score value if it is different from the last time we
* showed it.
*/
void
show_score(y, x, s, ls)
int y, x;
int s, *ls;
{
if (s == *ls)
return;
mvprintw(y, x, Score_fmt, s);
*ls = s;
}

65
mille/roll.c Normal file
View File

@@ -0,0 +1,65 @@
/* $NetBSD: roll.c,v 1.6 1997/10/12 00:54:28 lukem Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)roll.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: roll.c,v 1.6 1997/10/12 00:54:28 lukem Exp $");
#endif
#endif /* not lint */
# include "mille.h"
/*
* This routine rolls ndie nside-sided dice.
*
* @(#)roll.c 1.1 (Berkeley) 4/1/82
*
*/
int
roll(ndie, nsides)
int ndie, nsides;
{
int tot;
tot = 0;
while (ndie--)
tot += random() % nsides + 1;
return tot;
}

181
mille/save.c Normal file
View File

@@ -0,0 +1,181 @@
/* $NetBSD: save.c,v 1.6 1997/10/12 00:54:32 lukem Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)save.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: save.c,v 1.6 1997/10/12 00:54:32 lukem Exp $");
#endif
#endif /* not lint */
#include "mille.h"
#ifndef unctrl
#include "unctrl.h"
#endif
# ifdef attron
# include <term.h>
# endif attron
#include <time.h>
/*
* @(#)save.c 1.2 (Berkeley) 3/28/83
*/
typedef struct stat STAT;
/*
* This routine saves the current game for use at a later date
* Returns FALSE if it couldn't be done.
*/
bool
save()
{
char *sp;
int outf;
time_t *tp;
char buf[80];
time_t tme;
STAT junk;
bool rv;
sp = NULL;
tp = &tme;
if (Fromfile && getyn(SAMEFILEPROMPT))
strcpy(buf, Fromfile);
else {
over:
prompt(FILEPROMPT);
leaveok(Board, FALSE);
refresh();
sp = buf;
while ((*sp = readch()) != '\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));
++sp;
}
refresh();
}
*sp = '\0';
leaveok(Board, TRUE);
}
/*
* check for existing files, and confirm overwrite if needed
*/
if (sp == buf || (!Fromfile && stat(buf, &junk) > -1
&& getyn(OVERWRITEFILEPROMPT) == FALSE))
return FALSE;
if ((outf = creat(buf, 0644)) < 0) {
error(strerror(errno));
return FALSE;
}
mvwaddstr(Score, ERR_Y, ERR_X, buf);
wrefresh(Score);
time(tp); /* get current time */
rv = varpush(outf, writev);
close(outf);
if (rv == FALSE) {
unlink(buf);
} else {
strcpy(buf, ctime(tp));
for (sp = buf; *sp != '\n'; sp++)
continue;
*sp = '\0';
wprintw(Score, " [%s]", buf);
}
wclrtoeol(Score);
wrefresh(Score);
return rv;
}
/*
* 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.
*/
bool
rest_f(file)
const char *file;
{
char *sp;
int inf;
char buf[80];
STAT sbuf;
if ((inf = open(file, O_RDONLY)) < 0) {
warn("%s", file);
exit(1);
}
if (fstat(inf, &sbuf) < 0) { /* get file stats */
warn("%s", file);
exit(1);
}
varpush(inf, readv);
close(inf);
strcpy(buf, ctime(&sbuf.st_mtime));
for (sp = buf; *sp != '\n'; sp++)
continue;
*sp = '\0';
/*
* initialize some necessary values
*/
(void)sprintf(Initstr, "%s [%s]\n", file, buf);
Fromfile = file;
return !On_exit;
}

76
mille/table.c Normal file
View File

@@ -0,0 +1,76 @@
/* $NetBSD: table.c,v 1.5 1997/10/12 00:54:36 lukem Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1982, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)table.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: table.c,v 1.5 1997/10/12 00:54:36 lukem Exp $");
#endif
#endif /* not lint */
# define DEBUG
/*
* @(#)table.c 1.1 (Berkeley) 4/1/82
*/
# include "mille.h"
int main __P((int, char **));
int
main(argc, argv)
int argc;
char *argv[];
{
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)]);
}
}

86
mille/types.c Normal file
View File

@@ -0,0 +1,86 @@
/* $NetBSD: types.c,v 1.6 1997/10/12 00:54:40 lukem Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)types.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: types.c,v 1.6 1997/10/12 00:54:40 lukem Exp $");
#endif
#endif /* not lint */
# include "mille.h"
/*
* @(#)types.c 1.1 (Berkeley) 4/1/82
*/
int
is_repair(card)
CARD card;
{
return card == C_GAS || card == C_SPARE ||
card == C_REPAIRS || card == C_INIT;
}
int
safety(card)
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 */
return(0);
}

114
mille/varpush.c Normal file
View File

@@ -0,0 +1,114 @@
/* $NetBSD: varpush.c,v 1.6 1997/10/12 00:54:44 lukem Exp $ */
/*
* Copyright (c) 1982, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)varpush.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: varpush.c,v 1.6 1997/10/12 00:54:44 lukem Exp $");
#endif
#endif /* not lint */
# include <paths.h>
# include "mille.h"
/*
* @(#)varpush.c 1.1 (Berkeley) 4/1/82
*/
/*
* push variables around via the routine func() on the file
* channel file. func() is either read or write.
*/
bool
varpush(file, func)
int file;
#if defined(__linux__) && !defined(__GLIBC__)
ssize_t (*func) __P((int, const struct iovec *, size_t));
#else
ssize_t (*func) __P((int, const struct iovec *, int));
#endif
{
int temp;
const struct iovec vec[] = {
{ (void *) &Debug, sizeof Debug },
{ (void *) &Finished, sizeof Finished },
{ (void *) &Order, sizeof Order },
{ (void *) &End, sizeof End },
{ (void *) &On_exit, sizeof On_exit },
{ (void *) &Handstart, sizeof Handstart },
{ (void *) &Numgos, sizeof Numgos },
{ (void *) Numseen, sizeof Numseen },
{ (void *) &Play, sizeof Play },
{ (void *) &Window, sizeof Window },
{ (void *) Deck, sizeof Deck },
{ (void *) &Discard, sizeof Discard },
{ (void *) Player, sizeof Player }
};
if (((func)(file, vec, sizeof(vec) / sizeof(vec[0]))) < 0) {
error(strerror(errno));
return FALSE;
}
if (func == readv) {
if ((read(file, (void *) &temp, sizeof temp)) < 0) {
error(strerror(errno));
return FALSE;
}
Topcard = &Deck[temp];
#ifdef DEBUG
if (Debug) {
char buf[80];
over:
printf("Debug file:");
gets(buf);
if ((outf = fopen(buf, "w")) == NULL) {
warn("%s", buf);
goto over;
}
if (strcmp(buf, _PATH_DEVNULL) != 0)
setbuf(outf, (char *)NULL);
}
#endif
} else {
temp = Topcard - Deck;
if ((write(file, (void *) &temp, sizeof temp)) < 0) {
error(strerror(errno));
return FALSE;
}
}
return TRUE;
}