Importing games/monop

No Minix specific changes needed.

Change-Id: I362b974a95911d26fcd8a4401129ca946179d93c
This commit is contained in:
Thomas Cort 2014-03-16 10:42:24 -04:00 committed by Lionel Sambuc
parent 5f9253d438
commit 0c3cfeffb3
21 changed files with 4167 additions and 1 deletions

View File

@ -560,6 +560,7 @@
./usr/games/factor minix-sys
./usr/games/fortune minix-sys
./usr/games/hide minix-sys
./usr/games/monop minix-sys
./usr/games/morse minix-sys
./usr/games/number minix-sys
./usr/games/pig minix-sys
@ -4758,6 +4759,7 @@
./usr/man/man6/bcd.6 minix-sys
./usr/man/man6/factor.6 minix-sys
./usr/man/man6/fortune.6 minix-sys
./usr/man/man6/monop.6 minix-sys
./usr/man/man6/morse.6 minix-sys
./usr/man/man6/number.6 minix-sys
./usr/man/man6/pig.6 minix-sys

View File

@ -11,7 +11,7 @@ SUBDIR= adventure \
bcd \
\
factor fortune \
morse number \
monop morse number \
pig ppt primes
.if !defined(__MINIX)

12
games/monop/Makefile Normal file
View File

@ -0,0 +1,12 @@
# $NetBSD: Makefile,v 1.30 2008/02/24 02:43:18 dholland Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
.include <bsd.own.mk>
PROG= monop
SRCS= monop.c cards.c execute.c getinp.c houses.c jail.c misc.c \
morg.c print.c prop.c rent.c roll.c spec.c trade.c
MAN= monop.6
HIDEGAME=hidegame
.include <bsd.prog.mk>

397
games/monop/cards.c Normal file
View File

@ -0,0 +1,397 @@
/* $NetBSD: cards.c,v 1.25 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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[] = "@(#)cards.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: cards.c,v 1.25 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <sys/endian.h>
#include "monop.h"
#include "deck.h"
/*
* These routine deal with the card decks
*/
static void set_up(DECK *);
static void printmes(const char *text);
#define GOJF 'F' /* char for get-out-of-jail-free cards */
struct cardinfo {
const char *actioncode;
const char *text;
};
static const struct cardinfo cc_cards[] = {
{ "FF",
">> GET OUT OF JAIL FREE <<\n"
"Keep this card until needed or sold\n"
},
{ "++25",
"Receive for Services $25.\n"
},
{ "++200",
"Bank Error in Your Favor.\n"
"Collect $200.\n"
},
{ "++20",
"Income Tax Refund.\n"
"Collect $20.\n"
},
{ "--100",
"Pay Hospital $100\n"
},
{ "++100",
"Life Insurance Matures.\n"
"Collect $100\n"
},
{ "++45",
"From sale of Stock You get $45.\n"
},
{ "TX",
"You are Assessed for street repairs.\n"
"\t$40 per House\n"
"\t$115 per Hotel\n"
},
{ "++100",
"X-mas Fund Matures.\n"
"Collect $100.\n"
},
{ "++11",
"You have won Second Prize in a Beauty Contest\n"
"Collect $11\n"
},
{ "MF0",
"Advance to GO\n"
"(Collect $200)\n"
},
{ "++100",
"You inherit $100\n"
},
{ "--150",
"Pay School Tax of $150.\n"
},
{ "MJ",
"\t\t>> GO TO JAIL <<\n"
"Go Directly to Jail. Do not pass GO Do not collect $200.\n"
},
{ "+A50",
"\t\t>> GRAND OPERA OPENING <<\n"
"Collect $50 from each player for opening night seats.\n"
},
{ "--50",
"Doctor's Fee: Pay $50.\n"
}
};
static const struct cardinfo ch_cards[] = {
{ "FF",
">> GET OUT OF JAIL FREE <<\n"
"Keep this card until needed or sold\n"
},
{ "MR",
"Advance to the nearest Railroad, and pay owner\n"
"Twice the rental to which he is otherwise entitled.\n"
"If Railroad is unowned you may buy it from the bank\n"
},
{ "MU",
"Advance to the nearest Utility.\n"
"If unowned, you may buy it from the bank.\n"
"If owned, throw dice and pay oner a total of ten times\n"
"the amount thrown.\n"
},
{ "MB3",
"Go Back 3 Spaces\n"
},
{ "MR",
"Advance to the nearest Railroad, and pay owner\n"
"Twice the rental to which he is otherwise entitled.\n"
"If Railroad is unowned you may buy it from the bank\n"
},
{ "MJ",
" >> GO DIRECTLY TO JAIL <<\n"
"Do not pass GO, Do not Collect $200.\n"
},
{ "MF5",
"Take a Ride on the Reading.\n"
"If you pass GO, collect $200.\n"
},
{ "MF39",
"Take a Walk on the Board Walk.\n"
" (Advance To Board Walk)\n"
},
{ "MF24",
"Advance to Illinois Ave.\n"
},
{ "MF0",
"Advance to Go\n"
},
{ "MF11",
"Advance to St. Charles Place.\n"
"If you pass GO, collect $200.\n"
},
{ "TX",
"Make general repairs on all of your Property.\n"
"For Each House pay $25.\n"
"For Each Hotel pay $100.\n"
},
{ "-A50",
"You have been elected Chairman of the Board.\n"
"Pay each player $50.\n"
},
{ "--15",
"Pay Poor Tax of $15\n"
},
{ "++50",
"Bank pays you Dividend of $50.\n"
},
{ "++150",
"Your Building and Loan Matures.\n"
"Collect $150.\n"
}
};
/*
* This routine initializes the decks from the data above.
*/
void
init_decks(void)
{
CC_D.info = cc_cards;
CC_D.num_cards = sizeof(cc_cards) / sizeof(cc_cards[0]);
CH_D.info = ch_cards;
CH_D.num_cards = sizeof(ch_cards) / sizeof(ch_cards[0]);
set_up(&CC_D);
set_up(&CH_D);
}
/*
* This routine sets up the offset pointers for the given deck.
*/
static void
set_up(DECK *dp)
{
int r1, r2;
int i;
dp->cards = calloc((size_t)dp->num_cards, sizeof(dp->cards[0]));
if (dp->cards == NULL)
errx(1, "out of memory");
for (i = 0; i < dp->num_cards; i++)
dp->cards[i] = i;
dp->top_card = 0;
dp->gojf_used = FALSE;
for (i = 0; i < dp->num_cards; i++) {
int temp;
r1 = roll(1, dp->num_cards) - 1;
r2 = roll(1, dp->num_cards) - 1;
temp = dp->cards[r2];
dp->cards[r2] = dp->cards[r1];
dp->cards[r1] = temp;
}
}
/*
* This routine draws a card from the given deck
*/
void
get_card(DECK *dp)
{
char type_maj, type_min;
int num;
int i, per_h, per_H, num_h, num_H;
OWN *op;
const struct cardinfo *thiscard;
do {
thiscard = &dp->info[dp->top_card];
type_maj = thiscard->actioncode[0];
dp->top_card = (dp->top_card + 1) % dp->num_cards;
} while (dp->gojf_used && type_maj == GOJF);
type_min = thiscard->actioncode[1];
num = atoi(thiscard->actioncode+2);
printmes(thiscard->text);
switch (type_maj) {
case '+': /* get money */
if (type_min == 'A') {
for (i = 0; i < num_play; i++)
if (i != player)
play[i].money -= num;
num = num * (num_play - 1);
}
cur_p->money += num;
break;
case '-': /* lose money */
if (type_min == 'A') {
for (i = 0; i < num_play; i++)
if (i != player)
play[i].money += num;
num = num * (num_play - 1);
}
cur_p->money -= num;
break;
case 'M': /* move somewhere */
switch (type_min) {
case 'F': /* move forward */
num -= cur_p->loc;
if (num < 0)
num += 40;
break;
case 'J': /* move to jail */
goto_jail();
return;
case 'R': /* move to railroad */
spec = TRUE;
num = (int)((cur_p->loc + 5)/10)*10 + 5 - cur_p->loc;
break;
case 'U': /* move to utility */
spec = TRUE;
if (cur_p->loc >= 12 && cur_p->loc < 28)
num = 28 - cur_p->loc;
else {
num = 12 - cur_p->loc;
if (num < 0)
num += 40;
}
break;
case 'B':
num = -num;
break;
}
move(num);
break;
case 'T': /* tax */
if (dp == &CC_D) {
per_h = 40;
per_H = 115;
}
else {
per_h = 25;
per_H = 100;
}
num_h = num_H = 0;
for (op = cur_p->own_list; op; op = op->next)
if (op->sqr->type == PRPTY) {
if (op->sqr->desc->houses == 5)
++num_H;
else
num_h += op->sqr->desc->houses;
}
num = per_h * num_h + per_H * num_H;
printf(
"You had %d Houses and %d Hotels, so that cost you $%d\n",
num_h, num_H, num);
if (num == 0)
lucky("");
else
cur_p->money -= num;
break;
case GOJF: /* get-out-of-jail-free card */
cur_p->num_gojf++;
dp->gojf_used = TRUE;
break;
}
spec = FALSE;
}
/*
* This routine prints out the message on the card
*/
static void
printmes(const char *text)
{
int i;
printline();
fflush(stdout);
for (i = 0; text[i] != '\0'; i++)
putchar(text[i]);
printline();
fflush(stdout);
}
/*
* This routine returns the players get-out-of-jail-free card
* to the bottom of a deck. XXX currently does not return to the correct
* deck.
*/
void
ret_card(PLAY *plr)
{
char type_maj;
int gojfpos, last_card;
int i;
DECK *dp;
int temp;
plr->num_gojf--;
if (CC_D.gojf_used)
dp = &CC_D;
else
dp = &CH_D;
dp->gojf_used = FALSE;
/* Put at bottom of deck (top_card - 1) and remove it from wherever else
* it used to be.
*/
last_card = dp->top_card - 1;
if (last_card < 0)
last_card += dp->num_cards;
gojfpos = dp->top_card;
do {
gojfpos = (gojfpos + 1) % dp->num_cards;
type_maj = dp->info[gojfpos].actioncode[0];
} while (type_maj != GOJF);
temp = dp->cards[gojfpos];
/* Only one of the next two loops does anything */
for (i = gojfpos - 1; i > last_card; i--)
dp->cards[i + 1] = dp->cards[i];
for (i = gojfpos; i < last_card; i++)
dp->cards[i] = dp->cards[i + 1];
if (gojfpos > last_card) {
dp->cards[dp->top_card] = temp;
dp->top_card++;
dp->top_card %= dp->num_cards;
} else
dp->cards[last_card] = temp;
}

58
games/monop/deck.h Normal file
View File

@ -0,0 +1,58 @@
/* $NetBSD: deck.h,v 1.9 2008/02/24 02:43:18 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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.
*
* @(#)deck.h 8.1 (Berkeley) 5/31/93
*/
#include <sys/types.h>
#define bool char
struct cardinfo; /* private to cards.c */
#define CC_D deck[0]
#define CH_D deck[1]
struct dk_st { /* deck description structure */
int num_cards; /* number of cards in deck */
int top_card; /* number of last card picked */
bool gojf_used; /* set if gojf card out of deck */
int *cards; /* which cards (indexes info[]) */
const struct cardinfo *info; /* the static card data */
};
typedef struct dk_st DECK;
extern DECK deck[2];
/* cards.c */
void init_decks(void);
void get_card(DECK *);

761
games/monop/execute.c Normal file
View File

@ -0,0 +1,761 @@
/* $NetBSD: execute.c,v 1.22 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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[] = "@(#)execute.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: execute.c,v 1.22 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include "deck.h"
#include "monop.h"
#define MIN_FORMAT_VERSION 1
#define CUR_FORMAT_VERSION 1
#define MAX_FORMAT_VERSION 1
typedef struct stat STAT;
typedef struct tm TIME;
static char buf[257];
static bool new_play; /* set if move on to new player */
static void show_move(void);
static void restore_reset(void);
static int restore_parseline(char *txt);
static int restore_toplevel_attr(const char *attribute, char *txt);
static int restore_player_attr(const char *attribute, char *txt);
static int restore_deck_attr(const char *attribute, char *txt);
static int restore_square_attr(const char *attribute, char *txt);
static int getnum(const char *what, char *txt, int min, int max, int *ret);
static int getnum_withbrace(const char *what, char *txt, int min, int max,
int *ret);
/*
* This routine executes the given command by index number
*/
void
execute(int com_num)
{
new_play = FALSE; /* new_play is true if fixing */
(*func[com_num])();
notify();
force_morg();
if (new_play)
next_play();
else if (num_doub)
printf("%s rolled doubles. Goes again\n", cur_p->name);
}
/*
* This routine moves a piece around.
*/
void
do_move(void)
{
int r1, r2;
bool was_jail;
new_play = was_jail = FALSE;
printf("roll is %d, %d\n", r1=roll(1, 6), r2=roll(1, 6));
if (cur_p->loc == JAIL) {
was_jail++;
if (!move_jail(r1, r2)) {
new_play++;
goto ret;
}
}
else {
if (r1 == r2 && ++num_doub == 3) {
printf("That's 3 doubles. You go to jail\n");
goto_jail();
new_play++;
goto ret;
}
move(r1+r2);
}
if (r1 != r2 || was_jail)
new_play++;
ret:
return;
}
/*
* This routine moves a normal move
*/
void
move(int rl)
{
int old_loc;
old_loc = cur_p->loc;
cur_p->loc = (cur_p->loc + rl) % N_SQRS;
if (cur_p->loc < old_loc && rl > 0) {
cur_p->money += 200;
printf("You pass %s and get $200\n", board[0].name);
}
show_move();
}
/*
* This routine shows the results of a move
*/
static void
show_move(void)
{
SQUARE *sqp;
sqp = &board[cur_p->loc];
printf("That puts you on %s\n", sqp->name);
switch (sqp->type) {
case SAFE:
printf("That is a safe place\n");
break;
case CC:
cc();
break;
case CHANCE:
chance();
break;
case INC_TAX:
inc_tax();
break;
case GOTO_J:
goto_jail();
break;
case LUX_TAX:
lux_tax();
break;
case PRPTY:
case RR:
case UTIL:
if (sqp->owner < 0) {
printf("That would cost $%d\n", sqp->cost);
if (getyn("Do you want to buy? ") == 0) {
buy(player, sqp);
cur_p->money -= sqp->cost;
}
else if (num_play > 2)
bid();
}
else if (sqp->owner == player)
printf("You own it.\n");
else
rent(sqp);
}
}
/*
* Reset the game state.
*/
static void
reset_game(void)
{
int i;
for (i = 0; i < N_SQRS; i++) {
board[i].owner = -1;
if (board[i].type == PRPTY) {
board[i].desc->morg = 0;
board[i].desc->houses = 0;
} else if (board[i].type == RR || board[i].type == UTIL) {
board[i].desc->morg = 0;
}
}
for (i = 0; i < 2; i++) {
deck[i].top_card = 0;
deck[i].gojf_used = FALSE;
}
if (play) {
for (i = 0; i < num_play; i++) {
free(play[i].name);
play[i].name = NULL;
}
free(play);
play = NULL;
}
for (i = 0; i < MAX_PL+2; i++) {
name_list[i] = NULL;
}
cur_p = NULL;
num_play = 0;
player = 0;
num_doub = 0;
fixing = FALSE;
trading = FALSE;
told_em = FALSE;
spec = FALSE;
}
/*
* This routine saves the current game for use at a later date
*/
void
save(void)
{
char *sp;
FILE *outf;
time_t t;
struct stat sb;
int i, j;
printf("Which file do you wish to save it in? ");
fgets(buf, sizeof(buf), stdin);
if (feof(stdin))
return;
sp = strchr(buf, '\n');
if (sp)
*sp = '\0';
/*
* check for existing files, and confirm overwrite if needed
*/
if (stat(buf, &sb) == 0
&& getyn("File exists. Do you wish to overwrite? ") > 0)
return;
outf = fopen(buf, "w");
if (outf == NULL) {
warn("%s", buf);
return;
}
printf("\"%s\" ", buf);
time(&t); /* get current time */
/* Header */
fprintf(outf, "NetBSD monop format v%d\n", CUR_FORMAT_VERSION);
fprintf(outf, "time %s", ctime(&t)); /* ctime includes a \n */
fprintf(outf, "numplayers %d\n", num_play);
fprintf(outf, "currentplayer %d\n", player);
fprintf(outf, "doubles %d\n", num_doub);
/* Players */
for (i = 0; i < num_play; i++) {
fprintf(outf, "player %d {\n", i);
fprintf(outf, " name %s\n", name_list[i]);
fprintf(outf, " money %d\n", play[i].money);
fprintf(outf, " loc %d\n", play[i].loc);
fprintf(outf, " num_gojf %d\n", play[i].num_gojf);
fprintf(outf, " in_jail %d\n", play[i].in_jail);
fprintf(outf, "}\n");
}
/* Decks */
for (i = 0; i < 2; i++) {
fprintf(outf, "deck %d {\n", i);
fprintf(outf, " numcards %d\n", deck[i].num_cards);
fprintf(outf, " topcard %d\n", deck[i].top_card);
fprintf(outf, " gojf_used %d\n", deck[i].gojf_used);
fprintf(outf, " cards");
for (j = 0; j < deck[i].num_cards; j++)
fprintf(outf, " %d", deck[i].cards[j]);
fprintf(outf, "\n");
fprintf(outf, "}\n");
}
/* Board */
for (i = 0; i < N_SQRS; i++) {
fprintf(outf, "square %d {\n", i);
fprintf(outf, "owner %d\n", board[i].owner);
if (board[i].owner < 0) {
/* nothing */
} else if (board[i].type == PRPTY) {
fprintf(outf, "morg %d\n", board[i].desc->morg);
fprintf(outf, "houses %d\n", board[i].desc->houses);
} else if (board[i].type == RR || board[i].type == UTIL) {
fprintf(outf, "morg %d\n", board[i].desc->morg);
}
fprintf(outf, "}\n");
}
if (ferror(outf) || fflush(outf))
warnx("write error");
fclose(outf);
strcpy(buf, ctime(&t));
for (sp = buf; *sp != '\n'; sp++)
continue;
*sp = '\0';
printf("[%s]\n", buf);
}
/*
* This routine restores an old game from a file
*/
void
restore(void)
{
char *sp;
for (;;) {
printf("Which file do you wish to restore from? ");
fgets(buf, sizeof(buf), stdin);
if (feof(stdin))
return;
sp = strchr(buf, '\n');
if (sp)
*sp = '\0';
if (rest_f(buf) == 0)
break;
}
}
/*
* This does the actual restoring. It returns zero on success,
* and -1 on failure.
*/
int
rest_f(const char *file)
{
char *sp;
FILE *inf;
char xbuf[80];
STAT sbuf;
char readbuf[512];
int ret = 0;
inf = fopen(file, "r");
if (inf == NULL) {
warn("%s", file);
return -1;
}
printf("\"%s\" ", file);
if (fstat(fileno(inf), &sbuf) < 0) {
err(1, "%s: fstat", file);
}
/* Clear the game state to prevent brokenness on misordered files. */
reset_game();
/* Reset the parser */
restore_reset();
/* Note: can't use buf[], file might point at it. (Lame...) */
while (fgets(readbuf, sizeof(readbuf), inf)) {
/*
* The input buffer is long enough to handle anything
* that's supposed to be in the output buffer, so if
* we get a partial line, complain.
*/
sp = strchr(readbuf, '\n');
if (sp == NULL) {
printf("file is corrupt: long lines.\n");
ret = -1;
break;
}
*sp = '\0';
if (restore_parseline(readbuf)) {
ret = -1;
break;
}
}
if (ferror(inf))
warnx("%s: read error", file);
fclose(inf);
if (ret < 0)
return -1;
name_list[num_play] = "done";
if (play == NULL || cur_p == NULL || num_play < 2) {
printf("save file is incomplete.\n");
return -1;
}
/*
* We could at this point crosscheck the following:
* - there are only two GOJF cards floating around
* - total number of houses and hotels does not exceed maximums
* - no props are both built and mortgaged
* but for now we don't.
*/
strcpy(xbuf, ctime(&sbuf.st_mtime));
for (sp = xbuf; *sp != '\n'; sp++)
continue;
*sp = '\0';
printf("[%s]\n", xbuf);
return 0;
}
/*
* State of the restore parser
*/
static int restore_version;
static enum {
RI_NONE,
RI_PLAYER,
RI_DECK,
RI_SQUARE
} restore_item;
static int restore_itemnum;
/*
* Reset the restore parser
*/
static void
restore_reset(void)
{
restore_version = -1;
restore_item = RI_NONE;
restore_itemnum = -1;
}
/*
* Handle one line of the save file
*/
static int
restore_parseline(char *txt)
{
char *attribute;
char *s;
if (restore_version < 0) {
/* Haven't seen the header yet. Demand it right away. */
if (!strncmp(txt, "NetBSD monop format v", 21)) {
return getnum("format version", txt+21,
MIN_FORMAT_VERSION,
MAX_FORMAT_VERSION,
&restore_version);
}
printf("file is not a monop save file.\n");
return -1;
}
/* Check for lines that are right braces. */
if (!strcmp(txt, "}")) {
if (restore_item == RI_NONE) {
printf("mismatched close brace.\n");
return -1;
}
restore_item = RI_NONE;
restore_itemnum = -1;
return 0;
}
/* Any other line must begin with a word, which is the attribute. */
s = txt;
while (*s==' ')
s++;
attribute = s;
s = strchr(attribute, ' ');
if (s == NULL) {
printf("file is corrupt: attribute %s lacks value.\n",
attribute);
return -1;
}
*(s++) = '\0';
while (*s==' ')
s++;
/* keep the remaining text for further handling */
txt = s;
switch (restore_item) {
case RI_NONE:
/* toplevel attributes */
return restore_toplevel_attr(attribute, txt);
case RI_PLAYER:
/* player attributes */
return restore_player_attr(attribute, txt);
case RI_DECK:
/* deck attributes */
return restore_deck_attr(attribute, txt);
case RI_SQUARE:
/* board square attributes */
return restore_square_attr(attribute, txt);
}
/* NOTREACHED */
printf("internal logic error\n");
return -1;
}
static int
restore_toplevel_attr(const char *attribute, char *txt)
{
if (!strcmp(attribute, "time")) {
/* nothing */
} else if (!strcmp(attribute, "numplayers")) {
if (getnum("numplayers", txt, 2, MAX_PL, &num_play) < 0) {
return -1;
}
if (play != NULL) {
printf("numplayers: multiple settings\n");
return -1;
}
play = calloc((size_t)num_play, sizeof(play[0]));
if (play == NULL) {
err(1, "calloc");
}
} else if (!strcmp(attribute, "currentplayer")) {
if (getnum("currentplayer", txt, 0, num_play-1, &player) < 0) {
return -1;
}
if (play == NULL) {
printf("currentplayer: before numplayers\n");
return -1;
}
cur_p = &play[player];
} else if (!strcmp(attribute, "doubles")) {
if (getnum("doubles", txt, 0, 2, &num_doub) < 0) {
return -1;
}
} else if (!strcmp(attribute, "player")) {
if (getnum_withbrace("player", txt, 0, num_play-1,
&restore_itemnum) < 0) {
return -1;
}
restore_item = RI_PLAYER;
} else if (!strcmp(attribute, "deck")) {
if (getnum_withbrace("deck", txt, 0, 1,
&restore_itemnum) < 0) {
return -1;
}
restore_item = RI_DECK;
} else if (!strcmp(attribute, "square")) {
if (getnum_withbrace("square", txt, 0, N_SQRS-1,
&restore_itemnum) < 0) {
return -1;
}
restore_item = RI_SQUARE;
} else {
printf("unknown attribute %s\n", attribute);
return -1;
}
return 0;
}
static int
restore_player_attr(const char *attribute, char *txt)
{
PLAY *pp;
int tmp;
if (play == NULL) {
printf("player came before numplayers.\n");
return -1;
}
pp = &play[restore_itemnum];
if (!strcmp(attribute, "name")) {
if (pp->name != NULL) {
printf("player has multiple names.\n");
return -1;
}
/* XXX should really systematize the max name length */
if (strlen(txt) > 256) {
txt[256] = 0;
}
pp->name = strdup(txt);
if (pp->name == NULL)
err(1, "strdup");
name_list[restore_itemnum] = pp->name;
} else if (!strcmp(attribute, "money")) {
if (getnum(attribute, txt, 0, INT_MAX, &pp->money) < 0) {
return -1;
}
} else if (!strcmp(attribute, "loc")) {
/* note: not N_SQRS-1 */
if (getnum(attribute, txt, 0, N_SQRS, &tmp) < 0) {
return -1;
}
pp->loc = tmp;
} else if (!strcmp(attribute, "num_gojf")) {
if (getnum(attribute, txt, 0, 2, &tmp) < 0) {
return -1;
}
pp->num_gojf = tmp;
} else if (!strcmp(attribute, "in_jail")) {
if (getnum(attribute, txt, 0, 3, &tmp) < 0) {
return -1;
}
pp->in_jail = tmp;
if (pp->in_jail > 0 && pp->loc != JAIL) {
printf("player escaped from jail?\n");
return -1;
}
} else {
printf("unknown attribute %s\n", attribute);
return -1;
}
return 0;
}
static int
restore_deck_attr(const char *attribute, char *txt)
{
int tmp, j;
char *s;
DECK *dp;
dp = &deck[restore_itemnum];
if (!strcmp(attribute, "numcards")) {
if (getnum(attribute, txt, dp->num_cards, dp->num_cards,
&tmp) < 0) {
return -1;
}
} else if (!strcmp(attribute, "topcard")) {
if (getnum(attribute, txt, 0, dp->num_cards,
&dp->top_card) < 0) {
return -1;
}
} else if (!strcmp(attribute, "gojf_used")) {
if (getnum(attribute, txt, 0, 1, &tmp) < 0) {
return -1;
}
dp->gojf_used = tmp;
} else if (!strcmp(attribute, "cards")) {
errno = 0;
s = txt;
for (j = 0; j<dp->num_cards; j++) {
tmp = strtol(s, &s, 10);
if (tmp < 0 || tmp >= dp->num_cards) {
printf("cards: out of range value\n");
return -1;
}
dp->cards[j] = tmp;
}
if (errno) {
printf("cards: invalid values\n");
return -1;
}
} else {
printf("unknown attribute %s\n", attribute);
return -1;
}
return 0;
}
static int
restore_square_attr(const char *attribute, char *txt)
{
SQUARE *sp = &board[restore_itemnum];
int tmp;
if (!strcmp(attribute, "owner")) {
if (getnum(attribute, txt, -1, num_play-1, &tmp) < 0) {
return -1;
}
sp->owner = tmp;
if (tmp >= 0)
add_list(tmp, &play[tmp].own_list, restore_itemnum);
} else if (!strcmp(attribute, "morg")) {
if (sp->type != PRPTY && sp->type != RR && sp->type != UTIL) {
printf("unownable property is mortgaged.\n");
return -1;
}
if (getnum(attribute, txt, 0, 1, &tmp) < 0) {
return -1;
}
sp->desc->morg = tmp;
} else if (!strcmp(attribute, "houses")) {
if (sp->type != PRPTY) {
printf("unbuildable property has houses.\n");
return -1;
}
if (getnum(attribute, txt, 0, 5, &tmp) < 0) {
return -1;
}
sp->desc->houses = tmp;
} else {
printf("unknown attribute %s\n", attribute);
return -1;
}
return 0;
}
static int
getnum(const char *what, char *txt, int min, int max, int *ret)
{
char *s;
long l;
errno = 0;
l = strtol(txt, &s, 10);
if (errno || strlen(s)>0) {
printf("%s: not a number.\n", what);
return -1;
}
if (l < min || l > max) {
printf("%s: out of range.\n", what);
}
*ret = l;
return 0;
}
static int
getnum_withbrace(const char *what, char *txt, int min, int max, int *ret)
{
char *s;
s = strchr(txt, ' ');
if (s == NULL) {
printf("%s: expected open brace\n", what);
return -1;
}
*(s++) = '\0';
while (*s == ' ')
s++;
if (*s != '{') {
printf("%s: expected open brace\n", what);
return -1;
}
if (s[1] != 0) {
printf("%s: garbage after open brace\n", what);
return -1;
}
return getnum(what, txt, min, max, ret);
}

119
games/monop/getinp.c Normal file
View File

@ -0,0 +1,119 @@
/* $NetBSD: getinp.c,v 1.19 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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[] = "@(#)getinp.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: getinp.c,v 1.19 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "monop.h"
#define LINE 70
static char buf[257];
static int comp(const char *);
int
getinp(const char *prompt, const char *const lst [])
{
int i, n_match, match = 0;
char *sp;
for (;;) {
printf("%s", prompt);
fgets(buf, sizeof(buf), stdin);
if (feof(stdin)) {
return 0;
}
if (buf[0] == '?' && buf[1] == '\n') {
printf("Valid inputs are: ");
for (i = 0, match = 18; lst[i]; i++) {
if ((match+=(n_match=strlen(lst[i]))) > LINE) {
printf("\n\t");
match = n_match + 8;
}
if (*lst[i] == '\0') {
match += 8;
printf("<RETURN>");
}
else
printf("%s", lst[i]);
if (lst[i+1])
printf(", ");
else
putchar('\n');
match += 2;
}
continue;
}
if ((sp = strchr(buf, '\n')) != NULL)
*sp = '\0';
for (sp = buf; *sp; sp++)
*sp = tolower((unsigned char)*sp);
for (i = n_match = 0; lst[i]; i++)
if (comp(lst[i])) {
n_match++;
match = i;
}
if (n_match == 1)
return match;
else if (buf[0] != '\0')
printf("Illegal response: \"%s\". "
"Use '?' to get list of valid answers\n", buf);
}
}
static int
comp(const char *s1)
{
const char *sp, *tsp;
char c;
if (buf[0] != '\0')
for (sp = buf, tsp = s1; *sp; ) {
c = tolower((unsigned char)*tsp);
tsp++;
if (c != *sp++)
return 0;
}
else if (*s1 != '\0')
return 0;
return 1;
}

387
games/monop/houses.c Normal file
View File

@ -0,0 +1,387 @@
/* $NetBSD: houses.c,v 1.15 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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[] = "@(#)houses.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: houses.c,v 1.15 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include "monop.h"
static const char *names[N_MON+2];
static char cur_prop[80];
static MON *monops[N_MON];
static void buy_h(MON *);
static void sell_h(MON *);
static void list_cur(MON *);
static int get_avail_houses(void);
static int get_avail_hotels(void);
static bool ready_for_hotels(MON *);
/*
* These routines deal with buying and selling houses
*/
void
buy_houses(void)
{
int num_mon;
MON *mp;
OWN *op;
bool good, got_morg;
int i,p;
over:
num_mon = 0;
good = TRUE;
got_morg = FALSE;
for (op = cur_p->own_list; op && op->sqr->type != PRPTY; op = op->next)
continue;
while (op)
if (op->sqr->desc->monop) {
mp = op->sqr->desc->mon_desc;
names[num_mon] = (monops[num_mon]=mp)->name;
num_mon++;
got_morg = good = FALSE;
for (i = 0; i < mp->num_in; i++) {
if (op->sqr->desc->morg)
got_morg = TRUE;
if (op->sqr->desc->houses != 5)
good = TRUE;
op = op->next;
}
if (!good || got_morg)
--num_mon;
}
else
op = op->next;
if (num_mon == 0) {
if (got_morg)
printf("You can't build on mortgaged monopolies.\n");
else if (!good)
printf("You can't build any more.\n");
else
printf("But you don't have any monopolies!!\n");
return;
}
if (num_mon == 1)
buy_h(monops[0]);
else {
names[num_mon++] = "done";
names[num_mon--] = 0;
if ((p = getinp(
"Which property do you wish to buy houses for? ",
names)) == num_mon)
return;
buy_h(monops[p]);
goto over;
}
}
static void
buy_h(MON *mnp)
{
int i;
MON *mp;
int price;
short input[3], result[3];
int wanted_houses, wanted_hotels;
int total_purchase;
PROP *pp;
int avail_houses, avail_hotels;
bool buying_hotels;
mp = mnp;
price = mp->h_cost * 50;
avail_houses = get_avail_houses();
avail_hotels = get_avail_hotels();
buying_hotels = ready_for_hotels(mnp);
if (avail_houses == 0 && !buying_hotels) {
printf("Building shortage: no houses available.");
return;
}
if (avail_hotels == 0 && buying_hotels) {
printf("Building shortage: no hotels available.");
return;
}
blew_it:
list_cur(mp);
printf("Houses will cost $%d\n", price);
printf("How many houses do you wish to buy for\n");
for (i = 0; i < mp->num_in; i++) {
pp = mp->sq[i]->desc;
over:
if (pp->houses == 5) {
printf("%s (H):\n", mp->sq[i]->name);
input[i] = 0;
result[i] = 5;
continue;
}
(void)snprintf(cur_prop, sizeof(cur_prop), "%s (%d): ",
mp->sq[i]->name, pp->houses);
input[i] = get_int(cur_prop);
result[i] = input[i] + pp->houses;
if (result[i] > 5 || result[i] < 0) {
printf("That's too many. The most you can buy is %d\n",
5 - pp->houses);
goto over;
}
}
if (mp->num_in == 3 &&
(abs(result[0] - result[1]) > 1 ||
abs(result[0] - result[2]) > 1 ||
abs(result[1] - result[2]) > 1)) {
err: printf("That makes the spread too wide. Try again\n");
goto blew_it;
}
else if (mp->num_in == 2 && abs(result[0] - result[1]) > 1)
goto err;
wanted_houses = 0;
wanted_hotels = 0;
total_purchase = 0;
for (i = 0; i < mp->num_in; i++) {
wanted_houses += input[i];
total_purchase += input[i];
if (result[i] == 5 && input[i] > 0) {
wanted_hotels++;
wanted_houses--;
}
}
if (wanted_houses > avail_houses) {
printf("You have asked for %d %s but only %d are available. "
"Try again\n",
wanted_houses, wanted_houses == 1 ? "house" : "houses",
avail_houses);
goto blew_it;
} else if (wanted_hotels > avail_hotels) {
printf("You have asked for %d %s but only %d are available. "
"Try again\n",
wanted_hotels, wanted_hotels == 1 ? "hotel" : "hotels",
avail_hotels);
goto blew_it;
}
if (total_purchase) {
printf("You asked for %d %s and %d %s for $%d\n",
wanted_houses, wanted_houses == 1 ? "house" : "houses",
wanted_hotels, wanted_hotels == 1 ? "hotel" : "hotels",
total_purchase * price);
if (getyn("Is that ok? ") == 0) {
cur_p->money -= total_purchase * price;
for (i = 0; i < mp->num_in; i++)
mp->sq[i]->desc->houses = result[i];
}
}
}
/*
* This routine sells houses.
*/
void
sell_houses(void)
{
int num_mon;
MON *mp;
OWN *op;
bool good;
int p;
over:
num_mon = 0;
good = TRUE;
for (op = cur_p->own_list; op;)
if (op->sqr->type == PRPTY && op->sqr->desc->monop) {
mp = op->sqr->desc->mon_desc;
names[num_mon] = (monops[num_mon]=mp)->name;
num_mon++;
good = 0;
do
if (!good && op->sqr->desc->houses != 0)
good = TRUE;
while (op->next && op->sqr->desc->mon_desc == mp
&& (op = op->next));
if (!good)
--num_mon;
} else
op = op->next;
if (num_mon == 0) {
printf("You don't have any houses to sell!!\n");
return;
}
if (num_mon == 1)
sell_h(monops[0]);
else {
names[num_mon++] = "done";
names[num_mon--] = 0;
if ((p = getinp(
"Which property do you wish to sell houses from? ",
names)) == num_mon)
return;
sell_h(monops[p]);
notify();
goto over;
}
}
static void
sell_h(MON *mnp)
{
int i;
MON *mp;
int price;
short input[3],temp[3];
int tot;
PROP *pp;
mp = mnp;
price = mp->h_cost * 25;
blew_it:
printf("Houses will get you $%d apiece\n", price);
list_cur(mp);
printf("How many houses do you wish to sell from\n");
for (i = 0; i < mp->num_in; i++) {
pp = mp->sq[i]->desc;
over:
if (pp->houses == 0) {
printf("%s (0):\n", mp->sq[i]->name);
input[i] = temp[i] = 0;
continue;
}
if (pp->houses < 5)
(void)snprintf(cur_prop, sizeof(cur_prop), "%s (%d): ",
mp->sq[i]->name,pp->houses);
else
(void)snprintf(cur_prop, sizeof(cur_prop), "%s (H): ",
mp->sq[i]->name);
input[i] = get_int(cur_prop);
temp[i] = pp->houses - input[i];
if (temp[i] < 0) {
printf(
"That's too many. The most you can sell is %d\n",
pp->houses);
goto over;
}
}
if (mp->num_in == 3 && (abs(temp[0] - temp[1]) > 1 ||
abs(temp[0] - temp[2]) > 1 || abs(temp[1] - temp[2]) > 1)) {
err: printf("That makes the spread too wide. Try again\n");
goto blew_it;
}
else if (mp->num_in == 2 && abs(temp[0] - temp[1]) > 1)
goto err;
for (tot = i = 0; i < mp->num_in; i++)
tot += input[i];
if (tot) {
printf("You asked to sell %d house%s for $%d\n", tot,
tot == 1 ? "" : "s", tot * price);
if (getyn("Is that ok? ") == 0) {
cur_p->money += tot * price;
for (tot = i = 0; i < mp->num_in; i++)
mp->sq[i]->desc->houses = temp[i];
}
}
}
static void
list_cur(MON *mp)
{
int i;
SQUARE *sqp;
for (i = 0; i < mp->num_in; i++) {
sqp = mp->sq[i];
if (sqp->desc->houses == 5)
printf("%s (H) ", sqp->name);
else
printf("%s (%d) ", sqp->name, sqp->desc->houses);
}
putchar('\n');
}
static int
get_avail_houses(void)
{
int i, c;
SQUARE *sqp;
c = 0;
for (i = 0; i < N_SQRS; i++) {
sqp = &board[i];
if (sqp->type == PRPTY && sqp->owner >= 0 && sqp->desc->monop) {
if (sqp->desc->houses < 5 && sqp->desc->houses > 0)
c += sqp->desc->houses;
}
}
return(N_HOUSE - c);
}
static int
get_avail_hotels(void)
{
int i, c;
SQUARE *sqp;
c = 0;
for (i = 0; i < N_SQRS; i++) {
sqp = &board[i];
if (sqp->type == PRPTY && sqp->owner >= 0 && sqp->desc->monop) {
if (sqp->desc->houses == 5)
c++;
}
}
return(N_HOTEL - c);
}
/*
* If we can put a hotel on, we can't put any houses on, and if we can
* put houses on, then we can't put a hotel on yet.
*/
static bool
ready_for_hotels(MON *mp)
{
int i;
for (i = 0; i < mp->num_in; i++) {
if (mp->sq[i]->desc->houses < 4)
return(FALSE);
}
return(TRUE);
}

123
games/monop/jail.c Normal file
View File

@ -0,0 +1,123 @@
/* $NetBSD: jail.c,v 1.10 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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[] = "@(#)jail.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: jail.c,v 1.10 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include "monop.h"
/*
* This routine uses a get-out-of-jail-free card to get the
* player out of jail.
*/
void
card(void)
{
if (cur_p->loc != JAIL) {
printf("But you're not IN Jail\n");
return;
}
if (cur_p->num_gojf == 0) {
printf("But you don't HAVE a get out of jail free card\n");
return;
}
ret_card(cur_p);
cur_p->loc = 10; /* just visiting */
cur_p->in_jail = 0;
}
/*
* This routine deals with paying your way out of jail.
*/
void
pay(void)
{
if (cur_p->loc != JAIL) {
printf("But you're not IN Jail\n");
return;
}
cur_p->loc = 10;
cur_p->money -= 50;
cur_p->in_jail = 0;
printf("That cost you $50\n");
}
/*
* This routine deals with a move in jail
*/
int
move_jail(int r1, int r2)
{
if (r1 != r2) {
printf("Sorry, that doesn't get you out\n");
if (++(cur_p->in_jail) == 3) {
printf("It's your third turn and you didn't roll "
"doubles. You have to pay $50\n");
cur_p->money -= 50;
moveit:
cur_p->loc = 10;
cur_p->in_jail = 0;
move(r1+r2);
r1 = r2 - 1; /* kludge: stop new roll w/doub */
return TRUE;
}
return FALSE;
} else {
printf("Double roll gets you out.\n");
goto moveit;
}
}
void
printturn(void)
{
if (cur_p->loc != JAIL)
return;
printf("(This is your ");
switch (cur_p->in_jail) {
case 0:
printf("1st");
break;
case 1:
printf("2nd");
break;
case 2:
printf("3rd (and final)");
break;
}
printf(" turn in JAIL)\n");
}

299
games/monop/misc.c Normal file
View File

@ -0,0 +1,299 @@
/* $NetBSD: misc.c,v 1.23 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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.23 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include <ctype.h>
#include <limits.h>
#include <signal.h>
#include <errno.h>
#include "monop.h"
static void is_monop(MON *, int);
/*
* This routine executes a truncated set of commands until a
* "yes or "no" answer is gotten.
*/
int
getyn(const char *prompt)
{
int com;
for (;;)
if ((com=getinp(prompt, yncoms)) < 2)
return com;
else
(*func[com-2])();
}
/*
* This routine tells the player if he's out of money.
*/
void
notify(void)
{
if (cur_p->money < 0)
printf("That leaves you $%d in debt\n", -cur_p->money);
else if (cur_p->money == 0)
printf("that leaves you broke\n");
else if (fixing && !told_em && cur_p->money > 0) {
printf("-- You are now Solvent ---\n");
told_em = TRUE;
}
}
/*
* This routine switches to the next player
*/
void
next_play(void)
{
player = (player + 1) % num_play;
cur_p = &play[player];
num_doub = 0;
}
/*
* This routine gets an integer from the keyboard after the
* given prompt.
*/
int
get_int(const char *prompt)
{
long num;
char *sp;
char buf[257];
for (;;) {
printf("%s", prompt);
fgets(buf, sizeof(buf), stdin);
/* if stdin is closed we cant really play anymore */
if (feof(stdin))
quit();
sp = strchr(buf, '\n');
if (sp)
*sp = '\0';
errno = 0;
num = strtol(buf, &sp, 10);
if (errno || strlen(sp) > 0 || num < 0 || num >= INT_MAX) {
printf("I can't understand that\n");
continue;
}
return num;
}
}
/*
* This routine sets the monopoly flag from the list given.
*/
void
set_ownlist(int pl)
{
int num; /* general counter */
MON *orig; /* remember starting monop ptr */
OWN *op; /* current owned prop */
OWN *orig_op; /* original prop before loop */
op = play[pl].own_list;
#ifdef DEBUG
printf("op [%p] = play[pl [%d] ].own_list;\n", op, pl);
#endif
while (op) {
#ifdef DEBUG
printf("op->sqr->type = %d\n", op->sqr->type);
#endif
switch (op->sqr->type) {
case UTIL:
#ifdef DEBUG
printf(" case UTIL:\n");
#endif
for (num = 0; op && op->sqr->type == UTIL;
op = op->next)
num++;
play[pl].num_util = num;
#ifdef DEBUG
printf("play[pl].num_util = num [%d];\n", num);
#endif
break;
case RR:
#ifdef DEBUG
printf(" case RR:\n");
#endif
for (num = 0; op && op->sqr->type == RR;
op = op->next) {
#ifdef DEBUG
printf("iter: %d\n", num);
printf("op = %p, op->sqr = %p, "
"op->sqr->type = %d\n", op, op->sqr,
op->sqr->type);
#endif
num++;
}
play[pl].num_rr = num;
#ifdef DEBUG
printf("play[pl].num_rr = num [%d];\n", num);
#endif
break;
case PRPTY:
#ifdef DEBUG
printf(" case PRPTY:\n");
#endif
orig = op->sqr->desc->mon_desc;
orig_op = op;
num = 0;
while (op && op->sqr->desc->mon_desc == orig) {
#ifdef DEBUG
printf("iter: %d\n", num);
#endif
num++;
#ifdef DEBUG
printf("op = op->next ");
#endif
op = op->next;
#ifdef DEBUG
printf("[%p];\n", op);
#endif
}
#ifdef DEBUG
printf("num = %d\n", num);
#endif
if (orig == NULL) {
printf("panic: bad monopoly descriptor: "
"orig = %p\n", orig);
printf("player # %d\n", pl+1);
printhold(pl);
printf("orig_op = %p\n", orig_op);
if (orig_op) {
printf("orig_op->sqr->type = %d (PRPTY)\n",
orig_op->sqr->type);
printf("orig_op->next = %p\n",
orig_op->next);
printf("orig_op->sqr->desc = %p\n",
orig_op->sqr->desc);
}
printf("op = %p\n", op);
if (op) {
printf("op->sqr->type = %d (PRPTY)\n",
op->sqr->type);
printf("op->next = %p\n", op->next);
printf("op->sqr->desc = %p\n",
op->sqr->desc);
}
printf("num = %d\n", num);
exit(1);
}
#ifdef DEBUG
printf("orig->num_in = %d\n", orig->num_in);
#endif
if (num == orig->num_in)
is_monop(orig, pl);
else
is_not_monop(orig);
break;
}
}
}
/*
* This routine sets things up as if it is a new monopoly
*/
static void
is_monop(MON *mp, int pl)
{
int i;
mp->owner = pl;
mp->num_own = mp->num_in;
for (i = 0; i < mp->num_in; i++)
mp->sq[i]->desc->monop = TRUE;
mp->name = mp->mon_n;
}
/*
* This routine sets things up as if it is no longer a monopoly
*/
void
is_not_monop(MON *mp)
{
int i;
mp->owner = -1;
for (i = 0; i < mp->num_in; i++)
mp->sq[i]->desc->monop = FALSE;
mp->name = mp->not_m;
}
/*
* This routine gives a list of the current player's routine
*/
void
list(void)
{
printhold(player);
}
/*
* This routine gives a list of a given players holdings
*/
void
list_all(void)
{
int pl;
while ((pl = getinp("Whose holdings do you want to see? ", name_list))
< num_play)
printhold(pl);
}
/*
* This routine gives the players a chance before it exits.
*/
void
quit(void)
{
putchar('\n');
/* We dont even have a chance to input y/n if stdin is closed */
if (feof(stdin))
exit(0);
if (getyn("Do you all really want to quit? ") == 0)
exit(0);
}

178
games/monop/monop.6 Normal file
View File

@ -0,0 +1,178 @@
.\" $NetBSD: monop.6,v 1.19 2008/02/24 03:50:07 dholland Exp $
.\"
.\" Copyright (c) 1980 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. 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.
.\"
.\" @(#)monop.6 6.5 (Berkeley) 3/25/93
.\"
.Dd February 23, 2008
.Dt MONOP 6
.Os
.Sh NAME
.Nm monop
.Nd Monopoly game
.Sh SYNOPSIS
.Nm
.Op Ar file
.Sh DESCRIPTION
.Nm
is reminiscent of the Parker Brother's game Monopoly, and
monitors a game between 2 to 9 users.
It is assumed that the rules of Monopoly are known.
The game follows the standard rules, with the exception that,
if a property goes up for auction and there are only two solvent players,
no auction is held and the property remains unowned.
.Pp
The game, in effect, lends the player money,
so it is possible to buy something which you cannot afford.
However, as soon as a person goes into debt, he must
.Dq fix the problem ,
i.e., make himself solvent, before play can continue.
If this is not possible, the player's property reverts to his debtee,
either a player or the bank.
A player can resign at any time to any person or the bank,
which puts the property back on the board, unowned.
.Pp
Any time that the response to a question is a
.Em string ,
e.g., a name, place or person, you can type
.Sq Ic \&?
to get a list of valid answers.
It is not possible to input a negative number, nor is it ever necessary.
.Pp
.Em A Summary of Commands :
.Bl -tag -width item
.It Ic quit
quit game: This allows you to quit the game.
It asks you if you're sure.
.It Ic print
print board: This prints out the current board.
The columns have the following meanings (column headings are the same for the
.Ic where ,
.Ic own holdings ,
and
.Ic holdings
commands):
.Pp
.Bl -tag -width indent -compact
.It Name
The first ten characters of the name of the square.
.It Own
The
.Em number
of the owner of the property.
.It Price
The cost of the property (if any).
.It Mg
This field has a
.Sq *
in it if the property is mortgaged.
.It \&#
If the property is a Utility or Railroad, this is the number
of such owned by the owner.
If the property is land, this is the number of houses on it.
.It Rent
Current rent on the property.
If it is not owned, there is no rent.
.El
.It Ic where
where players are: Tells you where all the players are.
A
.Sq *
indicates the current player.
.It Ic own holdings
List your own holdings,
i.e., money, get-out-of-jail-free cards, and property.
.It Ic holdings
holdings list: Look at anyone's holdings.
It will ask you whose holdings you wish to look at.
When you are finished, type
.Sq Ic done .
.It Ic mortgage
mortgage property:
Sets up a list of mortgageable property, and asks which you wish to mortgage.
.It Ic unmortgage
unmortgage property:
Unmortgage mortgaged property.
.It Ic buy
buy houses:
Sets up a list of monopolies on which you can buy houses.
If there is more than one, it asks you which you want to buy for.
It then asks you how many for each piece of property,
giving the current amount in parentheses after the property name.
If you build in an unbalanced manner
(a disparity of more than one house within the same monopoly),
it asks you to re-input things.
.It Ic sell
sell houses:
Sets up a list of monopolies from which you can sell houses.
It operates in an analogous manner to
.Ic buy .
.It Ic card
card for jail:
Use a get-out-of-jail-free card to get out of jail.
If you're not in jail, or you don't have one, it tells you so.
.It Ic pay
pay for jail:
Pay $50 to get out of jail, from whence you are put on Just Visiting.
Difficult to do if you're not there.
.It Ic trade
This allows you to trade with another player.
It asks you whom you wish to trade with,
and then asks you what each wishes to give up.
You can get a summary at the end, and, in all cases,
it asks for confirmation of the trade before doing it.
.It Ic resign
Resign to another player or the bank.
If you resign to the bank, all property reverts to its virgin state,
and get-out-of-jail-free cards revert to the deck.
.It Ic save
save game:
Save the current game in a file for later play.
You can continue play after saving,
either by adding the file in which you saved the game after the
.Nm
command, or by using the
.Ic restore
command (see below).
It will ask you which file you wish to save it in,
and, if the file exists, confirm that you wish to overwrite it.
.It Ic restore
restore game:
Read in a previously saved game from a file.
It leaves the file intact.
.It Ic roll
Roll the dice and move forward to your new location.
If you simply hit the
.Aq RETURN
key instead of a command, it is the same as typing
.Ic roll .
.El
.Sh AUTHORS
.An Ken Arnold
.Sh BUGS
No command can be given an argument instead of a response to a query.

360
games/monop/monop.c Normal file
View File

@ -0,0 +1,360 @@
/* $NetBSD: monop.c,v 1.27 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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) 1980, 1993\
The Regents of the University of California. All rights reserved.");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)monop.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: monop.c,v 1.27 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "deck.h"
#include "monop.h"
int main(int, char *[]);
static void getplayers(void);
static void init_players(void);
static void init_monops(void);
static void do_quit(int);
bool fixing, /* set if fixing up debt */
trading, /* set if in process of trading */
told_em, /* set if told user he's out of debt */
spec; /* set if moving by card to RR or UTIL */
const char *name_list[MAX_PL+2]; /* list of players' names */
static const char *const comlist[] = { /* list of normal commands */
"quit", /* 0 */ "print", /* 1 */
"where", /* 2 */ "own holdings", /* 3 */
"holdings", /* 4 */ "mortgage", /* 5 */
"unmortgage", /* 6 */ "buy houses", /* 7 */
"sell houses", /* 8 */ "card", /* 9 */
"pay", /* 10 */ "trade", /* 11 */
"resign", /* 12 */ "save", /* 13 */
"restore", /* 14 */ "roll", /* 15 */
"", /* 16 */
0
};
const char *const yncoms[] = { /* list of commands for yes/no answers */
"yes", /* 0 */ "no", /* 1 */
"quit", /* 2 */ "print", /* 3 */
"where", /* 4 */ "own holdings", /* 5 */
"holdings", /* 6 */
0
};
const char *const lucky_mes[] = { /* "got lucky" messages */
"You lucky stiff", "You got lucky",
"What a lucky person!", "You must have a 4-leaf clover",
"My, my! Aren't we lucky!", "Luck smiles upon you",
"You got lucky this time", "Lucky person!",
"Your karma must certainly be together",
"How beautifully Cosmic", "Wow, you must be really with it"
/* "I want your autograph", -- Save for later */
};
int player, /* current player number */
num_play, /* current number of players */
num_doub, /* # of doubles current player rolled */
/* # of "got lucky" messages */
num_luck = sizeof lucky_mes / sizeof (char *);
/* list of command functions */
void (*const func[])(void) = { /* array of function calls for commands */
quit, /* quit game |* 0 *| */
printboard, /* print board |* 1 *| */
where, /* where players are |* 2 *| */
list, /* own holdings |* 3 *| */
list_all, /* holdings list |* 4 *| */
mortgage, /* mortgage property |* 5 *| */
unmortgage, /* unmortgage property |* 6 *| */
buy_houses, /* buy houses |* 7 *| */
sell_houses, /* sell houses |* 8 *| */
card, /* card for jail |* 9 *| */
pay, /* pay for jail |* 10 *| */
trade, /* trade |* 11 *| */
resign, /* resign |* 12 *| */
save, /* save game |* 13 *| */
restore, /* restore game |* 14 *| */
do_move, /* roll |* 15 *| */
do_move /* "" |* 16 *| */
};
DECK deck[2]; /* Chance and Community Chest */
PLAY *play, /* player structure array ("calloc"ed) */
*cur_p; /* pointer to current player's struct */
static RR_S rr[N_RR]; /* railroad descriptions */
static UTIL_S util[2]; /* utility descriptions */
#define MONINIT(num_in, h_cost, not_m, mon_n, sq1,sq2,sq3) \
{0, -1, num_in, 0, h_cost, not_m, mon_n, {sq1,sq2,sq3}, {0,0,0}}
/* name owner num_own sq */
static MON mon[N_MON] = { /* monopoly descriptions */
/* num_in h_cost not_m mon_n sqnums */
MONINIT(2, 1, "Purple", "PURPLE", 1,3, 0),
MONINIT(3, 1, "Lt. Blue", "LT. BLUE", 6,8,9),
MONINIT(3, 2, "Violet", "VIOLET", 11,13,14),
MONINIT(3, 2, "Orange", "ORANGE", 16,18,19),
MONINIT(3, 3, "Red", "RED", 21,23,24),
MONINIT(3, 3, "Yellow", "YELLOW", 26,27,29),
MONINIT(3, 4, "Green", "GREEN", 31,32,34),
MONINIT(2, 4, "Dk. Blue", "DK. BLUE", 37,39, 0),
};
#undef MONINIT
PROP prop[N_PROP] = { /* typical properties */
/* morg monop square houses mon_desc rent */
{0, 0, 1, 0, &mon[0], { 2, 10, 30, 90, 160, 250} },
{0, 0, 3, 0, &mon[0], { 4, 20, 60, 180, 320, 450} },
{0, 0, 6, 0, &mon[1], { 6, 30, 90, 270, 400, 550} },
{0, 0, 7, 0, &mon[1], { 6, 30, 90, 270, 400, 550} },
{0, 0, 9, 0, &mon[1], { 8, 40,100, 300, 450, 600} },
{0, 0, 11, 0, &mon[2], {10, 50,150, 450, 625, 750} },
{0, 0, 13, 0, &mon[2], {10, 50,150, 450, 625, 750} },
{0, 0, 14, 0, &mon[2], {12, 60,180, 500, 700, 900} },
{0, 0, 16, 0, &mon[3], {14, 70,200, 550, 750, 950} },
{0, 0, 17, 0, &mon[3], {14, 70,200, 550, 750, 950} },
{0, 0, 19, 0, &mon[3], {16, 80,220, 600, 800,1000} },
{0, 0, 21, 0, &mon[4], {18, 90,250, 700, 875,1050} },
{0, 0, 23, 0, &mon[4], {18, 90,250, 700, 875,1050} },
{0, 0, 24, 0, &mon[4], {20,100,300, 750, 925,1100} },
{0, 0, 26, 0, &mon[5], {22,110,330, 800, 975,1150} },
{0, 0, 27, 0, &mon[5], {22,110,330, 800, 975,1150} },
{0, 0, 29, 0, &mon[5], {24,120,360, 850,1025,1200} },
{0, 0, 31, 0, &mon[6], {26,130,390, 900,1100,1275} },
{0, 0, 32, 0, &mon[6], {26,130,390, 900,1100,1275} },
{0, 0, 34, 0, &mon[6], {28,150,450,1000,1200,1400} },
{0, 0, 37, 0, &mon[7], {35,175,500,1100,1300,1500} },
{0, 0, 39, 0, &mon[7], {50,200,600,1400,1700,2000} }
};
SQUARE board[N_SQRS+1] = { /* board itself (+1 for Jail) */
/* name (COLOR) owner type desc cost */
{"=== GO ===", -1, SAFE, NULL, 0 },
{"Mediterranean Ave. (P)", -1, PRPTY, &prop[0], 60 },
{"Community Chest i", -1, CC, NULL, 0 },
{"Baltic Ave. (P)", -1, PRPTY, &prop[1], 60 },
{"Income Tax", -1, INC_TAX, NULL, 0 },
{"Reading RR", -1, RR, &rr[0], 200 },
{"Oriental Ave. (L)", -1, PRPTY, &prop[2], 100 },
{"Chance i", -1, CHANCE, NULL, 0 },
{"Vermont Ave. (L)", -1, PRPTY, &prop[3], 100 },
{"Connecticut Ave. (L)", -1, PRPTY, &prop[4], 120 },
{"Just Visiting", -1, SAFE, NULL, 0 },
{"St. Charles Pl. (V)", -1, PRPTY, &prop[5], 140 },
{"Electric Co.", -1, UTIL, &util[0], 150 },
{"States Ave. (V)", -1, PRPTY, &prop[6], 140 },
{"Virginia Ave. (V)", -1, PRPTY, &prop[7], 160 },
{"Pennsylvania RR", -1, RR, &rr[1], 200 },
{"St. James Pl. (O)", -1, PRPTY, &prop[8], 180 },
{"Community Chest ii", -1, CC, NULL, 0 },
{"Tennessee Ave. (O)", -1, PRPTY, &prop[9], 180 },
{"New York Ave. (O)", -1, PRPTY, &prop[10], 200 },
{"Free Parking", -1, SAFE, NULL, 0 },
{"Kentucky Ave. (R)", -1, PRPTY, &prop[11], 220 },
{"Chance ii", -1, CHANCE, NULL, 0 },
{"Indiana Ave. (R)", -1, PRPTY, &prop[12], 220 },
{"Illinois Ave. (R)", -1, PRPTY, &prop[13], 240 },
{"B&O RR", -1, RR, &rr[2], 200 },
{"Atlantic Ave. (Y)", -1, PRPTY, &prop[14], 260 },
{"Ventnor Ave. (Y)", -1, PRPTY, &prop[15], 260 },
{"Water Works", -1, UTIL, &util[1], 150 },
{"Marvin Gardens (Y)", -1, PRPTY, &prop[16], 280 },
{"GO TO JAIL", -1, GOTO_J, NULL, 0 },
{"Pacific Ave. (G)", -1, PRPTY, &prop[17], 300 },
{"N. Carolina Ave. (G)", -1, PRPTY, &prop[18], 300 },
{"Community Chest iii", -1, CC, NULL, 0 },
{"Pennsylvania Ave. (G)", -1, PRPTY, &prop[19], 320 },
{"Short Line RR", -1, RR, &rr[3], 200 },
{"Chance iii", -1, CHANCE, NULL, 0 },
{"Park Place (D)", -1, PRPTY, &prop[20], 350 },
{"Luxury Tax", -1, LUX_TAX, NULL, 0 },
{"Boardwalk (D)", -1, PRPTY, &prop[21], 400 },
{"JAIL", -1, IN_JAIL, NULL, 0 }
};
/*
* This program implements a monopoly game
*/
int
main(int ac, char *av[])
{
/* Revoke setgid privileges */
setgid(getgid());
srandom((unsigned long)time(NULL));
num_luck = sizeof lucky_mes / sizeof (char *);
init_decks();
init_monops();
if (ac > 1) {
if (rest_f(av[1]) < 0)
restore();
}
else {
getplayers();
init_players();
}
signal(SIGINT, do_quit);
for (;;) {
printf("\n%s (%d) (cash $%d) on %s\n", cur_p->name, player + 1,
cur_p->money, board[cur_p->loc].name);
printturn();
force_morg();
execute(getinp("-- Command: ", comlist));
}
}
/*ARGSUSED*/
static void
do_quit(int n __unused)
{
quit();
}
/*
* This routine gets the names of the players
*/
static void
getplayers(void)
{
int i, j;
char buf[257];
blew_it:
for (;;) {
if ((num_play = get_int("How many players? ")) <= 1 ||
num_play > MAX_PL)
printf("Sorry. Number must range from 2 to %d\n",
MAX_PL);
else
break;
}
cur_p = play = calloc((size_t)num_play, sizeof (PLAY));
if (play == NULL)
err(1, NULL);
for (i = 0; i < num_play; i++) {
do {
printf("Player %d's name: ", i + 1);
fgets(buf, sizeof(buf), stdin);
if (feof(stdin)) {
quit();
}
buf[strcspn(buf, "\n")] = '\0';
} while (strlen(buf) == 0);
name_list[i] = play[i].name = strdup(buf);
if (name_list[i] == NULL)
err(1, NULL);
play[i].money = 1500;
}
name_list[i++] = "done";
name_list[i] = 0;
for (i = 0; i < num_play; i++)
for (j = i + 1; j <= num_play; j++)
if (strcasecmp(name_list[i], name_list[j]) == 0) {
if (j != num_play)
printf("Hey!!! Some of those are "
"IDENTICAL!! Let's try that "
"again...\n");
else
printf("\"done\" is a reserved word. "
"Please try again\n");
for (i = 0; i < num_play; i++)
free(play[i].name);
free(play);
goto blew_it;
}
}
/*
* This routine figures out who goes first
*/
static void
init_players(void)
{
int i, rl, cur_max;
bool over = 0;
int max_pl = 0;
again:
putchar('\n');
for (cur_max = i = 0; i < num_play; i++) {
printf("%s (%d) rolls %d\n", play[i].name, i+1, rl=roll(2, 6));
if (rl > cur_max) {
over = FALSE;
cur_max = rl;
max_pl = i;
}
else if (rl == cur_max)
over++;
}
if (over) {
printf("%d people rolled the same thing, so we'll try again\n",
over + 1);
goto again;
}
player = max_pl;
cur_p = &play[max_pl];
printf("%s (%d) goes first\n", cur_p->name, max_pl + 1);
}
/*
* This routine initializes the monopoly structures.
*/
static void
init_monops(void)
{
MON *mp;
int i;
for (mp = mon; mp < &mon[N_MON]; mp++) {
mp->name = mp->not_m;
for (i = 0; i < mp->num_in; i++)
mp->sq[i] = &board[mp->sqnums[i]];
}
}

221
games/monop/monop.h Normal file
View File

@ -0,0 +1,221 @@
/* $NetBSD: monop.h,v 1.19 2009/08/12 08:10:49 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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.
*
* @(#)monop.h 8.1 (Berkeley) 5/31/93
*/
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define bool char
#define TRUE (1)
#define FALSE (0)
#define N_MON 8 /* number of monopolies */
#define N_PROP 22 /* number of normal property squares */
#define N_RR 4 /* number of railroads */
#define N_UTIL 2 /* number of utilities */
#define N_SQRS 40 /* number of squares on board */
#define MAX_PL 9 /* maximum number of players */
#define MAX_PRP (N_PROP+N_RR+N_UTIL) /* max # ownable property */
#define N_HOUSE 32 /* total number of houses available */
#define N_HOTEL 12 /* total number of hotels available */
/* square type numbers */
#define PRPTY 0 /* normal property */
#define RR 1 /* railroad */
#define UTIL 2 /* water works - electric co */
#define SAFE 3 /* safe spot */
#define CC 4 /* community chest */
#define CHANCE 5 /* chance (surprise!!!) */
#define INC_TAX 6 /* Income tax */
#define GOTO_J 7 /* Go To Jail! */
#define LUX_TAX 8 /* Luxury tax */
#define IN_JAIL 9 /* In jail */
#define JAIL 40 /* JAIL square number */
#define lucky(str) printf("%s%s\n",str,lucky_mes[roll(1,num_luck)-1])
#define printline() printf("------------------------------\n")
#define sqnum(sqp) ((short)(sqp - board))
struct sqr_st { /* structure for square */
const char *name; /* place name */
short owner; /* owner number */
short type; /* place type */
struct prp_st *desc; /* description struct */
int cost; /* cost */
};
typedef struct sqr_st SQUARE;
struct mon_st { /* monopoly description structure */
const char *name; /* monop. name (color) */
short owner; /* owner of monopoly */
short num_in; /* # in monopoly */
short num_own; /* # owned (-1: not poss. monop)*/
short h_cost; /* price of houses */
const char *not_m; /* name if not monopoly */
const char *mon_n; /* name if a monopoly */
unsigned char sqnums[3]; /* Square numbers (used to init)*/
SQUARE *sq[3]; /* list of squares in monop */
};
typedef struct mon_st MON;
/*
* This struct describes a property. For railroads and utilities, only
* the "morg" member is used.
*/
struct prp_st { /* property description structure */
bool morg; /* set if mortgaged */
bool monop; /* set if monopoly */
short square; /* square description */
short houses; /* number of houses */
MON *mon_desc; /* name of color */
int rent[6]; /* rents */
};
struct own_st { /* element in list owned things */
SQUARE *sqr; /* pointer to square */
struct own_st *next; /* next in list */
};
typedef struct own_st OWN;
struct plr_st { /* player description structure */
char *name; /* owner name */
short num_gojf; /* # of get-out-of-jail-free's */
short num_rr; /* # of railroads owned */
short num_util; /* # of water works/elec. co. */
short loc; /* location on board */
short in_jail; /* count of turns in jail */
int money; /* amount of money */
OWN *own_list; /* start of property list */
};
typedef struct plr_st PLAY;
typedef struct prp_st PROP;
typedef struct prp_st RR_S;
typedef struct prp_st UTIL_S;
extern bool trading, spec, fixing, told_em;
extern const char *const yncoms[], *name_list[], *const lucky_mes[];
extern int num_play, player, num_doub, num_luck;
extern void (*const func[])(void);
/*extern MON mon[N_MON];*/
extern PLAY *play, *cur_p;
extern PROP prop[N_PROP];
/*extern RR_S rr[N_RR];*/
extern SQUARE board[N_SQRS + 1];
/*extern UTIL_S util[2];*/
/* cards.c */
void ret_card(PLAY *);
/* execute.c */
void execute(int);
void do_move(void);
void move(int);
void save(void);
void restore(void);
int rest_f(const char *);
/* getinp.c */
int getinp(const char *, const char *const []);
/* houses.c */
void buy_houses(void);
void sell_houses(void);
/* jail.c */
void card(void);
void pay(void);
int move_jail(int, int );
void printturn(void);
/* misc.c */
int getyn(const char *);
void notify(void);
void next_play(void);
int get_int(const char *);
void set_ownlist(int);
void is_not_monop(MON *);
void list(void);
void list_all(void);
void quit(void);
/* morg.c */
void mortgage(void);
void unmortgage(void);
void force_morg(void);
/* print.c */
void printboard(void);
void where(void);
void printsq(int, bool);
void printhold(int);
/* prop.c */
void buy(int, SQUARE *);
void add_list(int, OWN **, int);
void del_list(int, OWN **, short);
void bid(void);
int prop_worth(PLAY *);
/* rent.c */
void rent(SQUARE *);
/* roll.c */
int roll(int, int);
/* spec.c */
void inc_tax(void);
void goto_jail(void);
void lux_tax(void);
void cc(void);
void chance(void);
/* trade.c */
void trade(void);
void resign(void);

229
games/monop/morg.c Normal file
View File

@ -0,0 +1,229 @@
/* $NetBSD: morg.c,v 1.19 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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[] = "@(#)morg.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: morg.c,v 1.19 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include "monop.h"
/*
* These routines deal with mortgaging.
*/
static const char *names[MAX_PRP+2],
*const morg_coms[] = {
"quit", /* 0 */
"print", /* 1 */
"where", /* 2 */
"own holdings", /* 3 */
"holdings", /* 4 */
"mortgage", /* 5 */
"unmortgage", /* 6 */
"buy", /* 7 */
"sell", /* 8 */
"card", /* 9 */
"pay", /* 10 */
"trade", /* 11 */
"resign", /* 12 */
"save game", /* 13 */
"restore game", /* 14 */
0
};
static short square[MAX_PRP+2];
static int num_good, got_houses;
static int set_mlist(void);
static void m(int);
static int set_umlist(void);
static void unm(int);
/*
* This routine is the command level response the mortgage command.
* it gets the list of mortgageable property and asks which are to
* be mortgaged.
*/
void
mortgage(void)
{
int propnum;
for (;;) {
if (set_mlist() == 0) {
if (got_houses)
printf("You can't mortgage property with "
"houses on it.\n");
else
printf("You don't have any un-mortgaged "
"property.\n");
return;
}
if (num_good == 1) {
printf("Your only mortgageable property is %s\n",
names[0]);
if (getyn("Do you want to mortgage it? ") == 0)
m(square[0]);
return;
}
propnum = getinp("Which property do you want to mortgage? ",
names);
if (propnum == num_good)
return;
m(square[propnum]);
notify();
}
}
/*
* This routine sets up the list of mortgageable property
*/
static int
set_mlist(void)
{
OWN *op;
num_good = 0;
for (op = cur_p->own_list; op; op = op->next)
if (!op->sqr->desc->morg) {
if (op->sqr->type == PRPTY && op->sqr->desc->houses)
got_houses++;
else {
names[num_good] = op->sqr->name;
square[num_good++] = sqnum(op->sqr);
}
}
names[num_good++] = "done";
names[num_good--] = 0;
return num_good;
}
/*
* This routine actually mortgages the property.
*/
static void
m(int propnum)
{
int price;
price = board[propnum].cost/2;
board[propnum].desc->morg = TRUE;
printf("That got you $%d\n",price);
cur_p->money += price;
}
/*
* This routine is the command level repsponse to the unmortgage
* command. It gets the list of mortgaged property and asks which are
* to be unmortgaged.
*/
void
unmortgage(void)
{
int propnum;
for (;;) {
if (set_umlist() == 0) {
printf("You don't have any mortgaged property.\n");
return;
}
if (num_good == 1) {
printf("Your only mortgaged property is %s\n",
names[0]);
if (getyn("Do you want to unmortgage it? ") == 0)
unm(square[0]);
return;
}
propnum = getinp("Which property do you want to unmortgage? ",
names);
if (propnum == num_good)
return;
unm(square[propnum]);
}
}
/*
* This routine sets up the list of mortgaged property
*/
static int
set_umlist(void)
{
OWN *op;
num_good = 0;
for (op = cur_p->own_list; op; op = op->next)
if (op->sqr->desc->morg) {
names[num_good] = op->sqr->name;
square[num_good++] = sqnum(op->sqr);
}
names[num_good++] = "done";
names[num_good--] = 0;
return num_good;
}
/*
* This routine actually unmortgages the property
*/
static void
unm(int propnum)
{
int price;
price = board[propnum].cost/2;
board[propnum].desc->morg = FALSE;
price += price/10;
printf("That cost you $%d\n",price);
cur_p->money -= price;
(void)set_umlist();
}
/*
* This routine forces the indebted player to fix his
* financial woes. It is fine to have $0 but not to be in debt.
*/
void
force_morg(void)
{
told_em = fixing = TRUE;
while (cur_p->money < 0) {
told_em = FALSE;
(*func[(getinp("How are you going to fix it up? ", morg_coms))])();
notify();
}
fixing = FALSE;
}

197
games/monop/print.c Normal file
View File

@ -0,0 +1,197 @@
/* $NetBSD: print.c,v 1.13 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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.13 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include "monop.h"
static const char *header = "Name Own Price Mg # Rent";
static void printmorg(const SQUARE *);
/*
* This routine prints out the current board
*/
void
printboard(void)
{
int i;
printf("%s\t%s\n", header, header);
for (i = 0; i < N_SQRS/2; i++) {
printsq(i, FALSE);
putchar('\t');
printsq(i+N_SQRS/2, TRUE);
}
}
/*
* This routine lists where each player is.
*/
void
where(void)
{
int i;
printf("%s Player\n", header);
for (i = 0; i < num_play; i++) {
printsq(play[i].loc, FALSE);
printf(" %s (%d)", play[i].name, i+1);
if (cur_p == &play[i])
printf(" *");
putchar('\n');
}
}
/*
* This routine prints out an individual square
*/
void
printsq(int sqn, bool eoln)
{
int rnt;
PROP *pp;
SQUARE *sqp;
sqp = &board[sqn];
printf("%-10.10s", sqp->name);
switch (sqp->type) {
case SAFE:
case CC:
case CHANCE:
case INC_TAX:
case GOTO_J:
case LUX_TAX:
case IN_JAIL:
if (!eoln)
printf(" ");
break;
case PRPTY:
pp = sqp->desc;
if (sqp->owner < 0) {
printf(" - %-8.8s %3d", pp->mon_desc->name, sqp->cost);
if (!eoln)
printf(" ");
break;
}
printf(" %d %-8.8s %3d", sqp->owner+1, pp->mon_desc->name,
sqp->cost);
printmorg(sqp);
if (pp->monop) {
if (pp->houses < 5)
if (pp->houses > 0)
printf("%d %4d", pp->houses,
pp->rent[pp->houses]);
else
printf("0 %4d", pp->rent[0] * 2);
else
printf("H %4d", pp->rent[5]);
} else
printf(" %4d", pp->rent[0]);
break;
case UTIL:
if (sqp->owner < 0) {
printf(" - 150");
if (!eoln)
printf(" ");
break;
}
printf(" %d 150", sqp->owner+1);
printmorg(sqp);
printf("%d", play[sqp->owner].num_util);
if (!eoln)
printf(" ");
break;
case RR:
if (sqp->owner < 0) {
printf(" - Railroad 200");
if (!eoln)
printf(" ");
break;
}
printf(" %d Railroad 200", sqp->owner+1);
printmorg(sqp);
rnt = 25;
rnt <<= play[sqp->owner].num_rr - 1;
printf("%d %4d", play[sqp->owner].num_rr,
25 << (play[sqp->owner].num_rr - 1));
break;
}
if (eoln)
putchar('\n');
}
/*
* This routine prints out the mortgage flag.
*/
static void
printmorg(const SQUARE *sqp)
{
if (sqp->desc->morg)
printf(" * ");
else
printf(" ");
}
/*
* This routine lists the holdings of the player given
*/
void
printhold(int pl)
{
OWN *op;
PLAY *pp;
pp = &play[pl];
printf("%s's (%d) holdings (Total worth: $%d):\n", name_list[pl],
pl + 1, pp->money + prop_worth(pp));
printf("\t$%d", pp->money);
if (pp->num_gojf) {
printf(", %d get-out-of-jail-free card", pp->num_gojf);
if (pp->num_gojf > 1)
putchar('s');
}
putchar('\n');
if (pp->own_list) {
printf("\t%s\n", header);
for (op = pp->own_list; op; op = op->next) {
putchar('\t');
printsq(sqnum(op->sqr), TRUE);
}
}
}

224
games/monop/prop.c Normal file
View File

@ -0,0 +1,224 @@
/* $NetBSD: prop.c,v 1.20 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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[] = "@(#)prop.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: prop.c,v 1.20 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include <stdlib.h>
#include "monop.h"
static int value(SQUARE *);
/*
* This routine deals with buying property, setting all the
* appropriate flags.
*/
void
buy(int playernum, SQUARE *sqrp)
{
trading = FALSE;
sqrp->owner = playernum;
add_list(playernum, &(play[playernum].own_list), cur_p->loc);
}
/*
* This routine adds an item to the list.
*/
void
add_list(int plr, OWN **head, int op_sqr)
{
int val;
OWN *tp, *last_tp;
OWN *op;
op = calloc(1, sizeof (OWN));
if (op == NULL)
errx(1, "out of memory");
op->sqr = &board[op_sqr];
val = value(op->sqr);
last_tp = NULL;
for (tp = *head; tp && value(tp->sqr) < val; tp = tp->next)
if (val == value(tp->sqr)) {
free(op);
return;
}
else
last_tp = tp;
op->next = tp;
if (last_tp != NULL)
last_tp->next = op;
else
*head = op;
if (!trading)
set_ownlist(plr);
}
/*
* This routine deletes property from the list.
*/
void
del_list(int plr, OWN **head, short op_sqr)
{
OWN *op, *last_op;
switch (board[op_sqr].type) {
case PRPTY:
board[op_sqr].desc->mon_desc->num_own--;
break;
case RR:
play[plr].num_rr--;
break;
case UTIL:
play[plr].num_util--;
break;
}
last_op = NULL;
for (op = *head; op; op = op->next)
if (op->sqr == &board[op_sqr])
break;
else
last_op = op;
if (op == NULL)
return;
if (last_op == NULL)
*head = op->next;
else {
last_op->next = op->next;
free(op);
}
}
/*
* This routine calculates the value for sorting of the
* given square.
*/
static int
value(SQUARE *sqp)
{
int sqr;
sqr = sqnum(sqp);
switch (sqp->type) {
case SAFE:
return 0;
default: /* Specials, etc */
return 1;
case UTIL:
if (sqr == 12)
return 2;
else
return 3;
case RR:
return 4 + sqr/10;
case PRPTY:
return 8 + (sqp->desc) - prop;
}
}
/*
* This routine accepts bids for the current piece of property.
*/
void
bid(void)
{
static bool in[MAX_PL];
int i, num_in, cur_max;
char buf[257];
int cur_bid;
printf("\nSo it goes up for auction. Type your bid after your name\n");
for (i = 0; i < num_play; i++)
in[i] = TRUE;
i = -1;
cur_max = 0;
num_in = num_play;
while (num_in > 1 || (cur_max == 0 && num_in > 0)) {
i = (i + 1) % num_play;
if (in[i]) {
do {
(void)snprintf(buf, sizeof(buf), "%s: ",
name_list[i]);
cur_bid = get_int(buf);
if (cur_bid == 0) {
in[i] = FALSE;
if (--num_in == 0)
break;
} else if (cur_bid <= cur_max) {
printf("You must bid higher than %d "
"to stay in\n", cur_max);
printf("(bid of 0 drops you out)\n");
} else if (cur_bid > play[i].money) {
printf("You can't bid more than your cash ($%d)\n",
play[i].money);
cur_bid = -1;
}
} while (cur_bid != 0 && cur_bid <= cur_max);
cur_max = (cur_bid ? cur_bid : cur_max);
}
}
if (cur_max != 0) {
while (!in[i])
i = (i + 1) % num_play;
printf("It goes to %s (%d) for $%d\n",play[i].name,i+1,cur_max);
buy(i, &board[cur_p->loc]);
play[i].money -= cur_max;
}
else
printf("Nobody seems to want it, so we'll leave it for "
"later\n");
}
/*
* This routine calculates the value of the property
* of given player.
*/
int
prop_worth(PLAY *plp)
{
OWN *op;
int worth;
worth = 0;
for (op = plp->own_list; op; op = op->next) {
if (op->sqr->type == PRPTY && op->sqr->desc->monop)
worth += op->sqr->desc->mon_desc->h_cost * 50 *
op->sqr->desc->houses;
worth += op->sqr->cost;
}
return worth;
}

96
games/monop/rent.c Normal file
View File

@ -0,0 +1,96 @@
/* $NetBSD: rent.c,v 1.9 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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[] = "@(#)rent.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: rent.c,v 1.9 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include "monop.h"
/*
* This routine has the player pay rent
*/
void
rent(SQUARE *sqp)
{
int rnt = 0;
PROP *pp;
PLAY *plp;
plp = &play[sqp->owner];
printf("Owned by %s\n", plp->name);
if (sqp->desc->morg) {
lucky("The thing is mortgaged. ");
return;
}
switch (sqp->type) {
case PRPTY:
pp = sqp->desc;
if (pp->monop)
if (pp->houses == 0)
printf("rent is %d\n", rnt=pp->rent[0] * 2);
else if (pp->houses < 5)
printf("with %d house%s, rent is %d\n",
pp->houses, pp->houses == 1 ? "" : "s",
rnt=pp->rent[pp->houses]);
else
printf("with a hotel, rent is %d\n",
rnt=pp->rent[pp->houses]);
else
printf("rent is %d\n", rnt = pp->rent[0]);
break;
case RR:
rnt = 25;
rnt <<= (plp->num_rr - 1);
if (spec)
rnt <<= 1;
printf("rent is %d\n", rnt);
break;
case UTIL:
rnt = roll(2, 6);
if (plp->num_util == 2 || spec) {
printf("rent is 10 * roll (%d) = %d\n", rnt, rnt * 10);
rnt *= 10;
}
else {
printf("rent is 4 * roll (%d) = %d\n", rnt, rnt * 4);
rnt *= 4;
}
break;
}
cur_p->money -= rnt;
plp->money += rnt;
}

58
games/monop/roll.c Normal file
View File

@ -0,0 +1,58 @@
/* $NetBSD: roll.c,v 1.14 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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.14 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include <stdlib.h>
#include "monop.h"
/*
* This routine rolls ndie nside-sided dice.
*/
int
roll(int ndie, int nsides)
{
long tot;
tot = 0;
while (ndie--)
tot += (random() % nsides) + 1;
return (int)tot;
}

115
games/monop/spec.c Normal file
View File

@ -0,0 +1,115 @@
/* $NetBSD: spec.c,v 1.11 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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[] = "@(#)spec.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: spec.c,v 1.11 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include "monop.h"
#include "deck.h"
static const char *const perc[] = {
"10%", "ten percent", "%", "$200", "200", 0
};
/*
* collect income tax
*/
void
inc_tax(void)
{
int worth, com_num;
com_num = getinp("Do you wish to lose 10% of your total worth or "
"$200? ", perc);
worth = cur_p->money + prop_worth(cur_p);
printf("You were worth $%d", worth);
worth /= 10;
if (com_num > 2) {
if (worth < 200)
printf(". Good try, but not quite.\n");
else if (worth > 200)
lucky(".\nGood guess. ");
cur_p->money -= 200;
}
else {
printf(", so you pay $%d", worth);
if (worth > 200)
printf(" OUCH!!!!.\n");
else if (worth < 200)
lucky("\nGood guess. ");
cur_p->money -= worth;
}
if (worth == 200)
lucky("\nIt makes no difference! ");
}
/*
* move player to jail
*/
void
goto_jail(void)
{
cur_p->loc = JAIL;
}
/*
* landing on luxury tax
*/
void
lux_tax(void)
{
printf("You lose $75\n");
cur_p->money -= 75;
}
/*
* draw community chest card
*/
void
cc(void)
{
get_card(&CC_D);
}
/*
* draw chance card
*/
void
chance(void)
{
get_card(&CH_D);
}

329
games/monop/trade.c Normal file
View File

@ -0,0 +1,329 @@
/* $NetBSD: trade.c,v 1.16 2012/06/19 05:35:32 dholland Exp $ */
/*
* Copyright (c) 1980, 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. 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[] = "@(#)trade.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: trade.c,v 1.16 2012/06/19 05:35:32 dholland Exp $");
#endif
#endif /* not lint */
#include "monop.h"
struct trd_st { /* how much to give to other player */
int trader; /* trader number */
int cash; /* amount of cash */
int gojf; /* # get-out-of-jail-free cards */
OWN *prop_list; /* property list */
};
typedef struct trd_st TRADE;
static const char *plist[MAX_PRP+2];
static int used[MAX_PRP];
static TRADE trades[2];
static void get_list(int, int );
static int set_list(OWN *);
static void summate(void);
static void do_trade(void);
static void move_em(TRADE *, TRADE *);
void
trade(void)
{
int tradee, i;
trading = TRUE;
for (i = 0; i < 2; i++) {
trades[i].cash = 0;
trades[i].gojf = FALSE;
trades[i].prop_list = NULL;
}
over:
if (num_play == 1) {
printf("There ain't no-one around to trade WITH!!\n");
return;
}
if (num_play > 2) {
tradee = getinp("Which player do you wish to trade with? ",
name_list);
if (tradee == num_play)
return;
if (tradee == player) {
printf("You can't trade with yourself!\n");
goto over;
}
}
else
tradee = 1 - player;
get_list(0, player);
get_list(1, tradee);
if (getyn("Do you wish a summary? ") == 0)
summate();
if (getyn("Is the trade ok? ") == 0)
do_trade();
}
/*
* This routine gets the list of things to be trader for the
* player, and puts in the structure given.
*/
static void
get_list(int struct_no, int play_no)
{
int sn, pn;
PLAY *pp;
int numin, propnum, num_prp;
OWN *op;
TRADE *tp;
for (numin = 0; numin < MAX_PRP; numin++)
used[numin] = FALSE;
sn = struct_no, pn = play_no;
pp = &play[pn];
tp = &trades[sn];
tp->trader = pn;
printf("player %s (%d):\n", pp->name, pn+1);
if (pp->own_list) {
numin = set_list(pp->own_list);
for (num_prp = numin; num_prp; ) {
propnum=getinp("Which property do you wish to trade? ",
plist);
if (propnum == numin)
break;
else if (used[propnum])
printf("You've already allocated that.\n");
else {
num_prp--;
used[propnum] = TRUE;
for (op = pp->own_list; propnum--; op = op->next)
continue;
add_list(pn, &(tp->prop_list), sqnum(op->sqr));
}
}
}
if (pp->money > 0) {
printf("You have $%d. ", pp->money);
tp->cash = get_int("How much are you trading? ");
}
if (pp->num_gojf > 0) {
once_more:
printf("You have %d get-out-of-jail-free cards. ",pp->num_gojf);
tp->gojf = get_int("How many are you trading? ");
if (tp->gojf > pp->num_gojf) {
printf("You don't have that many. Try again.\n");
goto once_more;
}
}
}
/*
* This routine sets up the list of tradable property.
*/
static int
set_list(OWN *the_list)
{
int i;
OWN *op;
i = 0;
for (op = the_list; op; op = op->next)
if (!used[i])
plist[i++] = op->sqr->name;
plist[i++] = "done";
plist[i--] = 0;
return i;
}
/*
* This routine summates the trade.
*/
static void
summate(void)
{
bool some;
int i;
TRADE *tp;
OWN *op;
for (i = 0; i < 2; i++) {
tp = &trades[i];
some = FALSE;
printf("Player %s (%d) gives:\n", play[tp->trader].name,
tp->trader+1);
if (tp->cash > 0)
printf("\t$%d\n", tp->cash), some++;
if (tp->gojf > 0)
printf("\t%d get-out-of-jail-free card(s)\n", tp->gojf),
some++;
if (tp->prop_list) {
for (op = tp->prop_list; op; op = op->next)
putchar('\t'), printsq(sqnum(op->sqr), TRUE);
some++;
}
if (!some)
printf("\t-- Nothing --\n");
}
}
/*
* This routine actually executes the trade.
*/
static void
do_trade(void)
{
move_em(&trades[0], &trades[1]);
move_em(&trades[1], &trades[0]);
}
/*
* This routine does a switch from one player to another
*/
static void
move_em(TRADE *from, TRADE *to)
{
PLAY *pl_fr, *pl_to;
OWN *op;
pl_fr = &play[from->trader];
pl_to = &play[to->trader];
pl_fr->money -= from->cash;
pl_to->money += from->cash;
pl_fr->num_gojf -= from->gojf;
pl_to->num_gojf += from->gojf;
for (op = from->prop_list; op; op = op->next) {
add_list(to->trader, &(pl_to->own_list), sqnum(op->sqr));
op->sqr->owner = to->trader;
del_list(from->trader, &(pl_fr->own_list), sqnum(op->sqr));
}
set_ownlist(to->trader);
}
/*
* This routine lets a player resign
*/
void
resign(void)
{
int i, new_own;
OWN *op;
SQUARE *sqp;
if (cur_p->money <= 0) {
switch (board[cur_p->loc].type) {
case UTIL:
case RR:
case PRPTY:
new_own = board[cur_p->loc].owner;
/* If you ran out of money by buying current location */
if (new_own == player)
new_own = num_play;
break;
default: /* Chance, taxes, etc */
new_own = num_play;
break;
}
if (new_own == num_play)
printf("You would resign to the bank\n");
else
printf("You would resign to %s\n", name_list[new_own]);
}
else if (num_play == 1) {
new_own = num_play;
printf("You would resign to the bank\n");
}
else {
name_list[num_play] = "bank";
do {
new_own = getinp("Who do you wish to resign to? ",
name_list);
if (new_own == player)
printf("You can't resign to yourself!!\n");
} while (new_own == player);
name_list[num_play] = "done";
}
if (getyn("Do you really want to resign? ") != 0)
return;
if (num_play == 1) {
printf("Then NOBODY wins (not even YOU!)\n");
exit(0);
}
if (new_own < num_play) { /* resign to player */
printf("resigning to player\n");
trades[0].trader = new_own;
trades[0].cash = trades[0].gojf = 0;
trades[0].prop_list = NULL;
trades[1].trader = player;
trades[1].cash = cur_p->money > 0 ? cur_p->money : 0;
trades[1].gojf = cur_p->num_gojf;
trades[1].prop_list = cur_p->own_list;
do_trade();
}
else { /* resign to bank */
printf("resigning to bank\n");
for (op = cur_p->own_list; op; op = op->next) {
sqp = op->sqr;
sqp->owner = -1;
sqp->desc->morg = FALSE;
if (sqp->type == PRPTY) {
is_not_monop(sqp->desc->mon_desc);
sqp->desc->houses = 0;
}
}
if (cur_p->num_gojf)
ret_card(cur_p);
}
free(play[player].name);
for (i = player; i < num_play; i++) {
name_list[i] = name_list[i+1];
if (i + 1 < num_play)
play[i] = play[i+1];
}
name_list[num_play--] = NULL;
for (i = 0; i < N_SQRS; i++)
if (board[i].owner > player)
--board[i].owner;
player = player == 0 ? num_play - 1 : player - 1;
next_play();
if (num_play < 2) {
printf("\nThen %s WINS!!!!!\n", play[0].name);
printhold(0);
printf("That's a grand worth of $%d.\n",
play[0].money+prop_worth(&play[0]));
exit(0);
}
}

View File

@ -74,6 +74,7 @@
2013/12/1 12:00:00,games/fortune
2013/12/1 12:00:00,games/Makefile
2013/12/1 12:00:00,games/Makefile.inc
2013/12/1 12:00:00,games/monop
2013/12/1 12:00:00,games/morse
2013/12/1 12:00:00,games/number
2013/12/1 12:00:00,games/pig