Re-add test data and reference files after reboot

This commit is contained in:
Jarvis 2026-02-21 02:37:37 +00:00
parent 6fae024a7c
commit ba4463dcc8
28 changed files with 25679 additions and 0 deletions

85
irc_client.py Normal file
View file

@ -0,0 +1,85 @@
"""Minimal IRC client controller for black-box bot testing."""
import socket
import time
import threading
class IRCClient:
def __init__(self, nick, host="127.0.0.1", port=6667):
self.nick = nick
self.host = host
self.port = port
self.sock = None
self.buffer = ""
self.messages = [] # collected incoming messages
self._lock = threading.Lock()
self._reader = None
self._running = False
def connect(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((self.host, self.port))
self._running = True
self._reader = threading.Thread(target=self._read_loop, daemon=True)
self._reader.start()
self._send(f"NICK {self.nick}")
self._send(f"USER {self.nick} 0 * :{self.nick}")
# Wait for RPL_WELCOME (001) to confirm registration
welcome = self.wait_for(" 001 ", timeout=10)
if not welcome:
raise ConnectionError(f"{self.nick}: registration timed out")
def _send(self, line):
self.sock.sendall((line + "\r\n").encode())
def _read_loop(self):
while self._running:
try:
data = self.sock.recv(4096)
if not data:
break
self.buffer += data.decode("utf-8", errors="replace")
while "\r\n" in self.buffer:
line, self.buffer = self.buffer.split("\r\n", 1)
# Auto-respond to PING
if line.startswith("PING"):
self._send("PONG" + line[4:])
with self._lock:
self.messages.append(line)
except OSError:
break
def join(self, channel):
self._send(f"JOIN {channel}")
time.sleep(0.3)
def say(self, target, message):
self._send(f"PRIVMSG {target} :{message}")
def get_messages(self, clear=True):
with self._lock:
msgs = list(self.messages)
if clear:
self.messages.clear()
return msgs
def wait_for(self, substring, timeout=5.0):
"""Wait until a message containing substring appears. Returns it or None."""
deadline = time.time() + timeout
while time.time() < deadline:
with self._lock:
for i, msg in enumerate(self.messages):
if substring in msg:
self.messages.pop(i)
return msg
time.sleep(0.1)
return None
def quit(self):
self._running = False
try:
self._send("QUIT :bye")
self.sock.close()
except OSError:
pass

127
monop_bridge.py Normal file
View file

@ -0,0 +1,127 @@
"""Bridge monop binary to IRC via subprocess pipes."""
import sys
sys.stdout.reconfigure(line_buffering=True)
import socket
import subprocess
import threading
import time
import sys
import os
import re
HOST = "127.0.0.1"
PORT = 6667
NICK = "monop"
CHANNEL = "#monop"
PREFIX = "."
MONOP_BIN = "/tmp/monop-irc/monop/monop"
CARDS_FILE = "/tmp/monop-irc/monop/cards.pck"
class IRCBridge:
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.proc = None
self.buffer = ""
def irc_send(self, line):
self.sock.sendall((line + "\r\n").encode())
def irc_say(self, msg):
self.irc_send(f"PRIVMSG {CHANNEL} :{msg}")
def connect_irc(self):
self.sock.connect((HOST, PORT))
self.irc_send(f"NICK {NICK}")
self.irc_send(f"USER {NICK} 0 * :{NICK}")
# Wait for registration
while True:
data = self.sock.recv(4096)
if not data:
raise ConnectionError("IRC connection closed during registration")
self.buffer += data.decode("utf-8", errors="replace")
for line in self.buffer.split("\r\n"):
if line.startswith("PING"):
self.irc_send("PONG" + line[4:])
if "ERROR" in line:
print(f"[bridge] Server error: {line}")
if " 001 " in self.buffer:
break
self.irc_send(f"JOIN {CHANNEL}")
time.sleep(0.5)
self.buffer = ""
self.irc_say("Shall We Play A Game?")
self.irc_say(f'Prefix your commands with a dot "."')
print(f"[bridge] Connected to IRC as {NICK} in {CHANNEL}")
def start_monop(self):
env = os.environ.copy()
self.proc = subprocess.Popen(
[MONOP_BIN],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
env=env,
cwd=os.path.dirname(MONOP_BIN),
)
# Read monop stdout -> IRC
t = threading.Thread(target=self._monop_reader, daemon=True)
t.start()
print("[bridge] monop process started")
def _monop_reader(self):
"""Read lines from monop stdout and send to IRC."""
for raw in self.proc.stdout:
line = raw.decode("utf-8", errors="replace").rstrip("\n\r")
if line:
self.irc_say(line)
print(f"[monop -> irc] {line}")
def _feed_monop(self, nick, text):
"""Feed input to monop stdin as 'nick text'."""
feed = f"{nick} {text}\n"
print(f"[irc -> monop] {feed.rstrip()}")
try:
self.proc.stdin.write(feed.encode())
self.proc.stdin.flush()
except BrokenPipeError:
print("[bridge] monop process died, restarting...")
self.start_monop()
def run(self):
self.connect_irc()
self.start_monop()
while True:
try:
data = self.sock.recv(4096)
if not data:
break
self.buffer += data.decode("utf-8", errors="replace")
while "\r\n" in self.buffer:
line, self.buffer = self.buffer.split("\r\n", 1)
if line.startswith("PING"):
self.irc_send("PONG" + line[4:])
continue
# Parse PRIVMSG
m = re.match(
r":(\S+?)!(\S+?) PRIVMSG (\S+) :(.+)", line
)
if m:
sender_nick = m.group(1)
target = m.group(3)
msg = m.group(4)
if target == CHANNEL and sender_nick != NICK:
if msg.startswith(PREFIX):
cmd = msg[len(PREFIX):]
self._feed_monop(sender_nick, cmd)
except Exception as e:
print(f"[bridge] error: {e}")
break
if __name__ == "__main__":
bridge = IRCBridge()
bridge.run()

76
reference/brd.dat Normal file
View file

@ -0,0 +1,76 @@
/* $NetBSD: brd.dat,v 1.3 2003/08/07 09:37:27 agc 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.
*
* @(#)brd.dat 5.5 (Berkeley) 5/31/93
*/
/* name (COLOR) owner type desc cost */
{"=== GO ===", -1, SAFE, 0 },
{"Mediterranean ave. (P)", -1, PRPTY, &prop[0], 60 },
{"Community Chest i", -1, CC, },
{"Baltic ave. (P)", -1, PRPTY, &prop[1], 60 },
{"Income Tax", -1, INC_TAX, },
{"Reading RR", -1, RR, &rr[0], 200 },
{"Oriental ave. (L)", -1, PRPTY, &prop[2], 100 },
{"Chance i", -1, CHANCE, },
{"Vermont ave. (L)", -1, PRPTY, &prop[3], 100 },
{"Connecticut ave. (L)", -1, PRPTY, &prop[4], 120 },
{"Just Visiting", -1, SAFE, 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, },
{"Tennessee ave. (O)", -1, PRPTY, &prop[9], 180 },
{"New York ave. (O)", -1, PRPTY, &prop[10], 200 },
{"Free Parking", -1, SAFE, 0 },
{"Kentucky ave. (R)", -1, PRPTY, &prop[11], 220 },
{"Chance ii", -1, CHANCE, },
{"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, },
{"Pacific ave. (G)", -1, PRPTY, &prop[17], 300 },
{"N. Carolina ave. (G)", -1, PRPTY, &prop[18], 300 },
{"Community Chest iii", -1, CC, },
{"Pennsylvania ave. (G)", -1, PRPTY, &prop[19], 320 },
{"Short Line RR", -1, RR, &rr[3], 200 },
{"Chance iii", -1, CHANCE, },
{"Park place (D)", -1, PRPTY, &prop[20], 350 },
{"Luxury Tax", -1, LUX_TAX, },
{"Boardwalk (D)", -1, PRPTY, &prop[21], 400 },
{"JAIL", -1, IN_JAIL, }

241
reference/cards.c Normal file
View file

@ -0,0 +1,241 @@
/* $NetBSD: cards.c,v 1.14 2004/01/27 20:30:30 jsm 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.14 2004/01/27 20:30:30 jsm Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <endian.h>
#include "monop.ext"
#include "pathnames.h"
/*
* These routine deal with the card decks
*/
#define GOJF 'F' /* char for get-out-of-jail-free cards */
#ifndef DEV
static const char *cardfile = _PATH_CARDS;
#else
static const char *cardfile = "cards.pck";
#endif
static FILE *deckf;
static void set_up(DECK *);
static void printmes(void);
/*
* This routine initializes the decks from the data file,
* which it opens.
*/
void
init_decks()
{
int32_t nc;
if ((deckf=fopen(cardfile, "r")) == NULL) {
file_err:
perror(cardfile);
exit(1);
}
/* read number of community chest cards... */
if (fread(&nc, sizeof(nc), 1, deckf) != 1)
goto file_err;
CC_D.num_cards = be32toh(nc);
/* ... and number of community chest cards. */
if (fread(&nc, sizeof(nc), 1, deckf) != 1)
goto file_err;
CH_D.num_cards = be32toh(nc);
set_up(&CC_D);
set_up(&CH_D);
}
/*
* This routine sets up the offset pointers for the given deck.
*/
static void
set_up(dp)
DECK *dp;
{
int r1, r2;
int i;
dp->offsets = (u_int64_t *) calloc(dp->num_cards, sizeof (u_int64_t));
if (dp->offsets == NULL)
err(1, NULL);
if (fread(dp->offsets, sizeof(u_int64_t), dp->num_cards, deckf) !=
(size_t)dp->num_cards) {
perror(cardfile);
exit(1);
}
/* convert offsets from big-endian byte order */
for (i = 0; i < dp->num_cards; i++)
BE64TOH(dp->offsets[i]);
dp->last_card = 0;
dp->gojf_used = FALSE;
for (i = 0; i < dp->num_cards; i++) {
u_int64_t temp;
r1 = roll(1, dp->num_cards) - 1;
r2 = roll(1, dp->num_cards) - 1;
temp = dp->offsets[r2];
dp->offsets[r2] = dp->offsets[r1];
dp->offsets[r1] = temp;
}
}
/*
* This routine draws a card from the given deck
*/
void
get_card(dp)
DECK *dp;
{
char type_maj, type_min;
int num;
int i, per_h, per_H, num_h, num_H;
OWN *op;
do {
fseek(deckf, dp->offsets[dp->last_card], SEEK_SET);
dp->last_card = ++(dp->last_card) % dp->num_cards;
type_maj = getc(deckf);
} while (dp->gojf_used && type_maj == GOJF);
type_min = getc(deckf);
num = ntohl(getw(deckf));
printmes();
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()
{
char c;
printline();
fflush(stdout);
while ((c = getc(deckf)) != '\0')
putchar(c);
printline();
fflush(stdout);
}

122
reference/cards.inp Normal file
View file

@ -0,0 +1,122 @@
FF
>> GET OUT OF JAIL FREE <<
Keep this card until needed or sold
%%
++25
Receive for Services $25.
%%
++200
Bank Error in Your Favor.
Collect $200.
%%
++20
Income Tax Refund.
Collect $20.
%%
--100
Pay Hospital $100
%%
++100
Life Insurance Matures.
Collect $100
%%
++45
From sale of Stock You get $45.
%%
TX
You are Assessed for street repairs.
$40 per House
$115 per Hotel
%%
++100
X-mas Fund Matures.
Collect $100.
%%
++11
You have won Second Prize in a Beauty Contest
Collect $11
%%
MF0
Advance to GO
(Collect $200)
%%
++100
You inherit $100
%%
--150
Pay School Tax of $150.
%%
MJ
>> GO TO JAIL <<
Go Directly to Jail. Do not pass GO Do not collect $200.
%%
+A50
>> GRAND OPERA OPENING <<
Collect $50 from each player for opening night seats.
%%
--50
Doctor's Fee: Pay $50.
%-
FF
>> GET OUT OF JAIL FREE <<
Keep this card until needed or sold
%%
MR
Advance to the nearest Railroad, and pay owner
Twice the rental to which he is otherwise entitled.
If Railroad is unowned you may buy it from the bank
%%
MU
Advance to the nearest Utility.
If unowned, you may buy it from the bank.
If owned, throw dice and pay oner a total of ten times
the amount thrown.
%%
MB3
Go Back 3 Spaces
%%
MR
Advance to the nearest Railroad, and pay owner
Twice the rental to which he is otherwise entitled.
If Railroad is unowned you may buy it from the bank
%%
MJ
>> GO DIRECTLY TO JAIL <<
Do not pass GO, Do not Collect $200.
%%
MF5
Take a Ride on the Reading.
If you pass GO, collect $200.
%%
MF39
Take a Walk on the Board Walk.
(Advance To Board Walk)
%%
MF24
Advance to Illinois Ave.
%%
MF0
Advance to Go
%%
MF11
Advance to St. Charles Place.
If you pass GO, collect $200.
%%
TX
Make general repairs on all of your Property.
For Each House pay $25.
For Each Hotel pay $100.
%%
-A50
You have been elected Chairman of the Board.
Pay each player $50.
%%
--15
Pay Poor Tax of $15
%%
++50
Bank pays you Dividend of $50.
%%
++150
Your Building and Loan Matures.
Collect $150.

48
reference/deck.h Normal file
View file

@ -0,0 +1,48 @@
/* $NetBSD: deck.h,v 1.6 2003/08/07 09:37:27 agc 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
#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 last_card; /* number of last card picked */
bool gojf_used; /* set if gojf card out of deck */
u_int64_t *offsets; /* offsets for start of cards */
};
typedef struct dk_st DECK;

272
reference/execute.c Normal file
View file

@ -0,0 +1,272 @@
/* $NetBSD: execute.c,v 1.11 2004/01/27 20:30:30 jsm 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.11 2004/01/27 20:30:30 jsm Exp $");
#endif
#endif /* not lint */
#include "monop.ext"
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#define SEGSIZE 8192
typedef struct stat STAT;
typedef struct tm TIME;
static char buf[257];
static bool new_play; /* set if move on to new player */
extern void *heapstart;
static void show_move(void);
/*
* This routine executes the given command by index number
*/
void
execute(com_num)
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()
{
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(rl)
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()
{
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);
}
}
/*
* This routine saves the current game for use at a later date
*/
void
save()
{
char *sp;
int outf, num;
time_t t;
struct stat sb;
char *start, *end;
printf("Which file do you wish to save it in? ");
sp = buf;
while ((*sp++=getchar()) != '\n')
continue;
*--sp = '\0';
/*
* check for existing files, and confirm overwrite if needed
*/
if (stat(buf, &sb) > -1
&& getyn("File exists. Do you wish to overwrite? ") > 0)
return;
if ((outf=creat(buf, 0644)) < 0) {
perror(buf);
return;
}
printf("\"%s\" ", buf);
time(&t); /* get current time */
strcpy(buf, ctime(&t));
for (sp = buf; *sp != '\n'; sp++)
continue;
*sp = '\0';
start = heapstart;
end = sbrk(0);
while (start < end) { /* write out entire data space */
num = start + 16 * 1024 > end ? end - start : 16 * 1024;
write(outf, start, num);
start += num;
}
close(outf);
printf("[%s]\n", buf);
}
/*
* This routine restores an old game from a file
*/
void
restore()
{
char *sp;
printf("Which file do you wish to restore from? ");
for (sp = buf; (*sp=getchar()) != '\n'; sp++)
continue;
*sp = '\0';
rest_f(buf);
}
/*
* This does the actual restoring. It returns TRUE if the
* backup was successful, else false.
*/
int
rest_f(file)
const char *file;
{
char *sp;
int inf, num;
char buf[80];
char *start, *end;
STAT sbuf;
if ((inf=open(file, O_RDONLY)) < 0) {
perror(file);
return FALSE;
}
printf("\"%s\" ", file);
if (fstat(inf, &sbuf) < 0) { /* get file stats */
perror(file);
exit(1);
}
start = heapstart;
brk(end = start + sbuf.st_size);
while (start < end) { /* write out entire data space */
num = start + 16 * 1024 > end ? end - start : 16 * 1024;
read(inf, start, num);
start += num;
}
close(inf);
strcpy(buf, ctime(&sbuf.st_mtime));
for (sp = buf; *sp != '\n'; sp++)
continue;
*sp = '\0';
printf("[%s]\n", buf);
return TRUE;
}

145
reference/getinp.c Normal file
View file

@ -0,0 +1,145 @@
/* $NetBSD: getinp.c,v 1.13 2004/11/05 21:30:32 dsl 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.13 2004/11/05 21:30:32 dsl Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "monop.ext"
#define LINE 70
static char buf[257];
static int comp(const char *);
int
getinp(prompt, list)
const char *prompt, *const list[];
{
int i, n_match, match = 0;
char *sp;
PLAY *p;
int c;
p = trade_p ? trade_p : cur_p;
printf("%s\n", prompt);
fflush(stdout);
for (;;) {
inter:
begin:
sp=buf;
while ((c=getchar()) != ' ' && c != '\n') {
*sp = c;
sp++;
}
*sp = 0;
if (c == '\n' || strcmp(buf, p->name)) {
printf("Illegal action: bad player (%s's turn, not %s)\n", p->name, buf);
if (c != '\n') while ((c=getchar()) != '\n');
goto begin;
}
for (sp = buf; (c=getchar()) != '\n'; ) {
*sp = c;
if (c == -1) /* check for interrupted system call */
goto inter;
else if (sp != buf || *sp != ' ')
sp++;
}
*sp = c;
if (buf[0] == '?' && buf[1] == '\n') {
printf("Valid inputs are: ");
for (i = 0, match = 18; list[i]; i++) {
if ((match+=(n_match=strlen(list[i]))) > LINE) {
printf("\n ");
match = n_match + 8;
}
if (*list[i] == '\0') {
match += 8;
printf("<RETURN>");
}
else
printf("%s", list[i]);
if (list[i+1])
printf(", ");
else
putchar('\n');
match += 2;
}
continue;
}
*sp = '\0';
for (sp = buf; *sp; sp++)
*sp = tolower((unsigned char)*sp);
for (i = n_match = 0; list[i]; i++)
if (comp(list[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(s1)
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;
}

286
reference/houses.c Normal file
View file

@ -0,0 +1,286 @@
/* $NetBSD: houses.c,v 1.8 2004/01/27 20:30:30 jsm 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.8 2004/01/27 20:30:30 jsm Exp $");
#endif
#endif /* not lint */
#include "monop.ext"
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 *);
/*
* These routines deal with buying and selling houses
*/
void
buy_houses()
{
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++;
if (op->sqr->desc->houses != 5)
good++;
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(mnp)
MON *mnp;
{
int i;
MON *mp;
int price;
short input[3],temp[3];
int tot;
PROP *pp;
mp = mnp;
price = mp->h_cost * 50;
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;
temp[i] = 5;
continue;
}
(void)sprintf(cur_prop, "%s (%d): ",
mp->sq[i]->name, pp->houses);
input[i] = get_int(cur_prop);
temp[i] = input[i] + pp->houses;
if (temp[i] > 5) {
printf("That's too many. The most you can buy is %d\n",
5 - 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 for %d houses for $%d\n", tot, 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];
}
}
}
/*
* This routine sells houses.
*/
void
sell_houses()
{
int num_mon;
MON *mp;
OWN *op;
bool good;
int p;
over:
num_mon = 0;
good = TRUE;
for (op = cur_p->own_list; op; op = op->next)
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++;
while (op->next && op->sqr->desc->mon_desc == mp
&& (op=op->next));
if (!good)
--num_mon;
}
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(mnp)
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)sprintf(cur_prop,"%s (%d): ",
mp->sq[i]->name,pp->houses);
else
(void)sprintf(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 houses for $%d\n",tot,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(mp)
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');
}

276
reference/initdeck.c Normal file
View file

@ -0,0 +1,276 @@
/* $NetBSD: initdeck.c,v 1.15 2003/08/07 09:37:28 agc 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.
*/
#ifdef __NetBSD__
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)initdeck.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: initdeck.c,v 1.15 2003/08/07 09:37:28 agc Exp $");
#endif
#endif /* not lint */
#endif /* __NetBSD__ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "deck.h"
#ifndef u_int32_t
#define u_int32_t unsigned int
#endif
static u_int32_t
h2nl(u_int32_t h)
{
unsigned char c[4];
u_int32_t rv;
c[0] = (h >> 24) & 0xff;
c[1] = (h >> 16) & 0xff;
c[2] = (h >> 8) & 0xff;
c[3] = (h >> 0) & 0xff;
memcpy(&rv, c, sizeof rv);
return (rv);
}
/*
* This program initializes the card files for monopoly.
* It reads in a data file with Com. Chest cards, followed by
* the Chance card. The two are separated by a line of "%-".
* All other cards are separated by lines of "%%". In the front
* of the file is the data for the decks in the same order.
* This includes the seek pointer for the start of each card.
* All cards start with their execution code, followed by the
* string to print, terminated with a null byte.
*/
#define TRUE 1
#define FALSE 0
#define bool char
const char *infile = "cards.inp", /* input file */
*outfile = "cards.pck"; /* "packed" file */
DECK deck[2];
FILE *inf, *outf;
/* initdeck.c */
int main(int, char *[]);
static void getargs(int, char *[]);
static void fwrite_be_offt(off_t, FILE *);
static void count(void);
static void putem(void);
int
main(ac, av)
int ac;
char *av[];
{
int i, nc;
/* sanity test */
if (sizeof(int) != 4) {
fprintf(stderr, "sizeof(int) != 4\n");
exit(1);
}
getargs(ac, av);
if ((inf = fopen(infile, "r")) == NULL) {
perror(infile);
exit(1);
}
count();
/*
* allocate space for pointers.
*/
CC_D.offsets = calloc(CC_D.num_cards + 1, /* sizeof (off_t) */ 8);
CH_D.offsets = calloc(CH_D.num_cards + 1, /* sizeof (off_t) */ 8);
if (CC_D.offsets == NULL || CH_D.offsets == NULL) {
fprintf(stderr, "out of memory\n");
exit(1);
}
fseek(inf, 0L, SEEK_SET);
if ((outf = fopen(outfile, "w")) == NULL) {
perror(outfile);
exit(1);
}
/*
* these fields will be overwritten after the offsets are calculated,
* so byte-order doesn't matter yet.
*/
fwrite(&nc, sizeof(nc), 1, outf);
fwrite(&nc, sizeof(nc), 1, outf);
fwrite(CC_D.offsets, /* sizeof (off_t) */ 8, CC_D.num_cards, outf);
fwrite(CH_D.offsets, /* sizeof (off_t) */ 8, CH_D.num_cards, outf);
/*
* write out the cards themselves (calculating the offsets).
*/
putem();
fclose(inf);
fseek(outf, 0, SEEK_SET);
/* number of community chest cards first... */
nc = h2nl(CC_D.num_cards);
fwrite(&nc, sizeof(nc), 1, outf);
/* ... then number of chance cards. */
nc = h2nl(CH_D.num_cards);
fwrite(&nc, sizeof(nc), 1, outf);
/* dump offsets in big-endian byte order */
for (i = 0; i < CC_D.num_cards; i++)
fwrite_be_offt(CC_D.offsets[i], outf);
for (i = 0; i < CH_D.num_cards; i++)
fwrite_be_offt(CH_D.offsets[i], outf);
fflush(outf);
if (ferror(outf)) {
perror(outfile);
exit(1);
}
fclose(outf);
printf("There were %d com. chest and %d chance cards\n",
CC_D.num_cards, CH_D.num_cards);
exit(0);
}
static void
getargs(ac, av)
int ac;
char *av[];
{
if (ac > 1)
infile = av[1];
if (ac > 2)
outfile = av[2];
}
/*
* count the cards
*/
static void
count()
{
bool newline;
DECK *in_deck;
int c;
newline = TRUE;
in_deck = &CC_D;
while ((c=getc(inf)) != EOF)
if (newline && c == '%') {
newline = FALSE;
in_deck->num_cards++;
if (getc(inf) == '-')
in_deck = &CH_D;
}
else
newline = (c == '\n');
in_deck->num_cards++;
}
/*
* put strings in the file
*/
static void
putem()
{
bool newline;
DECK *in_deck;
int c;
int num;
in_deck = &CC_D;
CC_D.num_cards = 1;
CH_D.num_cards = 0;
CC_D.offsets[0] = ftell(outf);
putc(getc(inf), outf);
putc(getc(inf), outf);
for (num = 0; (c=getc(inf)) != '\n'; )
num = num * 10 + (c - '0');
putw(h2nl(num), outf);
newline = FALSE;
while ((c=getc(inf)) != EOF)
if (newline && c == '%') {
putc('\0', outf);
newline = FALSE;
if (getc(inf) == '-')
in_deck = &CH_D;
while (getc(inf) != '\n')
continue;
in_deck->offsets[in_deck->num_cards++] = ftell(outf);
if ((c=getc(inf)) == EOF)
break;
putc(c, outf);
putc(c = getc(inf), outf);
for (num = 0; (c=getc(inf)) != EOF && c != '\n'; )
num = num * 10 + (c - '0');
putw(h2nl(num), outf);
}
else {
putc(c, outf);
newline = (c == '\n');
}
putc('\0', outf);
}
/*
* fwrite_be_offt:
* Write out the off paramater as a 64 bit big endian number
*/
static void
fwrite_be_offt(off, f)
off_t off;
FILE *f;
{
int i;
unsigned char c[8];
for (i = 7; i >= 0; i--) {
c[i] = off & 0xff;
off >>= 8;
}
fwrite(c, sizeof(c), 1, f);
}

140
reference/jail.c Normal file
View file

@ -0,0 +1,140 @@
/* $NetBSD: jail.c,v 1.6 2003/08/07 09:37:28 agc 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.6 2003/08/07 09:37:28 agc Exp $");
#endif
#endif /* not lint */
#include "monop.ext"
/*
* This routine uses a get-out-of-jail-free card to get the
* player out of jail.
*/
void
card()
{
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 returns the players get-out-of-jail-free card
* to a deck.
*/
void
ret_card(plr)
PLAY *plr;
{
plr->num_gojf--;
if (CC_D.gojf_used)
CC_D.gojf_used = FALSE;
else
CH_D.gojf_used = FALSE;
}
/*
* This routine deals with paying your way out of jail.
*/
void
pay()
{
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(r1, r2)
int r1, 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()
{
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");
}

493
reference/malloc.c Normal file
View file

@ -0,0 +1,493 @@
/* $NetBSD: malloc.c,v 1.4 2004/12/14 00:21:01 nathanw Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. 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>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)malloc.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: malloc.c,v 1.4 2004/12/14 00:21:01 nathanw Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
/*
* malloc.c (Caltech) 2/21/82
* Chris Kingsley, kingsley@cit-20.
*
* This is a very fast storage allocator. It allocates blocks of a small
* number of different sizes, and keeps free lists of each size. Blocks that
* don't exactly fit are passed up to the next larger size. In this
* implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
* This is designed for use in a virtual memory environment.
*/
#include <sys/types.h>
#if defined(DEBUG) || defined(RCHECK)
#include <sys/uio.h>
#endif
#if defined(RCHECK) || defined(MSTATS)
#include <stdio.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
/*
* The overhead on a block is at least 4 bytes. When free, this space
* contains a pointer to the next free block, and the bottom two bits must
* be zero. When in use, the first byte is set to MAGIC, and the second
* byte is the size index. The remaining bytes are for alignment.
* If range checking is enabled then a second word holds the size of the
* requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
* The order of elements is critical: ov_magic must overlay the low order
* bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
*/
union overhead {
union overhead *ov_next; /* when free */
struct {
u_char ovu_magic; /* magic number */
u_char ovu_index; /* bucket # */
#ifdef RCHECK
u_short ovu_rmagic; /* range magic number */
u_long ovu_size; /* actual block size */
#endif
} ovu;
#define ov_magic ovu.ovu_magic
#define ov_index ovu.ovu_index
#define ov_rmagic ovu.ovu_rmagic
#define ov_size ovu.ovu_size
};
#define MAGIC 0xef /* magic # on accounting info */
#ifdef RCHECK
#define RMAGIC 0x5555 /* magic # on range info */
#endif
#ifdef RCHECK
#define RSLOP sizeof (u_short)
#else
#define RSLOP 0
#endif
/*
* nextf[i] is the pointer to the next free block of size 2^(i+3). The
* smallest allocatable block is 8 bytes. The overhead information
* precedes the data area returned to the user.
*/
#define NBUCKETS 30
static union overhead *nextf[NBUCKETS];
static long pagesz; /* page size */
static int pagebucket; /* page size bucket */
#ifdef MSTATS
/*
* nmalloc[i] is the difference between the number of mallocs and frees
* for a given block size.
*/
static u_int nmalloc[NBUCKETS];
#endif
static pthread_mutex_t malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
static void morecore(int);
static int findbucket(union overhead *, int);
#ifdef MSTATS
void mstats(const char *);
#endif
#if defined(DEBUG) || defined(RCHECK)
#define ASSERT(p) if (!(p)) botch(__STRING(p))
static void botch(const char *);
/*
* NOTE: since this may be called while malloc_mutex is locked, stdio must not
* be used in this function.
*/
static void
botch(s)
const char *s;
{
struct iovec iov[3];
iov[0].iov_base = "\nassertion botched: ";
iov[0].iov_len = 20;
iov[1].iov_base = (void *)s;
iov[1].iov_len = strlen(s);
iov[2].iov_base = "\n";
iov[2].iov_len = 1;
/*
* This place deserves a word of warning: a cancellation point will
* occur when executing writev(), and we might be still owning
* malloc_mutex. At this point we need to disable cancellation
* until `after' abort() because i) establishing a cancellation handler
* might, depending on the implementation, result in another malloc()
* to be executed, and ii) it is really not desirable to let execution
* continue. `Fix me.'
*
* Note that holding mutex_lock during abort() is safe.
*/
(void)writev(STDERR_FILENO, iov, 3);
abort();
}
#else
#define ASSERT(p)
#endif
void *
malloc(nbytes)
size_t nbytes;
{
union overhead *op;
int bucket;
long n;
unsigned amt;
pthread_mutex_lock(&malloc_mutex);
/*
* First time malloc is called, setup page size and
* align break pointer so all data will be page aligned.
*/
if (pagesz == 0) {
pagesz = n = getpagesize();
ASSERT(pagesz > 0);
op = (union overhead *)(void *)sbrk(0);
n = n - sizeof (*op) - ((long)op & (n - 1));
if (n < 0)
n += pagesz;
if (n) {
if (sbrk((int)n) == (void *)-1) {
pthread_mutex_unlock(&malloc_mutex);
return (NULL);
}
}
bucket = 0;
amt = 8;
while (pagesz > amt) {
amt <<= 1;
bucket++;
}
pagebucket = bucket;
}
/*
* Convert amount of memory requested into closest block size
* stored in hash buckets which satisfies request.
* Account for space used per block for accounting.
*/
if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) {
#ifndef RCHECK
amt = 8; /* size of first bucket */
bucket = 0;
#else
amt = 16; /* size of first bucket */
bucket = 1;
#endif
n = -((long)sizeof (*op) + RSLOP);
} else {
amt = (unsigned)pagesz;
bucket = pagebucket;
}
while (nbytes > amt + n) {
amt <<= 1;
if (amt == 0)
return (NULL);
bucket++;
}
/*
* If nothing in hash bucket right now,
* request more memory from the system.
*/
if ((op = nextf[bucket]) == NULL) {
morecore(bucket);
if ((op = nextf[bucket]) == NULL) {
pthread_mutex_unlock(&malloc_mutex);
return (NULL);
}
}
/* remove from linked list */
nextf[bucket] = op->ov_next;
op->ov_magic = MAGIC;
op->ov_index = bucket;
#ifdef MSTATS
nmalloc[bucket]++;
#endif
pthread_mutex_unlock(&malloc_mutex);
#ifdef RCHECK
/*
* Record allocated size of block and
* bound space with magic numbers.
*/
op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
op->ov_rmagic = RMAGIC;
*(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif
return ((void *)(op + 1));
}
/*
* Allocate more memory to the indicated bucket.
*/
static void
morecore(bucket)
int bucket;
{
union overhead *op;
long sz; /* size of desired block */
long amt; /* amount to allocate */
long nblks; /* how many blocks we get */
/*
* sbrk_size <= 0 only for big, FLUFFY, requests (about
* 2^30 bytes on a VAX, I think) or for a negative arg.
*/
sz = 1 << (bucket + 3);
#ifdef DEBUG
ASSERT(sz > 0);
#else
if (sz <= 0)
return;
#endif
if (sz < pagesz) {
amt = pagesz;
nblks = amt / sz;
} else {
amt = sz + pagesz;
nblks = 1;
}
op = (union overhead *)(void *)sbrk((int)amt);
/* no more room! */
if ((long)op == -1)
return;
/*
* Add new memory allocated to that on
* free list for this hash bucket.
*/
nextf[bucket] = op;
while (--nblks > 0) {
op->ov_next =
(union overhead *)(void *)((caddr_t)(void *)op+(size_t)sz);
op = op->ov_next;
}
}
void
free(cp)
void *cp;
{
long size;
union overhead *op;
if (cp == NULL)
return;
op = (union overhead *)(void *)((caddr_t)cp - sizeof (union overhead));
#ifdef DEBUG
ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */
#else
if (op->ov_magic != MAGIC)
return; /* sanity */
#endif
#ifdef RCHECK
ASSERT(op->ov_rmagic == RMAGIC);
ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
#endif
size = op->ov_index;
ASSERT(size < NBUCKETS);
pthread_mutex_lock(&malloc_mutex);
op->ov_next = nextf[(unsigned int)size];/* also clobbers ov_magic */
nextf[(unsigned int)size] = op;
#ifdef MSTATS
nmalloc[(size_t)size]--;
#endif
pthread_mutex_unlock(&malloc_mutex);
}
/*
* When a program attempts "storage compaction" as mentioned in the
* old malloc man page, it realloc's an already freed block. Usually
* this is the last block it freed; occasionally it might be farther
* back. We have to search all the free lists for the block in order
* to determine its bucket: 1st we make one pass thru the lists
* checking only the first block in each; if that fails we search
* ``__realloc_srchlen'' blocks in each list for a match (the variable
* is extern so the caller can modify it). If that fails we just copy
* however many bytes was given to realloc() and hope it's not huge.
*/
int __realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */
void *
realloc(cp, nbytes)
void *cp;
size_t nbytes;
{
u_long onb;
long i;
union overhead *op;
char *res;
int was_alloced = 0;
if (cp == NULL)
return (malloc(nbytes));
if (nbytes == 0) {
free (cp);
return (NULL);
}
op = (union overhead *)(void *)((caddr_t)cp - sizeof (union overhead));
pthread_mutex_lock(&malloc_mutex);
if (op->ov_magic == MAGIC) {
was_alloced++;
i = op->ov_index;
} else {
/*
* Already free, doing "compaction".
*
* Search for the old block of memory on the
* free list. First, check the most common
* case (last element free'd), then (this failing)
* the last ``__realloc_srchlen'' items free'd.
* If all lookups fail, then assume the size of
* the memory block being realloc'd is the
* largest possible (so that all "nbytes" of new
* memory are copied into). Note that this could cause
* a memory fault if the old area was tiny, and the moon
* is gibbous. However, that is very unlikely.
*/
if ((i = findbucket(op, 1)) < 0 &&
(i = findbucket(op, __realloc_srchlen)) < 0)
i = NBUCKETS;
}
onb = (u_long)1 << (u_long)(i + 3);
if (onb < pagesz)
onb -= sizeof (*op) + RSLOP;
else
onb += pagesz - sizeof (*op) - RSLOP;
/* avoid the copy if same size block */
if (was_alloced) {
if (i) {
i = (long)1 << (long)(i + 2);
if (i < pagesz)
i -= sizeof (*op) + RSLOP;
else
i += pagesz - sizeof (*op) - RSLOP;
}
if (nbytes <= onb && nbytes > i) {
#ifdef RCHECK
op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
*(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif
pthread_mutex_unlock(&malloc_mutex);
return (cp);
}
#ifndef _REENT
else
free(cp);
#endif
}
pthread_mutex_unlock(&malloc_mutex);
if ((res = malloc(nbytes)) == NULL) {
#ifdef _REENT
free(cp);
#endif
return (NULL);
}
#ifndef _REENT
if (cp != res) /* common optimization if "compacting" */
(void)memmove(res, cp, (size_t)((nbytes < onb) ? nbytes : onb));
#else
(void)memmove(res, cp, (size_t)((nbytes < onb) ? nbytes : onb));
free(cp);
#endif
return (res);
}
/*
* Search ``srchlen'' elements of each free list for a block whose
* header starts at ``freep''. If srchlen is -1 search the whole list.
* Return bucket number, or -1 if not found.
*/
static int
findbucket(freep, srchlen)
union overhead *freep;
int srchlen;
{
union overhead *p;
int i, j;
for (i = 0; i < NBUCKETS; i++) {
j = 0;
for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
if (p == freep)
return (i);
j++;
}
}
return (-1);
}
#ifdef MSTATS
/*
* mstats - print out statistics about malloc
*
* Prints two lines of numbers, one showing the length of the free list
* for each size category, the second showing the number of mallocs -
* frees for each size category.
*/
void
mstats(s)
char *s;
{
int i, j;
union overhead *p;
int totfree = 0,
totused = 0;
fprintf(stderr, "Memory allocation statistics %s\nfree: ", s);
for (i = 0; i < NBUCKETS; i++) {
for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
;
fprintf(stderr, " %d", j);
totfree += j * (1 << (i + 3));
}
fprintf(stderr, "\nused: ");
for (i = 0; i < NBUCKETS; i++) {
fprintf(stderr, " %d", nmalloc[i]);
totused += nmalloc[i] * (1 << (i + 3));
}
fprintf(stderr, "\n Total in use: %d, total free: %d\n",
totused, totfree);
}
#endif

314
reference/misc.c Normal file
View file

@ -0,0 +1,314 @@
/* $NetBSD: misc.c,v 1.13 2004/11/05 21:30:32 dsl 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.13 2004/11/05 21:30:32 dsl Exp $");
#endif
#endif /* not lint */
#include "monop.ext"
#include <ctype.h>
#include <signal.h>
/*
* This routine executes a truncated set of commands until a
* "yes or "no" answer is gotten.
*/
int
getyn(prompt)
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()
{
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()
{
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(prompt)
const char *prompt;
{
int num;
char *sp;
int c;
char buf[257];
PLAY *p;
p = trade_p ? trade_p : cur_p;
for (;;) {
inter:
printf("%s\n", prompt);
fflush(stdout);
begin:
sp=buf;
while ((c=getchar()) != ' ' && c != '\n') {
*sp = c;
sp++;
}
*sp = 0;
if (p && (c == '\n' || strcmp(buf, p->name))) {
printf("Illegal action: bad player (%s's turn, not %s)\n", p->name, buf);
if (c != '\n') while ((c=getchar()) != '\n');
goto begin;
}
num = 0;
for (sp = buf; (c=getchar()) != '\n'; *sp++ = c)
if (c == -1) /* check for interrupted system call */
goto inter;
*sp = c;
if (sp == buf)
continue;
for (sp = buf; isspace((unsigned char)*sp); sp++)
continue;
for (; isdigit((unsigned char)*sp); sp++)
num = num * 10 + *sp - '0';
if (*sp == '\n')
return num;
else
printf("I can't understand that\n");
}
}
/*
* This routine sets the monopoly flag from the list given.
*/
void
set_ownlist(pl)
int pl;
{
int num; /* general counter */
MON *orig; /* remember starting monop ptr */
OWN *op; /* current owned prop */
OWN *orig_op; /* origianl prop before loop */
op = play[pl].own_list;
#ifdef DEBUG
printf("op [%d] = 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 = %d, op->sqr = %d, "
"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("[%d];\n", op);
#endif
}
#ifdef DEBUG
printf("num = %d\n");
#endif
if (orig == 0) {
printf("panic: bad monopoly descriptor: "
"orig = %p\n", orig);
printf("player # %d\n", pl+1);
printhold(pl);
printf("orig_op = %p\n", orig_op);
printf("orig_op->sqr->type = %d (PRPTY)\n",
op->sqr->type);
printf("orig_op->next = %p\n", op->next);
printf("orig_op->sqr->desc = %p\n",
op->sqr->desc);
printf("op = %p\n", 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);
}
#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
*/
void
is_monop(mp, pl)
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(mp)
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()
{
printhold(player);
}
/*
* This routine gives a list of a given players holdings
*/
void
list_all()
{
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()
{
putchar('\n');
if (getyn("Abort the WHOLE GAME and start over? [y/n]") == 0) {
printf("The party is over.\n");
exit(0);
}
}

42
reference/mon.dat Normal file
View file

@ -0,0 +1,42 @@
/* $NetBSD: mon.dat,v 1.3 2003/08/07 09:37:28 agc 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.
*
* @(#)mon.dat 5.4 (Berkeley) 5/31/93
*/
/* name owner num_in num_own h_cost not_m mon_n sq */
{0, -1, 2, 0, 1, "Purple", "PURPLE", {1,3}},
{0, -1, 3, 0, 1, "Lt. Blue", "LT. BLUE", {6,8,9}},
{0, -1, 3, 0, 2, "Violet", "VIOLET", {11,13,14}},
{0, -1, 3, 0, 2, "Orange", "ORANGE", {16,18,19}},
{0, -1, 3, 0, 3, "Red", "RED", {21,23,24}},
{0, -1, 3, 0, 3, "Yellow", "YELLOW", {26,27,29}},
{0, -1, 3, 0, 4, "Green", "GREEN", {31,32,34}},
{0, -1, 2, 0, 4, "Dk. Blue", "DK. BLUE", {37,39}}

207
reference/monop.c Normal file
View file

@ -0,0 +1,207 @@
/* $NetBSD: monop.c,v 1.15 2004/01/27 20:30:30 jsm 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\n\
The Regents of the University of California. All rights reserved.\n");
#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.15 2004/01/27 20:30:30 jsm Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include "monop.def"
int main(int, char *[]);
static void getplayers(void);
static void init_players(void);
static void init_monops(void);
static void do_quit(int);
void *heapstart;
/*
* This program implements a monopoly game
*/
int
main(ac, av)
int ac;
char *av[];
{
/* Revoke setgid privileges */
setregid(getgid(), getgid());
srand(getpid());
heapstart = sbrk(0);
setbuf(stdout, NULL);
if (ac > 1) {
if (!rest_f(av[1]))
restore();
}
else {
getplayers();
init_players();
init_monops();
}
num_luck = sizeof lucky_mes / sizeof (char *);
init_decks();
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(n)
int n __attribute__((__unused__));
{
quit();
}
/*
* This routine gets the names of the players
*/
static void
getplayers()
{
char *sp;
int i, j;
char buf[257];
trade_p = 0x0;
blew_it:
for (;;) {
if ((num_play=get_int("How many players? ")) <= 0 ||
num_play > MAX_PL)
printf("Sorry. Number must range from 1 to 9\n");
else
break;
}
cur_p = play = (PLAY *) calloc(num_play, sizeof (PLAY));
if (play == NULL)
err(1, NULL);
for (i = 0; i < num_play; i++) {
over:
printf("Player %d, say ''me'' please.\n", i + 1);
fflush(stdout);
/* read the irc nickname ... */
for (sp = buf; (*sp=getchar()) != ' '; sp++)
continue;
while (getchar() != '\n'); /* ... and discard the 'me' */
if (sp == buf)
goto over;
*sp++ = '\0';
name_list[i] = play[i].name = (char *)calloc(1, sp - buf);
if (name_list[i] == NULL)
err(1, NULL);
strcpy(play[i].name, buf);
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 (i != num_play - 1)
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()
{
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()
{
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]];
}
}

119
reference/monop.def Normal file
View file

@ -0,0 +1,119 @@
/* $NetBSD: monop.def,v 1.9 2004/01/27 20:30:30 jsm 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.def 5.5 (Berkeley) 5/31/93
*/
#include "deck.h"
#include "monop.h"
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 */
*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 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 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 */
*trade_p; /* pointer to current trading player */
RR_S rr[N_RR]; /* raildroad descriptions */
UTIL_S util[2]; /* utility descriptions */
MON mon[N_MON] = { /* monopoly descriptions */
# include "mon.dat"
};
PROP prop[N_PROP] = { /* typical properties */
# include "prop.dat"
};
SQUARE board[N_SQRS+1] = { /* board itself (+1 for Jail) */
# include "brd.dat"
};

57
reference/monop.ext Normal file
View file

@ -0,0 +1,57 @@
/* $NetBSD: monop.ext,v 1.7 2004/01/27 20:30:30 jsm 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.ext 5.4 (Berkeley) 5/31/93
*/
#include "deck.h"
#include "monop.h"
extern bool trading, spec, fixing, told_em;
extern const char *const yncoms[], *const comlist[], *name_list[], *const lucky_mes[];
extern int num_play, player, num_doub, num_luck;
extern void (*const func[])(void);
extern DECK deck[2];
extern MON mon[];
extern PLAY *play, *cur_p, *trade_p;
extern PROP prop[];
extern RR_S rr[];
extern SQUARE board[];
extern UTIL_S util[];

207
reference/monop.h Normal file
View file

@ -0,0 +1,207 @@
/* $NetBSD: monop.h,v 1.12 2004/01/27 20:30:30 jsm 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 */
/* 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) (sqp - board)
#define swap(A1,A2) if ((A1) != (A2)) { \
(A1) ^= (A2); \
(A2) ^= (A1); \
(A1) ^= (A2); \
}
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 propery list */
};
typedef struct plr_st PLAY;
typedef struct prp_st PROP;
typedef struct prp_st RR_S;
typedef struct prp_st UTIL_S;
/* cards.c */
void init_decks(void);
void get_card(DECK *);
/* 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 ret_card(PLAY *);
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_monop(MON *, 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);

239
reference/morg.c Normal file
View file

@ -0,0 +1,239 @@
/* $NetBSD: morg.c,v 1.10 2004/01/27 20:30:30 jsm 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.10 2004/01/27 20:30:30 jsm Exp $");
#endif
#endif /* not lint */
#include "monop.ext"
/*
* 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);
static void fix_ex(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()
{
int prop;
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 mortageable property is %s\n",
names[0]);
if (getyn("Do you want to mortgage it? ") == 0)
m(square[0]);
return;
}
prop = getinp("Which property do you want to mortgage? ",names);
if (prop == num_good)
return;
m(square[prop]);
notify();
}
}
/*
* This routine sets up the list of mortgageable property
*/
static int
set_mlist()
{
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(prop)
int prop;
{
int price;
price = board[prop].cost/2;
board[prop].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()
{
int prop;
for (;;) {
if (set_umlist() == 0) {
printf("You don't have any mortgaged property.\n");
return;
}
if (num_good == 1) {
printf("Your only mortaged property is %s\n",names[0]);
if (getyn("Do you want to unmortgage it? ") == 0)
unm(square[0]);
return;
}
prop = getinp("Which property do you want to unmortgage? ",
names);
if (prop == num_good)
return;
unm(square[prop]);
}
}
/*
* This routine sets up the list of mortgaged property
*/
static int
set_umlist()
{
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(prop)
int prop;
{
int price;
price = board[prop].cost/2;
board[prop].desc->morg = FALSE;
price += price/10;
printf("That cost you $%d\n",price);
cur_p->money -= price;
set_umlist();
}
/*
* This routine forces the indebted player to fix his
* financial woes.
*/
void
force_morg()
{
told_em = fixing = TRUE;
while (cur_p->money <= 0)
fix_ex(getinp("How are you going to fix it up? ",morg_coms));
fixing = FALSE;
}
/*
* This routine is a special execute for the force_morg routine
*/
static void
fix_ex(com_num)
int com_num;
{
told_em = FALSE;
(*func[com_num])();
notify();
}

35
reference/pathnames.h Normal file
View file

@ -0,0 +1,35 @@
/* Automatically generated from monop/pathnames.h.in. Do not edit. */
/* $NetBSD: pathnames.h,v 1.4 2003/08/07 09:37:29 agc Exp $ */
/*-
* Copyright (c) 1990, 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.
*
* @(#)pathnames.h 8.1 (Berkeley) 5/31/93
*/
#define _PATH_CARDS "/usr/share/games/bsdgames/monop-cards.pck"

202
reference/print.c Normal file
View file

@ -0,0 +1,202 @@
/* $NetBSD: print.c,v 1.8 2004/01/27 20:30:30 jsm 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.8 2004/01/27 20:30:30 jsm Exp $");
#endif
#endif /* not lint */
#include "monop.ext"
static const char *header = "Name Own Price Mg # Rent";
static void printmorg(const SQUARE *);
/*
* This routine prints out the current board
*/
void
printboard()
{
int i;
printf("%s %s\n", header, header);
for (i = 0; i < N_SQRS/2; i++) {
printsq(i, FALSE);
putchar(' ');
printsq(i+N_SQRS/2, TRUE);
}
}
/*
* This routine lists where each player is.
*/
void
where()
{
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(sqn, eoln)
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(sqp)
const SQUARE *sqp;
{
if (sqp->desc->morg)
printf(" * ");
else
printf(" ");
}
/*
* This routine lists the holdings of the player given
*/
void
printhold(pl)
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(" $%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(" %s\n", header);
for (op = pp->own_list; op; op = op->next) {
putchar(' ');
printsq(sqnum(op->sqr), TRUE);
}
}
}

230
reference/prop.c Normal file
View file

@ -0,0 +1,230 @@
/* $NetBSD: prop.c,v 1.9 2004/01/27 20:30:30 jsm 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.9 2004/01/27 20:30:30 jsm Exp $");
#endif
#endif /* not lint */
#include <stdlib.h>
#include "monop.ext"
static int value(SQUARE *);
/*
* This routine deals with buying property, setting all the
* appropriate flags.
*/
void
buy(player, sqrp)
int player;
SQUARE *sqrp;
{
trading = FALSE;
sqrp->owner = player;
add_list(player, &(play[player].own_list), cur_p->loc);
}
/*
* This routine adds an item to the list.
*/
void
add_list(plr, head, op_sqr)
int plr;
OWN **head;
int op_sqr;
{
int val;
OWN *tp, *last_tp;
OWN *op;
op = (OWN *)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(plr, head, op_sqr)
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 (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(sqp)
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 peice
* of property.
*/
void
bid()
{
static bool in[MAX_PL];
int i, num_in, cur_max;
char buf[80];
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)sprintf(buf, "%s: ", name_list[i]);
trade_p = &play[i];
cur_bid = get_int(buf);
trade_p = 0x0;
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");
}
} 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(plp)
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;
}

56
reference/prop.dat Normal file
View file

@ -0,0 +1,56 @@
/* $NetBSD: prop.dat,v 1.3 2003/08/07 09:37:29 agc 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.
*
* @(#)prop.dat 5.4 (Berkeley) 5/31/93
*/
/* 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} }

96
reference/rent.c Normal file
View file

@ -0,0 +1,96 @@
/* $NetBSD: rent.c,v 1.6 2003/08/07 09:37:29 agc 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.6 2003/08/07 09:37:29 agc Exp $");
#endif
#endif /* not lint */
#include "monop.ext"
/*
* This routine has the player pay rent
*/
void
rent(sqp)
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 houses, rent is %d\n",
pp->houses, 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;
}

80
reference/roll.c Normal file
View file

@ -0,0 +1,80 @@
/* $NetBSD: roll.c,v 1.9 2003/08/07 09:37:29 agc 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.9 2003/08/07 09:37:29 agc Exp $");
#endif
#endif /* not lint */
#include "monop.ext"
#include <stdlib.h>
/*
* This routine rolls ndie nside-sided dice.
*/
#if defined(pdp11)
#define MAXRAND 32767L
int
roll(ndie, nsides)
int ndie, nsides;
{
long tot;
unsigned n, r;
tot = 0;
n = ndie;
while (n--)
tot += rand();
return (int) ((tot * (long) nsides) / ((long) MAXRAND + 1)) + ndie;
}
#else
int
roll(ndie, nsides)
int ndie, nsides;
{
int tot, r;
double num_sides;
num_sides = nsides;
tot = 0;
while (ndie--)
tot += (r = rand()) * (num_sides / RAND_MAX) + 1;
return tot;
}
#endif

99
reference/spec.c Normal file
View file

@ -0,0 +1,99 @@
/* $NetBSD: spec.c,v 1.7 2003/08/07 09:37:30 agc 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.7 2003/08/07 09:37:30 agc Exp $");
#endif
#endif /* not lint */
#include "monop.ext"
static const char *const perc[] = {
"10%", "ten percent", "%", "$200", "200", 0
};
void
inc_tax()
{ /* collect income tax */
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! ");
}
void
goto_jail()
{ /* move player to jail */
cur_p->loc = JAIL;
}
void
lux_tax()
{ /* landing on luxury tax */
printf("You lose $75\n");
cur_p->money -= 75;
}
void
cc()
{ /* draw community chest card */
get_card(&CC_D);
}
void
chance()
{ /* draw chance card */
get_card(&CH_D);
}

333
reference/trade.c Normal file
View file

@ -0,0 +1,333 @@
/* $NetBSD: trade.c,v 1.9 2004/01/27 20:30:30 jsm 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.9 2004/01/27 20:30:30 jsm Exp $");
#endif
#endif /* not lint */
#include "monop.ext"
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()
{
int tradee, i;
char tradebuf[257];
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();
trade_p = &play[tradee];
sprintf(tradebuf, "%s, is the trade ok? ", trade_p->name);
if (getyn(tradebuf) == 0)
do_trade();
trade_p = 0x0;
}
/*
* This routine gets the list of things to be trader for the
* player, and puts in the structure given.
*/
static void
get_list(struct_no, play_no)
int struct_no, play_no;
{
int sn, pn;
PLAY *pp;
int numin, prop, 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; ) {
prop = getinp("Which property do you wish to trade? ",
plist);
if (prop == numin)
break;
else if (used[prop])
printf("You've already allocated that.\n");
else {
num_prp--;
used[prop] = TRUE;
for (op = pp->own_list; prop--; 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(the_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()
{
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(" $%d\n", tp->cash), some++;
if (tp->gojf > 0)
printf(" %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(' '), printsq(sqnum(op->sqr), TRUE);
some++;
}
if (!some)
printf(" -- Nothing --\n");
}
}
/*
* This routine actually executes the trade.
*/
static void
do_trade()
{
move_em(&trades[0], &trades[1]);
move_em(&trades[1], &trades[0]);
printf("Trade is done!\n");
}
/*
* This routine does a switch from one player to another
*/
static void
move_em(from, to)
TRADE *from, *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()
{
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;
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);
}
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--] = 0;
for (i = 0; i < N_SQRS; i++)
if (board[i].owner > player)
--board[i].owner;
player = --player < 0 ? num_play - 1 : player;
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);
}
}

21052
test_data/monop.log Normal file

File diff suppressed because it is too large Load diff