Initial revision

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

68
AUTHORS Normal file
View File

@@ -0,0 +1,68 @@
Authors of bsd-games and bsd-games-non-free
===========================================
The bsd-games package was originally created by Curt Olson
<curt@me.umn.edu> and Andy Tefft <teffta@engr.dnet.ge.com>. The games
themselves were written by many contributers to *BSD over the past
twenty years or so. Maintenance of the package was passed to me in
1997; I divided it into bsd-games and bsd-games-non-free according to
the established (DFSG/OSD) definition, following the division used for
the Debian package of 1.3. Much of the packaging has been written or
extensively modified by myself. Joey Hess <joeyh@master.debian.org>
wrote the manpages for wargames and paranoia.
Based on the source and manpages, here are the details of the people
who originally wrote the games over more than 20 years. Many of the
email addresses below are probably no longer valid. Please send any
further information you have to help improve this list.
adventure: Will Crowther, Don Woods; C port by Jim Gilloghy
arithmetic: Eamonn McManus <emcmanus@cs.tcd.ie>
atc: Ed James <edjames@berkeley.edu>
backgammon: Alan Char
banner: Mark Horton
battlestar: David Riggle <riggle.pa@xerox.arpa>, with acknowledgements to
Chris Guthrie <chris%ucbcory@berkeley.arpa>, Peter Da Silva,
Kevin Brown, Edward Wang <edward%ucbarpa@berkeley.arpa>,
Ken Arnold & Company
bcd: Steve Hayman <sahayman@iuvax.cs.indiana.edu>
boggle: Barry Brachman <brachman@cs.ubc.ca>
caesar: Rick Adams, Stan King, John Eldridge, based on algorithm
suggested by Bob Morris
canfield: Steve Levine; further random hacking by Steve Feldman,
Kirk McKusick, Mikey Olson, Eric Allman
countmail: Charles M. Hannum <mycroft@netbsd.org>
cribbage: Earl T. Cohen, Ken Arnold
dm: (unknown)
factor: Landon Curt Noll <chongo@toad.com>
fish: Muffy Barkocy
fortune: Ken Arnold (fortunes from many sources)
gomoku: Ralph Campbell (with acknowledgement to Peter Langston)
hangman: Ken Arnold
hunt: Conrad Huang <conrad@cgl.ucsf.edu>,
Greg Couch <gregc@cgl.ucsf.edu>
mille: Ken Arnold
monop: Ken Arnold
morse: (unknown)
number: (unknown)
phantasia: Edward Estes <ihnp4!ttrde!estes>, with thanks to
Chris Robertson
pig: (unknown)
pom: Keith E. Brandt
ppt: (unknown)
primes: Landon Curt Noll <chongo@toad.com>
quiz: Jim R. Oldroyd
rain: Eric P. Scott
random: Guy Harris
robots: Ken Arnold
rogue: Timothy Stoehr, Michael C. Toy, Kenneth C. R. C. Arnold
sail: Dave Riggle <riggle@ernie.berkeley.edu>,
Ed Wang <edward@ucbarpa.berkeley.edu>; Craig Leres,
Chris Guthrie
snake: (unknown)
tetris: Nancy L. Tinkham, Darren F. Provine, Chris Torek
trek: Eric Allman
wargames: (unknown)
worm: (unknown)
worms: Eric P. Scott
wump: Dave Taylor

47
BUGS Normal file
View File

@@ -0,0 +1,47 @@
Known bugs in bsd-games and bsd-games-non-free
==============================================
I know of the following bugs in bsd-games and bsd-games-non-free;
there is no need to report them if you come across them, but fixes are
welcome.
General
=======
Some games may not handle signals (especially resizing) properly.
Handling signals properly means in a way conforming to ISO C and
POSIX.1: no async-unsafe functions may be used in a signal handler if
the signal could have interrupted an async-unsafe function, and any
variable of static storage duration assigned to must be of type
volatile sig_atomic_t. (See adventure for an example of proper
handling.)
Some games may not check for errors when they should (including
allocation failure), or may return inappropriate exit statuses.
Some games may have arbitrary limits that they should not have.
Specific games
==============
Under some circumstances, hunt fails to start the hunt daemon if one
is not already running. In general, hunt needs thorough testing by
someone willing to investigate and fix bugs; at present hunt should be
considered unsupported and probably broken.
Saving in monop is completely broken. Since it assumes it can save by
writing out the whole data space from 0 to sbrk(0) and read it in to
restore, it may not be easy to fix.
Gomoku can use 16 megabytes or more of memory. (This is reported (not
by me) as NetBSD PR 3126.)
Joseph S. Myers
jsm28@cam.ac.uk
Local Variables:
mode: text
End:

3147
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

67
ChangeLog.0 Normal file
View File

@@ -0,0 +1,67 @@
10/24/93 -replace previous words file with the words file provided by
Rik Faith, faith@cs.unc.edu. This package can be found at
ftp.cs.unc.edu in /pub/faith/linux/utils/linux.words.2.tar.gz
9/30/93 - changed 'mkdir' to 'mkdir -p' in the top level Makefile so
intermediate directories will be created if they don't exist.
9/25/93 - Top level Makefile now creates the directories DESTDIR, MANDIR,
and LIBDIR if they do not exist before trying to install the
individual programs.
9/25/93 - Fixed makefiles to inherit defines from upper level makefiles.
Also fixed hard coded pathnames in .h files to be taken from the
makefiles.
9/23/93 - [bog] Modified the end of game behavior to be more intuitive.
Original behavior can be set by defining PURE in CFLAGS.
9/23/93 - [bog] Fixed a bug in bog which caused a crash at the end of
displaying the help.
"extern char *version" -> "extern char version[]"
Aren't these two equivalent??? I guess not :) Thanks Andrew
Kuchling for spotting this one.
8/25/93 - Version 1.2 Released
==============================================================================
8/25/93 - Added paranoia
8/25/93 - Added hunt
8/23/93 - Added sail
8/23/93 - Added pom
8/23/93 - Added bog
8/22/93 - Added factor
8/22/93 - Added primes
8/21/93 - Added trek
8/21/93 - Added monop
8/19/93 - Version 1.1 Semi-released
==============================================================================
8/19/93 - Added wargames
8/19/93 - [robots] Fixed robots screen restore bug.
8/19/93 - Added snake
8/19/93 - Added caesar
8/19/93 - Added cribbage
8/18/93 - Found a man page for number
8/17/93 - Version 1.0 Released.
==============================================================================

186
INSTALL Normal file
View File

@@ -0,0 +1,186 @@
Installation instructions
=========================
Packaging
=========
If packaging bsd-games or bsd-games-non-free for a Linux distribution,
please read the PACKAGING file for further information after this one.
Others who wish to install it under a packaging system, or rebuild it
automatically and without interactive configuration, may also find
this file useful.
Non-free games
==============
These installation instructions apply to both bsd-games and
bsd-games-non-free. bsd-games-non-free contains rogue, which it seems
cannot be sold for profit: the rest of the games are under the
standard BSD distribution conditions, or very similar ones (phantasia
is public domain, i.e. not copyrighted). As of version 2.2 and later,
the bsd-games-non-free package unpacks conventionally into a directory
of its own. It can be built separately from bsd-games, or in the same
source directory: to do the latter, move those files and directories
that are in bsd-games-non-free but not bsd-games into the
bsd-games-VERSION directory before building. If you are building
bsd-games, cd to boggle and decide if you want -DNEW_STYLE or not --
see boggle/README.linux for more information. If you are in a hurry,
don't worry about it ... it really is more of an aesthetic thing.
Prerequisites
=============
You need gcc, libc5 (version 5.4.5 or later) or libc6, and ncurses
(any reasonably recent version). Older versions of ncurses may work
(but are much more buggy), and BSD curses / termcap just might work
(but is obsolete), but these are completely unsupported; even with
recent ncurses versions you could run into problems with some games
dependent on the version of ncurses; if so, get a debugging version of
ncurses (libncurses_g.a), link with -lncurses_g instead of -lncurses,
and good luck bug-hunting. If the display gets confused in ordinary
use (as opposed for example to after resizing the window), this might
be a bug in the game, but is probably a bug in ncurses. You also need
some sort of lex and yacc; by default this package will use flex and
bison, but byacc will probably work as well. Libc5 versions before
5.4.5, or libc4, will not work since they don't have the BSD <err.h>
error reporting functions.
The makefiles require GNU make; if you have a strange system on which
`make' is not GNU make you can use it under some other name since
$(MAKE) is used where appropriate. The configure script assumes that
/bin/sh is a POSIX.2 shell (bash is known to work; current versions of
ksh and ash should be OK but I haven't tested them); it can be run
manually with `bash configure' or similar if /bin/sh is not a POSIX.2
shell. It uses the POSIX.2 printf utility (in GNU sh-utils, and a
builtin in bash 2.02) to avoid depending on echo -n.
I am not aware of any dependence on the version of gcc used, although
it would be advisable to use gcc 2.7.2.1 or later (or use
-fno-strength-reduce). Sufficiently recent egcs snapshots (those with
global CSE), and egcs releases 1.1 or later, may produce spurious
warnings about uninitialized variables because of limitations in the
code to detect this, but this does not affect the correctness of the
compiled code. Some glibc versions may produce many warnings in the
system headers; these can be ignored.
Some man pages may look better with the tmac.doc macros from NetBSD,
rather than the older ones distributed with groff. If any man pages
look funny or appear to have words missing (especially the program
name or a reference to NetBSD), having older tmac.doc may be the
cause.
Security
========
See the SECURITY file for a discussion of security issues about the
BSD games.
Building and installation
=========================
1. cd to the top level directory in the source distribution, i.e. the
directory that contains this file. There is not yet any support
for building in a directory other than the source directory.
2. Run `./configure' and configure the installation to your liking.
There may be some games you don't want to build because you have
them from elsewhere; for example, there is another fortune package
(fortune-mod) available, and factor is included in GNU sh-utils as
of version 1.12q. Also banner is in util-linux. You can specify
particular games you do not want built before specifying the list
of games to build (which will default to all those available,
except those you have excluded).
The filesystem structure used defaults to that the the Filesystem
Hierarchy Standard (FHS), version 2.0. If you are using the older
FSSTND 1.2, or a newer FHS, or wish to install into /usr/local,
check the paths given and make changes as appropriate.
3. Type `make'. You can probably ignore compiler warnings, although
most should be fixed in this release. If you are building on a 64
bit architecture, you might want to look over the warnings and let
me know about any that are normally significant in such cases.
Some versions of gcc (e.g. egcs 1.1) give many `missing
initializer' warnings; these are harmless.
At the start of the build, their will be many `No such file or
directory' warnings from make. Ignore these as long as make does
not stop because of them: these refer to dependency files that
make can regenerate for itself. See `Automatic Dependencies' in
the GNU Make manual for details.
In the unlikely event of an internal compiler error, the build
system supports generating the files of preprocessor output
required for a bug report: if the error occurs while compiling
`foo/bar.c', then `make foo/bar.i' will put the preprocessor
output in `foo/bar.i', suitable for sending in a bug report along
with details of compiler version and options used. You may,
however, wish to minimise the testcase before sending a bug
report, if you have the time to do so.
4. Save copies of any old versions of games you like and their
datafiles, until you know that the new versions work.
5. Become root. (If, as an ordinary user, you are installing under
your home directory, and have chosen not to set owners and groups
on the installed files, there is of course no need to do this.)
6. Type `make install'. If you want the installed binaries to be
stripped, use `make install-strip' instead. This saves disk
space, but means that you cannot debug the installed binaries.
7. If you had an old installation of bsd-games, check for file
locations that have changed. You will probably want to remove old
executables and static data (formerly defaulting to installation
in /usr/games/lib), and replace any empty score files that have
been installed with your old ones (checking the permissions).
The default locations changed again in 2.2, to those mandated by
the new FHS 2.0 - manpages in /usr/share/man, variable data in
/var/games. In addition, huntd's default location has changed
from /usr/sbin back to /usr/games and the location for dm to keep
hidden games has changed from /usr/libexec/dm to
/usr/lib/games/dm.
In version 2.4, the recommended permissions on the directory for
sail, if you installed it setgid, changed from 0775 to 2770; you
may need to adjust the permissions manually if you had a previous
installation of version 2.3.
8. You may wish to do something with the BSD Users' Supplementary
Documents for trek and rogue, in trek/USD.doc/trek.me and
rogue/USD.doc/rogue.me. You can look at them on a text terminal
with `nroff -me' (piped to your pager), or format in PostScript
for printing with `groff -me -Tps'.
9. `make distclean' will restore the source directory to the original
unpacked state. The automatically generated dependency files
include paths to system headers, including those in gcc's internal
header directory: if you have changed your compiler or library
headers between building bsd-games and cleaning up, you can use
`make distclean nodep=true' to avoid this causing problems.
`make clean' will restore the sources to the state just after
configuration.
Further information
===================
Some subdirectories have README.linux files. If you are still having
trouble with a program, check this file first -- it may contain some
helpful hints, or information about further configuration options.
See TODO for information on what needs to be improved in this package;
you may want to volunteer for some of the things in there.
The file BUGS lists known bugs. The README file discusses how to
produce useful bug reports.
Joseph S. Myers
jsm28@cam.ac.uk
Local Variables:
mode: text
End:

96
Makeconfig.in Normal file
View File

@@ -0,0 +1,96 @@
# Makeconfig.in - configuration included in Makefiles after substitution
# If some variables are unexpanded in Makeconfig, this shouldn't be a
# problem, it will be because they weren't configured since the relevant
# games weren't being built.
# Source directory
SRCDIR := @srcdir@
# Build directories
BUILDDIRS := @build_dirs@
# Installation prefix
INSTALL_PREFIX := @install_prefix@
# Games directory
GAMESDIR := @gamesdir@
# Daemon directory
SBINDIR := @sbindir@
# Other binaries directory
USRBINDIR := @usrbindir@
# Manual pages, section 6
MAN6DIR := @man6dir@
# Manual pages, section 8
MAN8DIR := @man8dir@
# Manual pages, section 5
MAN5DIR := @man5dir@
# Constant data (arch-dependent)
LIBDIR := @usrlibdir@
# Constant data (arch-independent)
SHAREDIR := @sharedir@
# Variable data
VARLIBDIR := @varlibdir@
# Directory for hidden games (dm)
LIBEXECDIR := @libexecdir@
# Installation commands, with install -c -o whatever -s etc.
INSTALL_BINARY := @install_binary@
INSTALL_SCRIPT := @install_script@
INSTALL_SCORE_GAME := @install_score_game@
INSTALL_DAEMON := @install_daemon@
INSTALL_MANUAL := @srcdir@/install-man
INSTALL_DATA := @install_constdata@
INSTALL_VARDATA := @install_vardata@
INSTALL_DM := @install_dm@
INSTALL_SAIL_DIR := @install_sail_dir@
# Is INSTALL_VARDATA actually needed (for games that start with non-empty
# scorefile?)
# For games which can start with empty scorefile we do:
INSTALL_SCORE_FILE := @srcdir@/install-score
# Definitions of INSTALL_* that may have -s added
# This first one should no longer be needed
DEFS_TO_PASS := INSTALL_BINARY="$(INSTALL_BINARY)" \
INSTALL_SCORE_GAME="$(INSTALL_SCORE_GAME)" \
INSTALL_DAEMON="$(INSTALL_DAEMON)" INSTALL_DM="$(INSTALL_DM)"
# For the top level install-strip target
DEFS_TO_PASS_STRIP := INSTALL_BINARY="$(INSTALL_BINARY) -s" \
INSTALL_SCORE_GAME="$(INSTALL_SCORE_GAME) -s" \
INSTALL_DAEMON="$(INSTALL_DAEMON) -s" INSTALL_DM="$(INSTALL_DM) -s"
# srcdir/hide-game or :
HIDE_GAME := @hidegame@
# Compilation details
CC := @cc@
OPTIMIZE := @optimize_flags@
WARNING := @warning_flags@
CFLAGS := $(OPTIMIZE) $(WARNING) @other_cflags@
LDFLAGS := @other_ldflags@
NCURSES_LIB := @ncurses_lib@
NCURSES_INCS := @ncurses_includes@
BASE_INCS := -Iinclude $(NCURSES_INCS)
BASE_LIBS := @base_libs@
YACC := @yacc@
LEX := @lex@
LEX_LIB := @lex_lib@
# More paths
PAGER := @pager@
# Individual games
ATC_DIR := @atc_dir@
ATC_SCOREFILE := @atc_scorefile@
BATTLESTAR_SCOREFILE := @battlestar_scorefile@
BOGGLE_DIR := @boggle_dir@
CANFIELD_SCOREFILE := @canfield_scorefile@
CRIBBAGE_INSTRFILE := @cribbage_instrfile@
CRIBBAGE_SCOREFILE := @cribbage_scorefile@
FISH_INSTRFILE := @fish_instrfile@
FORTUNE_TYPE := @fortune_type@
HANGMAN_WORDSFILE := @hangman_wordsfile@
MONOP_CARDSFILE := @monop_cardsfile@
PHANTASIA_DIR := @phantasia_dir@
QUIZ_DIR := @quiz_dir@
ROBOTS_SCOREFILE := @robots_scorefile@
ROGUE_SCOREFILE := @rogue_scorefile@
SAIL_SCOREFILE := @sail_scorefile@
SAIL_DIR := @sail_dir@
SNAKE_SCOREFILE := @snake_scorefile@
SNAKE_RAWSCOREFILE := @snake_rawscorefile@
TETRIS_SCOREFILE := @tetris_scorefile@
WUMP_INFOFILE := @wump_infofile@

14
Makefile.bsd Normal file
View File

@@ -0,0 +1,14 @@
# $NetBSD: Makefile,v 1.16 1997/10/10 09:39:04 lukem Exp $
# @(#)Makefile 8.3 (Berkeley) 7/24/94
# Missing: ching dungeon warp
# Moved: chess
# Don't belong: xneko xroach
SUBDIR= adventure arithmetic atc backgammon banner battlestar bcd boggle \
caesar canfield countmail cribbage dm factor fish fortune gomoku hack \
hangman hunt larn mille monop morse number phantasia pig pom ppt \
primes quiz rain random robots rogue sail snake tetris trek wargames \
worm worms wump
.include <bsd.subdir.mk>

16
Makefile.inc.bsd Normal file
View File

@@ -0,0 +1,16 @@
# $NetBSD: Makefile.inc,v 1.9 1997/11/20 00:12:30 mrg Exp $
# @(#)Makefile.inc 8.1 (Berkeley) 5/31/93
.if defined(HIDEGAME) && defined(PROG)
BINDIR?= /usr/games/hide
BINGRP?= games
.if defined(SETGIDGAME)
BINMODE?= 2550
.else
BINMODE?= 550
.endif
SYMLINKS+= dm /usr/games/${PROG}
.else
BINDIR?= /usr/games
.endif
WARNS?= 1

252
NEWS Normal file
View File

@@ -0,0 +1,252 @@
NEWS for bsd-games and bsd-games-non-free
=========================================
This file contains a summary of changes in each version of bsd-games
and bsd-games-non-free after 1.3. For fuller details, see ChangeLog
and ChangeLog.0.
As well as reading this summary, it is a good idea to reread the
INSTALL file whenever installing a new version, to check for any
changes in installation instructions. Packagers should also reread
the PACKAGING file each version (or do a diff between the old and new
versions of the package and read that).
Version 2.5
===========
* New build system, using a single project Makefile (autogenerated)
that includes makefile fragments from subdirectories, and uses GNU
Make's automatic dependency generation to generate dependencies
automatically, rather than recursive make. See Peter Miller's paper
`Recursive Make Considered Harmful'
<http://www.canb.auug.org.au/~millerp/rmch/recu-make-cons-harm.html>
for reasons why this is better than recursive make. This should make
no difference to normal users, but if you modify the sources note that
you will need to rebuild from the top directory, and you may find that
the dependencies are now accurate whereas formerly they were
incomplete. The automatic dependency generation causes the build to
start with about 300 `no such file or directory' warnings, which
should be ignored: these refer to the dependency files which GNU Make
will then automatically generate.
* Should work with glibc 2.1 (at least, version 2.0.96 on x86, which
is what I've tested). See the ChangeLog for an explanation of the
problem previous releases had with glibc 2.1.
* Boggle is now in the main bsd-games package - Paul Janzen checked
with the original author, who confirmed that the BSD licence
superseded the old non-free one. bsd-games-non-free now only contains
rogue.
* Other minor changes.
Version 2.4
===========
* Various minor bug fixes and improvements (some from OpenBSD, thanks
to Paul Janzen <pjanzen@foatdi.harvard.edu>).
* Sail directory can now be non-world-accessible (mode 2770 root.games
or similar). This may improve security, since it means users cannot
tamper with sync files their sail process creates.
* Rogue buffer overrun fix. An audit is still needed.
* dm now ignores the environment variable TZ when deciding at what
times games can be played. (This only affects you if you are using dm
to control at what times games can be played, and not then if you are
using libc 5.4.45 or 5.4.46 (which completely ignore TZ in setgid
programs rather than checking the validity of any filename given as
glibc does).)
* All games updated from NetBSD-current of 1998-08-30 (minor changes;
some more of my changes have been merged back into NetBSD).
Version 2.3
===========
* A possible temporary file security bug in sail fixed.
* Countmail is back, with a licence (apparently the standard NetBSD
one), since it has one in NetBSD-current of 1998-08-19.
* All the other games updated from NetBSD-current of 1998-08-19 (minor
changes).
* Other minor changes.
* Version 2.2 was never properly released, since the upload to sunsite
was truncated and the sail hole was found before the truncated file
had been removed or the release put in place on tsx-11.
Version 2.2
===========
* Another bug-fix release.
* This version includes security fixes from OpenBSD.
* This release is believed year 2000 compliant. Please see the year
2000 statement in the file YEAR2000 for details and disclaimer.
* Paranoia has been removed from bsd-games-non-free, since it has no
clear licence at all, and being derived from a magazine article it is
not clear it was ever legally distributable. Anyone wanting to
resurrect it in a separate package would need to investigate the
copyright on the magazine article as well as getting a proper licence
from the author.
* Countmail has been removed from bsd-games because of the lack of a
licence.
* All other games updated from NetBSD-current of 1998-07-27 (very
minor changes).
* Default paths now follow FHS 2.0 - enter the paths you want when
running configure if you are using the FSSTND 1.2.
* You can now easily specify games you don't want built when running
configure.
* All games that can invoke pagers handle PAGER in the way specified
by POSIX.2 for standard programs that invoke pagers.
* Rogue bug fix from Bill Lash <lash@tellabs.com>.
* Other bug fixes.
* Information for those packaging bsd-games or bsd-games-non-free for
a Linux distribution is in the file PACKAGING.
Version 2.1
===========
* This is mainly a bug-fix release.
* All games updated to NetBSD-current as of 1998-03-21 (except for
paranoia). The changes are mostly minor, replacing warning fixes
local to bsd-games with ones now in NetBSD.
* Some bugs fixed, and most of the additional warnings given by the
current egcs snapshot fixed as well.
* Configuration / installation change - to strip the installed
binaries, use `make install-strip' instead of `make install'; this
replaces the configuration option for `make install' to strip the
installed binaries.
* Manpages for wargames and paranoia, thanks to Joey Hess
<joeyh@kitenet.net>.
* Battlestar save file name can be chosen at runtime, and defaults to
`.Bstar' instead of `Bstar' for cleaner directory listings.
Version 2.0
===========
* All games updated to NetBSD-current as of 1997-12-12 (except for
paranoia). Hunt and boggle are now based on the NetBSD versions.
* Many bugs fixed.
* Added countmail.
* Better libc6 support - adventure should now work.
* No longer uses libbsd with libc5.
* Nearly warning-free compile with -Wall -W -Wstrict-prototypes
-Wmissing-prototypes.
* Hunt now uses internet domain sockets (untested).
Version 1.5
===========
* All games updated to NetBSD-current as of 1997-07-12 (except for
bog, hunt and paranoia).
* Added adventure, banner, dm, phantasia, pig, quiz, random and rogue.
(Rogue is in bsd-games-non-free only).
* BETA level libc6 support. (It may not yet compile, but should be
nearer to compiling with libc6 than version 1.4.)
Version 1.4
===========
* Fish, fortune and hangman updated to the versions in NetBSD-current.
* Public release.
Version 1.3.4beta
=================
* Bug fix in backgammon.
* Backgammon, battlestar, bcd, caesar, canfield, cribbage and factor
updated to the versions in NetBSD-current. As a side-effect, caesar
now installs a `rot13' script.
* Tetris score file now defaults to tetris-bsd.scores for consistency
with using tetris-bsd in the names of files installed from tetris.
(The rationale of this is that there is more than one Tetris game and
this one should not presume to be the one that takes the
/usr/games/tetris name; that should be a decision for the
administrator, who can reasonably install more than one Tetris game.)
Nor should other files such as the man page or score file potentially
conflict with other Tetris games. Of course, you can configure the
package to use the old score file name (or any other) if you want.
Version 1.3.3beta
=================
* Non-free package now contains all the files required to build on its
own. It can now be built on its own, or in the same source tree as
bsd-games; the files that appear in both are exact duplicates.
* Bug-fixes in backgammon and sail.
Version 1.3.2beta
=================
* Non-free games (bog and paranoia) now distributed separately -
unpack both source packages together before configuring if you want to
build them.
* Configuration script improved: now the default list of games to
build is the list of subdirectories, and you can configure the exact
paths to score files and data files for individual games using it - so
they are always correctly substituted in the manpages.
* Bug-fixes in backgammon, snake and worm.
* Arithmetic and atc updated to the versions in NetBSD-current.
Version 1.3.1beta
=================
* Now works with libc 5 ;-).
* Debian patches from Joey Hess <joeyh@master.debian.org> mostly
integrated up to Debian version 1.3-7.
* New ports of tetris and gomoku, thanks to David Frey
<david@eos.lugs.ch>.
* Distributed as source only.
* Many bug-fixes to battlestar.
* Configuration script, now substitutes correct paths in manpages.
* Defaults hopefully closer to FSSTND/FHS.
* Builds with ncurses by default. Curses/termcap are obsolete and no
longer supported (not that this package is supported anyway ;-)).
Local Variables:
mode: text
End:

140
PACKAGING Normal file
View File

@@ -0,0 +1,140 @@
Packaging bsd-games and bsd-games-non-free
==========================================
This file contains some information intended for those packaging
bsd-games or bsd-games-non-free for a Linux distribution. It is
presumed that you have read INSTALL first, and that you have the
competence in the POSIX shell required to read and understand the
configure script. This information may also be useful to people
building their own systems, who wish to rebuild the whole system
automatically or who use a packaging system for locally built
software.
The configuration and build of bsd-games has two features designed to
facilitate packaging:
1) Installation prefix.
The configure script allows you to choose an installation prefix (by
default empty) that is prepended to all paths used for installation,
but not those built into the executables (this is similar to the
install_root of glibc, and DESTDIR in some packages, but is chosen at
configure time). The package would then be built in some way from
this directory, and the contents would end up in the root of the
target system. If used, this prefix must be an absolute path.
2) config.params to change configuration defaults.
Although the configuration script is by default interactive (although
it does not need a terminal), it can also be used non-interactively.
If a file `config.params' exists in the source directory, it will be
sourced by the configure script. If this file (which can be an
arbitrary shell script) sets `bsd_games_cfg_non_interactive' to `y',
then the default answers to all questions will be taken without
interaction. If this sets `bsd_games_cfg_FOO' to `BAR' then the
default value for configuration parameter `FOO' will become `BAR'
instead of whatever default the script would otherwise give. You can
find the names and meanings of the configuration parameters by reading
the configure script; they are not otherwise documented.
Issues for packagers
====================
Please read the security warnings in SECURITY. There is a potential
trade-off between security and functionality present, and you may wish
to choose a potentially more secure default and allow the sysadmin to
change permissions if they are in an environment (for example, a home
system with only trusted users) where the functionality is preferred,
while ensuring such changes persist across upgrades.
You may wish to include auxiliary documentation for users, such as the
BSD Users' Supplementary Documents for trek and rogue
(trek/USD.doc/trek.me and rogue/USD.doc/rogue.me, or formatted
versions thereof), the AUTHORS and THANKS files, and the year 2000
statement YEAR2000. Note that the trek manpage contains a reference
to /usr/doc/trek, which should be updated to point to where you put
trek.me or a formatted version. As noted below, it is better to
update trek.6.in (before configure) than trek.6.
Assuming you distribute source for your package (I do not believe any
of the games have licences requiring this), and separate your patches
from the original source .tar.gz files (whether in separate files or
in a single file source package including them as separable
components), arranging the building of the source so that your patches
add a `config.params' as described above, and do any other necessary
changes to `configure' or other source files, and so that the build
process runs configure non-interactively and then builds the package,
makes it easier for readers to see how you have packaged it than
running configure interactively and including the generated files in
your patch.
Andries Brouwer has noted more than once on linux-kernel (and
elsewhere) that some packagers (for various software and documentation
used under Linux):
(a) Do not send their patches to upstream maintainers, so that
improvements and bug fixes stay in some distributions, which may need
to discover them independently, and do not come to benefit other
users.
(b) Keep applying their same patches to new versions of the source as
long as they apply without error, even though they may no longer be
needed or even be harmful.
If you have patches that are needed for the package to build (in a
supported environment: libc 5.3.12 (or any Linux libc before 5.4.5)
and glibc 1.99 (or other old snapshots) are not supported although the
latter may work; nor is BSD curses/libtermcap or ncurses before 1.9.9e
(== 3.0 shared library version)) or to fix bugs (again in a supported
environment) or that provide enhancements other than conforming to
distribution-specific policy, please send them to me (unidiffs
preferred; see notes on bug reporting and sending patches at the end
of README). Do not assume that old patches should be applied to new
versions; check that the problem they are supposed to fix is still
present first.
Warnings
========
If distributing bsd-games, it is your responsibility to check that the
licences on the games you distribute permit what you wish to do with
them, and that you are providing accurate information on the licences
to your users. Likewise it is your responsibility to carry out
whatever audits you deem necessary on the code, and to include such
warnings or information (about security and otherwise) for the end
user as you see fit. Please read the disclaimers in the individual
source files.
Some of the games may contain material, actions or language that in
some jurisdictions may be prohibited or considered unsuitable for
minors; this includes but is not limited to the offensive fortunes.
It is your responsibility to determine and apply any restriction on
your distribution of the games that may be necessary in consequence.
Notification of new versions
============================
If you want to receive notification of new versions by email, but do
not currently receive this notification, please let me know.
A note on terminology and credit
================================
I am not the `upstream author' of the games packaged here; for an
incomplete list of the authors see AUTHORS, but do not give me this
credit I do not deserve at the expense of the true authors. Rather I
am the `upstream maintainer' of the bsd-games and bsd-games-non-free
packages (upstream relative to distributions), and upstream of me is
NetBSD, who also are maintainers of the games, but not for the most
part authors. Nor am I the creator of the bsd-games package, although
much the current form of the packaging and many of the porting changes
are mine: the package was created by Curt Olson and Andy Tefft, and
passed to me after it had been idle and unmaintained for some years.
Any system that provides fields for recording this sort of information
should distinguish these concepts, and the different fields should be
filled in correctly. Please consider where credit is due and credit
the authors of the games accordingly: if you find the names of authors
where not known and listed in AUTHORS, or up-to-date contact details
for authors listed there, please send me the details so they can
receive their due credit in future versions, and thanks from any
appreciative users.

102
README Normal file
View File

@@ -0,0 +1,102 @@
README for bsd-games
====================
This is the bsd-games package for Linux, containing ports of all the
games from NetBSD-current that are free in the usual (DFSG/OSD) sense
(i.e. modified and unmodified versions can be freely distributed,
including for profit). NetBSD-current contains three other games,
rogue, hack and larn. Rogue has a standard BSD licence, but with an
additional contradictory licence that does not allow for-profit
distribution; hack and larn have no licence at all. If you want
rogue, get the bsd-games-non-free package (which should be on sunsite,
but not tsx-11), and read the README.non-free that it contains: rogue
is being distributed separately, and hack and larn not distributed at
all in this Linux port, in the absence of definite confirmation of
what licences really apply. A game not from NetBSD, paranoia, was in
earlier versions of bsd-games-non-free (and bsd-games 1.2 and 1.3) but
has been removed because of the lack of a clear licence.
The games are mostly not enhanced from the NetBSD versions, but many
bugs are fixed.
The games should work with ncurses (any reasonably recent version).
They might also work with BSD curses/termcap, but this is not tested
by me. They should work with both libc5 (version 5.4.5 or later -
earlier versions won't work) and libc6 (glibc 2). Note however that I
don't test all possible combinations of libraries for each release, so
tell me if some versions don't work. For details of prerequisites,
see INSTALL.
For installation instructions, see the file `INSTALL'. Some games
have `README.linux' files you may wish to read.
The statement of year 2000 issues associated with bsd-games and
bsd-games-non-free is in the file `YEAR2000'.
This package contains the following games:
adventure: the original adventure by Crowther and Woods
arithmetic: arithmetic quiz/speed test
atc: air traffic control
backgammon: backgammon
banner: display a message in big letters
battlestar: adventure game on a battlestar
bcd: outputs text in an antique form
boggle: boggle
caesar: reads fortunes from the game fortune, also some internet posts
canfield: curses-based solitaire
countmail: tell you how much new mail you have
cribbage: cribbage
dm: dungeon master, regulates games playing
factor: factor a number
fish: go fish
fortune: displays a random silly message
gomoku: gomoku
hangman: guess the word before it is too late
hunt: hunt each other in a maze (multiplayer -- great)
mille: mille borne against the computer
monop: monopoly
morse: output morse code
number: output the English text for a number
phantasia: interterminal fantasy game
pig: output text in Pig Latin
pom: display the phase of the moon
ppt: outputs text in another antique form
primes: generate primes
quiz: random knowledge tests
rain: attempts to create a rain drop effect (best at 9600 baud)
random: random lines from a file or random numbers
robots: well... avoid the robots
sail: sail your ship into battle
snake: grab the cash and avoid the snake and exit
tetris: tetris
trek: We come in peace, shoot to kill. It's worse than that, he's
dead Jim. Ye cannot change the laws of physics. It's life
Jim, but not as we know it. There's Klingons on the starboard
bow ...
wargames: would you like to play a game?
worm: eat the numbers without running into anything
worms: random worms scurrying across your screen
wump: hunt the wumpus
If you have questions about bsd-games or bsd-games-non-free you can
contact me at <jsm28@cam.ac.uk>. Bug reports should state the
versions of ncurses and libc used, unless clearly not relevant (e.g.,
bugs in data files, or where you have an analysis and patch). If you
want to be informed by email of new releases when they come out,
please let me know.
Known bugs are listed in the file BUGS; please do not send bug reports
for bugs listed there, but patches that fix them are welcome.
For patches, I prefer unidiffs (use `diff -u OLD NEW', or `diff -ruN
OLD-DIRECTORY NEW-DIRECTORY'), but if your diff cannot produce them
then context diffs are OK. Please remember to include details of the
bug and your analysis of the problem if you are sending a patch; I
have ported the code from NetBSD to Linux, but may not be familiar
with the workings of any particular program, whereas you will be if
you have been tracing and fixing a bug. The gcc info manual contains
a discussion of how to produce good bug reports.
Joseph S. Myers
jsm28@cam.ac.uk

77
SECURITY Normal file
View File

@@ -0,0 +1,77 @@
Security of bsd-games and bsd-games-non-free
============================================
Some games maintain system-wide score files or logs, and need
appropriate privileges to write to these files. They can get these
privileges by being installed setgid games, or through the files being
world writable. If they do not have these privileges, they will run,
but fail to update the score files. Most of the games were written at
a time when security was not considered important; therefore, making
games setgid has in the past meant that users can get a shell with gid
games, and possibly also get access to the accounts of other games
players by corrupting the score files. (This will also apply to many
more modern games that are badly written.)
In version 2.2, security fixes from OpenBSD have been applied: most of
the games that have score files will open them on startup, and then
drop any setgid privileges completely (including the saved gid). This
limits the effect of a cracked game to corruption of its score file.
It should be somewhat safer now to make games setgid games than in
versions 2.1 and earlier, but probably not completely safe; phantasia,
sail, rogue and tetris do not currently handle their score files in
the above way, and so should be considered the most dangerous to
install setgid. If you are auditing these games, phantasia, sail,
rogue and tetris should be considered the most important to audit.
You should, of course, only install the games setgid if this is in
line with system security policy. Games should not be installed
setuid, since if a setuid game is cracked this allows games to be
replaced with trojans. Games should not be installed setgid to a
system group such as `root' or `daemon'. In some environments, an
acceptable alternative may be not to give the games any special
privileges, but to put trusted users in the games group.
An option is to use the `dungeon master' dm to regulate games playing.
I believe this is safe; games that do not need to run setgid drop the
setgid privileges they get from dm on startup. If dm is setgid, but
the games that access score files are not, then they will keep their
setgid privileges from dm; note that in this case it does not make
sense for dm to be setgid to some gid other than the one (normally
`games') with write access to the score files.
***********************************************************************
* *
* DO NOT INSTALL ANY GAMES SETUID, ONLY SETGID. *
* *
* INSTALLING GAMES SETGID GAMES MIGHT ENABLE TO GET SHELLS WITH GID *
* GAMES. *
* *
* WHERE GAMES READ A SCORE FILE, IF A USER CAN CORRUPT THIS FILE IT *
* MIGHT IN SOME CASES MEAN THEY CAN GET ACCESS TO THE ACCOUNTS OF *
* OTHER USERS PLAYING THAT GAME. *
* *
* IF IN DOUBT, CHOOSE THE DEFAULT OPTIONS FOR PERMISSIONS AND DO *
* WITHOUT SCOREFILES. *
* *
* THESE GAMES COME WITH NO WARRANTY. *
* *
***********************************************************************
If you are compiling these games on an operating system other than
Linux, be warned that they rely for their security on
`setregid(getgid(), getgid())' dropping all setgid privileges
permanently, _including the saved gid_. On some operating systems
this may fail to drop the saved gid (and indeed such operating systems
may provide no way for a process not running as root to revoke
privileges permanently); in such a case, bugs in a game may provide
access to the games group rather than merely to to that game's score
file.
Joseph S. Myers
jsm28@cam.ac.uk
Local Variables:
mode: text
End:

66
THANKS Normal file
View File

@@ -0,0 +1,66 @@
Credits and acknowledgements for bsd-games and bsd-games-non-free
=================================================================
For details of authors of the games and maintenance of the bsd-games
and bsd-games-non-free packages, see AUTHORS. The following are
further credits for people who have helped improve the package; thanks
also to those who have reported bugs and so helped us improve the
package, and to those who have similarly contributed to the games in
*BSD over the years. Please help me to repair any errors or omissions
in this list.
For recent work (since 1.3), thanks to:
Joey Hess <joeyh@master.debian.org>
For the Debian patches, which covered what was needed to make the games
compile with current libraries, provided many bug fixes and showed
where I needed to do things like parametrise manpages. Also many other
bug reports and fixes, and manpages for wargames and paranoia.
David Frey <david@eos.lugs.ch>
For the ports of tetris and gomoku.
Bill Lash <lash@tellabs.com>
For tracking down and fixing a bug in rogue.
Paul Janzen <pjanzen@foatdi.harvard.edu>
For work on the OpenBSD games, including supplying improvements that
could be applied to the Linux port, and merging NetBSD changes into
OpenBSD so making it easier to extract his and other OpenBSD changes
to include in the Linux port. Also for checking the licence of
boggle, so it could be included in the main bsd-games package.
Hubert Feyrer <hubertf@netbsd.org>
For timely responses to my NetBSD PRs, merging the Linux changes
back into NetBSD.
For the original bsd-games package (versions up to 1.3):
Special Thanks to:
Andy Tefft (teffta@engr.dnet.ge.com)
For porting backgammon, canfield, fortune, and number. Andy also was a
big help in organizing this project, and in getting the ball rolling in
the early stages.
Thanks also to:
Ross Becker (beckerr@pyrite.som.cwru.edu) - working on hunt.
jyanowit@orixa.mtholyoke.edu - backgammon bug fix.
Andrew Kuchling (fnord@binkley.cs.mcgill.ca) - bog bug fix.
Rik Faith (faith@cs.unc.edu) - words file for hangman and bog.
For authors and acknowledgements for the original BSD games, see
AUTHORS.
Local Variables:
mode: text
End:

69
TODO Normal file
View File

@@ -0,0 +1,69 @@
TODO list for bsd-games and bsd-games-non-free
==============================================
Please let me (jsm28@cam.ac.uk) know if you're interested in doing any
of these, or have done work on them, so we can avoid duplication of
effort. The order of entries is just the order they were added in, not any
priority order.
The file BUGS lists known bugs; you may wish to work on some of
those. The issues listed there are not included in this list.
1997-04-29 - Improve security of games when running setgid. Most of
this has been done, through adopting changes from
OpenBSD, but a thorough audit is needed - see SECURITY.
There are rumours of the games having been audited by the
Linux Security Audit Project (see linux-kernel archives
and Alan Cox's diary at
<URL:http://roadrunner.swansea.uk.linux.org/alan.shtml>)
but I have received no patches.
1997-04-29 - Fix compilation warnings with increasingly strict warning
options. -Wwrite-strings (and general use of const) is
currently being worked on.
1997-04-29 - Get changes (at least the bug-fixes) merged back into NetBSD.
Various patches for specific bugs have been sent in and
applied: more still needs to be done, and some patches
are currently waiting in their bug tracking system.
1997-05-01 - Games with scorefiles should lock them when updating them.
1997-07-15 - Get distribution permission for hack and larn. Get
licence of rogue clarified. (See NetBSD PR 5850.)
1998-07-28 - Support building in a directory other than the source directory.
1998-08-18 - Fix whatever makes rogue need -fwritable-strings. This
seem to be various arrays of struct id being initialised
with constant strings, but then being modified in the
course of saving and restoring. Only object.c needs to
be compiled with -fwritable-strings.
1998-08-27 - Convert the games that use termcap to use curses.
Currently these are backgammon, rain, snake, tetris and
worms. Somewhat hacked versions of rain and worms that
use curses are distributed as test programs with ncurses;
these might just possibly be useful.
1998-08-27 - If we build a game that links to another game's manpage,
but don't install the other game, then we get a dangling
symlink or .so for the manpage.
1998-08-27 - Merge in improvements from OpenBSD.
1998-08-27 - Fix warnings with -Wl,--warn-common (i.e., variables should be
declared extern in the header, and defined non-extern
exactly once).
1998-09-04 - dm should not access the utmp file directly.
1998-09-11 - Move building of the manpages and headers in which
configuration variables are substituted from the
configure script into the Makefiles.
Local Variables:
mode: text
End:

36
YEAR2000 Normal file
View File

@@ -0,0 +1,36 @@
YEAR 2000 STATEMENT FOR BSD-GAMES AND BSD-GAMES-NON-FREE
========================================================
The BSD games, and the Linux port thereof, come with NO WARRANTY, to
the extent permitted by applicable law; see the disclaimers in the
source files for details. These games are not suitable for use in
mission-critical situations. The information given below is for
information only, and the maintainer can accept no liability for any
damage that may be caused by any defect in this software or inaccuracy
in the statement below. (If you bought this software from a
distributor, they may offer a warranty; contact them for any details
of this, or if you want copies of any year 2000 statements on headed
notepaper.)
The BSD games are only one piece of software on a Linux system, and
their year 2000 behaviour must be considered in conjunction with that
of other software on the system; in particular, the C runtime library
(including the math library), the ncurses library, the lex library,
and the kernel, functions of which may be used at runtime, and the
complier, binary utilities, make, yacc, lex and header files used to
compile the BSD games. I can provide no information concerning the
compliance of these components, or how any non-compliance might affect
the compliance of the BSD games.
To the best of my knowledge, there are no date-related operations in
any of the BSD games, in bsd-games and bsd-games-non-free versions 2.2
or later, which will handle the year 2000 incorrectly; please see the
disclaimer above. Earlier versions are known to have problems; in
particular, the game with the greatest date dependence, pom (which
determines the phase of the Moon), may handle the year 2000
incorrectly in earlier versions. However I cannot vouch for the
accuracy of the algorithm used by pom over any particular timescale,
and for accurate information on the phases of the Moon you are advised
to consult the Astronomical Almanac or some other reputable source.
Any further date-related bugs that are found and reported _may_ be
fixed in the ordinary course of subsequent releases.

16
adventure/Makefile.bsd Normal file
View File

@@ -0,0 +1,16 @@
# $NetBSD: Makefile,v 1.7 1998/08/01 23:02:35 hubertf Exp $
# @(#)Makefile 8.1 (Berkeley) 6/12/93
PROG= adventure
SRCS= main.c init.c done.c save.c subr.c vocab.c wizard.c io.c data.c crc.c
MAN= adventure.6
HIDEGAME=hidegame
CLEANFILES+=setup data.c
data.c: glorkz setup
${.OBJDIR}/setup ${.CURDIR}/glorkz > data.c
setup: setup.c hdr.h
${HOST_CC} -o setup ${.CURDIR}/setup.c
.include <bsd.prog.mk>

14
adventure/Makefrag Normal file
View File

@@ -0,0 +1,14 @@
# Makefrag - makefile fragment for adventure
adventure_CLEANFILES := data.c
adventure_DIRS := $(GAMESDIR) $(MAN6DIR)
adventure_all: adventure/adventure adventure/adventure.6
adventure/data.c: adventure/glorkz adventure/setup
adventure/setup $< >$@
adventure_install: adventure_all
$(INSTALL_BINARY) adventure/adventure $(INSTALL_PREFIX)$(GAMESDIR)/adventure
$(HIDE_GAME) adventure
$(INSTALL_MANUAL) adventure/adventure.6

59
adventure/adventure.6 Normal file
View File

@@ -0,0 +1,59 @@
.\" $NetBSD: adventure.6,v 1.3 1997/10/10 11:59:33 lukem Exp $
.\"
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" The game adventure was originally written in Fortran by Will Crowther
.\" and Don Woods. It was later translated to C and enhanced by Jim
.\" Gillogly. This code is derived from software contributed to Berkeley
.\" by Jim Gillogly at The Rand Corporation.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)adventure.6 8.1 (Berkeley) 5/31/93
.\"
.Dd May 31, 1993
.Dt ADVENTURE 6
.Os
.Sh NAME
.Nm adventure
.Nd an exploration game
.Sh SYNOPSIS
.Nm
.Op saved-file
.Sh DESCRIPTION
The object of the game is to locate and explore Colossal Cave, find the
treasures hidden there, and bring them back to the building with you.
The program is self-descriptive to a point, but part of the game is to
discover its rules.
.Pp
To terminate a game, enter
.Dq quit ;
to save a game for later resumption, enter
.Dq suspend .

140
adventure/crc.c Normal file
View File

@@ -0,0 +1,140 @@
/* $NetBSD: crc.c,v 1.6 1998/09/13 00:07:24 hubertf Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* James W. Williams of the University of Maryland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)crc.c 8.1 (Berkeley) 5/31/93";
static char ORIGINAL_sccsid[] = "@(#)crc.c 5.2 (Berkeley) 4/4/91";
#else
__RCSID("$NetBSD: crc.c,v 1.6 1998/09/13 00:07:24 hubertf Exp $");
#endif
#endif /* not lint */
#include "extern.h"
const unsigned long crctab[] = {
0x7fffffff,
0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e,
0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d,
0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0,
0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63,
0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa,
0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75,
0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180,
0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87,
0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5,
0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b,
0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea,
0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541,
0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc,
0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f,
0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e,
0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c,
0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b,
0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2,
0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671,
0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8,
0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767,
0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795,
0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b,
0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82,
0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d,
0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8,
0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff,
0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee,
0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d,
0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c,
0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02,
0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
/*
* crc --
* Compute a POSIX.2 checksum. This routine modified by Jim Gillogly
* to work on sequential data rather than on a file. Initial call to
* crc_start initializes the sum, and subsequent calls to crc update
* it.
*/
unsigned long crcval;
unsigned int step;
void
crc_start()
{
crcval = step = 0;
}
unsigned long
crc(ptr, nr) /* Process nr bytes at a time; ptr points to them */
const char *ptr;
int nr;
{
int i;
const char *p;
while (nr > 0)
for (p = ptr; nr--; ++p) {
if (!(i = crcval >> 24 ^ *p)) {
i = step++;
if (step >= sizeof(crctab) / sizeof(crctab[0]))
step = 0;
}
crcval = (crcval << 8) ^ crctab[i];
}
return crcval & 0xffffffff; /* Mask to 32 bits. */
}

174
adventure/done.c Normal file
View File

@@ -0,0 +1,174 @@
/* $NetBSD: done.c,v 1.6 1998/09/13 15:21:36 hubertf Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* The game adventure was originally written in Fortran by Will Crowther
* and Don Woods. It was later translated to C and enhanced by Jim
* Gillogly. This code is derived from software contributed to Berkeley
* by Jim Gillogly at The Rand Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)done.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: done.c,v 1.6 1998/09/13 15:21:36 hubertf Exp $");
#endif
#endif /* not lint */
/* Re-coding of advent in C: termination routines */
#include <stdio.h>
#include "hdr.h"
#include "extern.h"
int
score()
{ /* sort of like 20000 */
int scor, i;
mxscor = scor = 0;
for (i = 50; i <= maxtrs; i++) {
if (ptext[i].txtlen == 0)
continue;
k = 12;
if (i == chest)
k = 14;
if (i > chest)
k = 16;
if (prop[i] >= 0)
scor += 2;
if (place[i] == 3 && prop[i] == 0)
scor += k - 2;
mxscor += k;
}
scor += (maxdie - numdie) * 10;
mxscor += maxdie * 10;
if (!(scorng || gaveup))
scor += 4;
mxscor += 4;
if (dflag != 0)
scor += 25;
mxscor += 25;
if (closng)
scor += 25;
mxscor += 25;
if (closed) {
if (bonus == 0)
scor += 10;
if (bonus == 135)
scor += 25;
if (bonus == 134)
scor += 30;
if (bonus == 133)
scor += 45;
}
mxscor += 45;
if (place[magzin] == 108)
scor++;
mxscor++;
scor += 2;
mxscor += 2;
for (i = 1; i <= hntmax; i++)
if (hinted[i])
scor -= hints[i][2];
return (scor);
}
void
done(entry) /* entry=1 means goto 13000 */ /* game is over */
int entry; /* entry=2 means goto 20000 */ /* 3=19000 */
{
int i, sc;
if (entry == 1)
mspeak(1);
if (entry == 3)
rspeak(136);
printf("\n\n\nYou scored %d out of a ", (sc = score()));
printf("possible %d using %d turns.\n", mxscor, turns);
for (i = 1; i <= clsses; i++)
if (cval[i] >= sc) {
speak(&ctext[i]);
if (i == clsses - 1) {
printf("To achieve the next higher rating");
printf(" would be a neat trick!\n\n");
printf("Congratulations!!\n");
exit(0);
}
k = cval[i] + 1 - sc;
printf("To achieve the next higher rating, you need");
printf(" %d more point", k);
if (k == 1)
printf(".\n");
else
printf("s.\n");
exit(0);
}
printf("You just went off my scale!!!\n");
exit(0);
}
void
die(entry) /* label 90 */
int entry;
{
int i;
if (entry != 99) {
rspeak(23);
oldlc2 = loc;
}
if (closng) { /* 99 */
rspeak(131);
numdie++;
done(2);
}
yea = yes(81 + numdie * 2, 82 + numdie * 2, 54);
numdie++;
if (numdie == maxdie || !yea)
done(2);
place[water] = 0;
place[oil] = 0;
if (toting(lamp))
prop[lamp] = 0;
for (i = 100; i >= 1; i--) {
if (!toting(i))
continue;
k = oldlc2;
if (i == lamp)
k = 1;
drop(i, k);
}
loc = 3;
oldloc = loc;
}

130
adventure/extern.h Normal file
View File

@@ -0,0 +1,130 @@
/* $NetBSD: extern.h,v 1.9 1998/09/13 15:21:37 hubertf Exp $ */
/*
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christos Zoulas.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <string.h>
/* crc.c */
void crc_start __P((void));
unsigned long crc __P((const char *, int));
/* done.c */
int score __P((void));
void done __P((int)) __attribute__((__noreturn__));
void die __P((int));
/* init.c */
void init __P((void));
char *decr __P((int, int, int, int, int));
void linkdata __P((void));
void trapdel __P((int));
void startup __P((void));
/* io.c */
void getin __P((char **, char **));
int yes __P((int, int, int));
int yesm __P((int, int, int));
int next __P((void));
void rdata __P((void));
int rnum __P((void));
void rdesc __P((int));
void rtrav __P((void));
#ifdef DEBUG
void twrite __P((int));
#endif
void rvoc __P((void));
void rlocs __P((void));
void rdflt __P((void));
void rliq __P((void));
void rhints __P((void));
void rspeak __P((int));
void mspeak __P((int));
struct text;
void speak __P((const struct text *));
void pspeak __P((int, int));
/* save.c */
int save __P((const char *));
int restore __P((const char *));
/* subr.c */
int toting __P((int));
int here __P((int));
int at __P((int));
int liq2 __P((int));
int liq __P((void));
int liqloc __P((int));
int bitset __P((int, int));
int forced __P((int));
int dark __P((void));
int pct __P((int));
int fdwarf __P((void));
int march __P((void));
int mback __P((void));
int specials __P((void));
int trbridge __P((void));
void badmove __P((void));
void bug __P((int)) __attribute__((__noreturn__));
void checkhints __P((void));
int trsay __P((void));
int trtake __P((void));
int dropper __P((void));
int trdrop __P((void));
int tropen __P((void));
int trkill __P((void));
int trtoss __P((void));
int trfeed __P((void));
int trfill __P((void));
void closing __P((void));
void caveclose __P((void));
/* vocab.c */
void dstroy __P((int));
void juggle __P((int));
void move __P((int, int));
int put __P((int, int, int));
void carry __P((int, int));
void drop __P((int, int));
int vocab __P((const char *, int, int));
/* These three used to be functions in vocab.c */
#define copystr(src, dest) strcpy((dest), (src))
#define weq(str1, str2) (!strncmp((str1), (str2), 5))
#define length(str) (strlen((str)) + 1)
void prht __P((void));
/* wizard.c */
void datime __P((int *, int *));
void poof __P((void));
int Start __P((void));
int wizard __P((void));
void ciao __P((void));
int ran __P((int));

1815
adventure/glorkz Normal file

File diff suppressed because it is too large Load Diff

164
adventure/hdr.h Normal file
View File

@@ -0,0 +1,164 @@
/* $NetBSD: hdr.h,v 1.5 1998/08/29 20:19:56 hubertf Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* The game adventure was originally written in Fortran by Will Crowther
* and Don Woods. It was later translated to C and enhanced by Jim
* Gillogly. This code is derived from software contributed to Berkeley
* by Jim Gillogly at The Rand Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)hdr.h 8.1 (Berkeley) 5/31/93
*/
/* ADVENTURE -- Jim Gillogly, Jul 1977
* This program is a re-write of ADVENT, written in FORTRAN mostly by
* Don Woods of SAIL. In most places it is as nearly identical to the
* original as possible given the language and word-size differences.
* A few places, such as the message arrays and travel arrays were changed
* to reflect the smaller core size and word size. The labels of the
* original are reflected in this version, so that the comments of the
* fortran are still applicable here.
*
* The data file distributed with the fortran source is assumed to be called
* "glorkz" in the directory where the program is first run.
*/
/* hdr.h: included by c advent files */
#include <signal.h>
int datfd; /* message file descriptor */
volatile sig_atomic_t delhit;
int yea;
extern char data_file[]; /* Virtual data file */
#define TAB 011
#define LF 012
#define FLUSHLINE do { int flushline_ch; while ((flushline_ch = getchar()) != EOF && flushline_ch != '\n'); } while (0)
#define FLUSHLF while (next()!=LF)
int loc, newloc, oldloc, oldlc2, wzdark, gaveup, kq, k, k2;
char *wd1, *wd2; /* the complete words */
int verb, obj, spk;
extern int blklin;
int saved, savet, mxscor, latncy;
#define SHORT 50 /* How short is a demo game? */
#define MAXSTR 20 /* max length of user's words */
#define HTSIZE 512 /* max number of vocab words */
struct hashtab { /* hash table for vocabulary */
int val; /* word type &index (ktab) */
char *atab; /* pointer to actual string */
} voc[HTSIZE];
#define SEED 1815622 /* "Encryption" seed */
struct text
#ifdef OLDSTUFF
{
int seekadr; /* DATFILE must be < 2**16 */
#endif /* OLDSTUFF */
{
char *seekadr;/* Msg start in virtual disk */
int txtlen; /* length of msg starting here */
};
#define RTXSIZ 205
struct text rtext[RTXSIZ]; /* random text messages */
#define MAGSIZ 35
struct text mtext[MAGSIZ]; /* magic messages */
int clsses;
#define CLSMAX 12
struct text ctext[CLSMAX]; /* classes of adventurer */
int cval[CLSMAX];
struct text ptext[101]; /* object descriptions */
#define LOCSIZ 141 /* number of locations */
struct text ltext[LOCSIZ]; /* long loc description */
struct text stext[LOCSIZ]; /* short loc descriptions */
struct travlist { /* direcs & conditions of travel */
struct travlist *next; /* ptr to next list entry */
int conditions; /* m in writeup (newloc / 1000) */
int tloc; /* n in writeup (newloc % 1000) */
int tverb; /* the verb that takes you there */
} *travel[LOCSIZ], *tkk; /* travel is closer to keys(...) */
int atloc[LOCSIZ];
int plac[101]; /* initial object placement */
int fixd[101], fixed[101]; /* location fixed? */
int actspk[35]; /* rtext msg for verb <n> */
int cond[LOCSIZ]; /* various condition bits */
extern int setbit[16]; /* bit defn masks 1,2,4,... */
int hntmax;
int hints[20][5]; /* info on hints */
int hinted[20], hintlc[20];
int place[101], prop[101], links[201];
int abb[LOCSIZ];
int maxtrs, tally, tally2; /* treasure values */
#define FALSE 0
#define TRUE 1
int keys, lamp, grate, cage, rod, rod2, steps, /* mnemonics */
bird, door, pillow, snake, fissur, tablet, clam, oyster,
magzin, dwarf, knife, food, bottle, water, oil, plant, plant2,
axe, mirror, dragon, chasm, troll, troll2, bear, messag,
vend, batter, nugget, coins, chest, eggs, tridnt, vase,
emrald, pyram, pearl, rug, chain, spices, back, look, cave,
null, entrnc, dprssn, enter, stream, pour, say, lock, throw,
find, invent;
int chloc, chloc2, dseen[7], dloc[7], /* dwarf stuff */
odloc[7], dflag, daltlc;
int tk[21], stick, dtotal, attack;
int turns, lmwarn, iwest, knfloc, detail, /* various flags and
* counters */
abbnum, maxdie, numdie, holdng, dkill, foobar, bonus, clock1,
clock2, saved, closng, panic, closed, scorng;
int demo, newloc, limit;
#define DECR(a,b,c,d,e) decr(a+'+',b+'-',c+'#',d+'&',e+'%')

241
adventure/init.c Normal file
View File

@@ -0,0 +1,241 @@
/* $NetBSD: init.c,v 1.10 1998/08/29 20:19:56 hubertf Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* The game adventure was originally written in Fortran by Will Crowther
* and Don Woods. It was later translated to C and enhanced by Jim
* Gillogly. This code is derived from software contributed to Berkeley
* by Jim Gillogly at The Rand Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 6/2/93";
#else
__RCSID("$NetBSD: init.c,v 1.10 1998/08/29 20:19:56 hubertf Exp $");
#endif
#endif /* not lint */
/* Re-coding of advent in C: data initialization */
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "hdr.h"
#include "extern.h"
int blklin = TRUE;
int setbit[16] = {1, 2, 4, 010, 020, 040, 0100, 0200, 0400, 01000, 02000, 04000,
010000, 020000, 040000, 0100000};
void
init() /* everything for 1st time run */
{
rdata(); /* read data from orig. file */
linkdata();
poof();
}
char *
decr(a, b, c, d, e)
char a, b, c, d, e;
{
static char buf[6];
buf[0] = a - '+';
buf[1] = b - '-';
buf[2] = c - '#';
buf[3] = d - '&';
buf[4] = e - '%';
buf[5] = 0;
return buf;
}
void
linkdata()
{ /* secondary data manipulation */
int i, j;
/* array linkages */
for (i = 1; i <= LOCSIZ; i++)
if (ltext[i].seekadr != 0 && travel[i] != 0)
if ((travel[i]->tverb) == 1)
cond[i] = 2;
for (j = 100; j > 0; j--)
if (fixd[j] > 0) {
drop(j + 100, fixd[j]);
drop(j, plac[j]);
}
for (j = 100; j > 0; j--) {
fixed[j] = fixd[j];
if (plac[j] != 0 && fixd[j] <= 0)
drop(j, plac[j]);
}
maxtrs = 79;
tally = 0;
tally2 = 0;
for (i = 50; i <= maxtrs; i++) {
if (ptext[i].seekadr != 0)
prop[i] = -1;
tally -= prop[i];
}
/* define mnemonics */
keys = vocab(DECR('k', 'e', 'y', 's', '\0'), 1, 0);
lamp = vocab(DECR('l', 'a', 'm', 'p', '\0'), 1, 0);
grate = vocab(DECR('g', 'r', 'a', 't', 'e'), 1, 0);
cage = vocab(DECR('c', 'a', 'g', 'e', '\0'), 1, 0);
rod = vocab(DECR('r', 'o', 'd', '\0', '\0'), 1, 0);
rod2 = rod + 1;
steps = vocab(DECR('s', 't', 'e', 'p', 's'), 1, 0);
bird = vocab(DECR('b', 'i', 'r', 'd', '\0'), 1, 0);
door = vocab(DECR('d', 'o', 'o', 'r', '\0'), 1, 0);
pillow = vocab(DECR('p', 'i', 'l', 'l', 'o'), 1, 0);
snake = vocab(DECR('s', 'n', 'a', 'k', 'e'), 1, 0);
fissur = vocab(DECR('f', 'i', 's', 's', 'u'), 1, 0);
tablet = vocab(DECR('t', 'a', 'b', 'l', 'e'), 1, 0);
clam = vocab(DECR('c', 'l', 'a', 'm', '\0'), 1, 0);
oyster = vocab(DECR('o', 'y', 's', 't', 'e'), 1, 0);
magzin = vocab(DECR('m', 'a', 'g', 'a', 'z'), 1, 0);
dwarf = vocab(DECR('d', 'w', 'a', 'r', 'f'), 1, 0);
knife = vocab(DECR('k', 'n', 'i', 'f', 'e'), 1, 0);
food = vocab(DECR('f', 'o', 'o', 'd', '\0'), 1, 0);
bottle = vocab(DECR('b', 'o', 't', 't', 'l'), 1, 0);
water = vocab(DECR('w', 'a', 't', 'e', 'r'), 1, 0);
oil = vocab(DECR('o', 'i', 'l', '\0', '\0'), 1, 0);
plant = vocab(DECR('p', 'l', 'a', 'n', 't'), 1, 0);
plant2 = plant + 1;
axe = vocab(DECR('a', 'x', 'e', '\0', '\0'), 1, 0);
mirror = vocab(DECR('m', 'i', 'r', 'r', 'o'), 1, 0);
dragon = vocab(DECR('d', 'r', 'a', 'g', 'o'), 1, 0);
chasm = vocab(DECR('c', 'h', 'a', 's', 'm'), 1, 0);
troll = vocab(DECR('t', 'r', 'o', 'l', 'l'), 1, 0);
troll2 = troll + 1;
bear = vocab(DECR('b', 'e', 'a', 'r', '\0'), 1, 0);
messag = vocab(DECR('m', 'e', 's', 's', 'a'), 1, 0);
vend = vocab(DECR('v', 'e', 'n', 'd', 'i'), 1, 0);
batter = vocab(DECR('b', 'a', 't', 't', 'e'), 1, 0);
nugget = vocab(DECR('g', 'o', 'l', 'd', '\0'), 1, 0);
coins = vocab(DECR('c', 'o', 'i', 'n', 's'), 1, 0);
chest = vocab(DECR('c', 'h', 'e', 's', 't'), 1, 0);
eggs = vocab(DECR('e', 'g', 'g', 's', '\0'), 1, 0);
tridnt = vocab(DECR('t', 'r', 'i', 'd', 'e'), 1, 0);
vase = vocab(DECR('v', 'a', 's', 'e', '\0'), 1, 0);
emrald = vocab(DECR('e', 'm', 'e', 'r', 'a'), 1, 0);
pyram = vocab(DECR('p', 'y', 'r', 'a', 'm'), 1, 0);
pearl = vocab(DECR('p', 'e', 'a', 'r', 'l'), 1, 0);
rug = vocab(DECR('r', 'u', 'g', '\0', '\0'), 1, 0);
chain = vocab(DECR('c', 'h', 'a', 'i', 'n'), 1, 0);
back = vocab(DECR('b', 'a', 'c', 'k', '\0'), 0, 0);
look = vocab(DECR('l', 'o', 'o', 'k', '\0'), 0, 0);
cave = vocab(DECR('c', 'a', 'v', 'e', '\0'), 0, 0);
null = vocab(DECR('n', 'u', 'l', 'l', '\0'), 0, 0);
entrnc = vocab(DECR('e', 'n', 't', 'r', 'a'), 0, 0);
dprssn = vocab(DECR('d', 'e', 'p', 'r', 'e'), 0, 0);
enter = vocab(DECR('e', 'n', 't', 'e', 'r'), 0, 0);
pour = vocab(DECR('p', 'o', 'u', 'r', '\0'), 2, 0);
say = vocab(DECR('s', 'a', 'y', '\0', '\0'), 2, 0);
lock = vocab(DECR('l', 'o', 'c', 'k', '\0'), 2, 0);
throw = vocab(DECR('t', 'h', 'r', 'o', 'w'), 2, 0);
find = vocab(DECR('f', 'i', 'n', 'd', '\0'), 2, 0);
invent = vocab(DECR('i', 'n', 'v', 'e', 'n'), 2, 0);
/* initialize dwarves */
chloc = 114;
chloc2 = 140;
for (i = 1; i <= 6; i++)
dseen[i] = FALSE;
dflag = 0;
dloc[1] = 19;
dloc[2] = 27;
dloc[3] = 33;
dloc[4] = 44;
dloc[5] = 64;
dloc[6] = chloc;
daltlc = 18;
/* random flags & ctrs */
turns = 0;
lmwarn = FALSE;
iwest = 0;
knfloc = 0;
detail = 0;
abbnum = 5;
for (i = 0; i <= 4; i++)
if (rtext[2 * i + 81].seekadr != 0)
maxdie = i + 1;
numdie = holdng = dkill = foobar = bonus = 0;
clock1 = 30;
clock2 = 50;
saved = 0;
closng = panic = closed = scorng = FALSE;
}
void
trapdel(n) /* come here if he hits a del */
int n __attribute__((unused));
{
delhit = 1; /* main checks, treats as QUIT */
signal(SIGINT, trapdel);/* catch subsequent DELs */
}
void
startup()
{
demo = Start();
srand((int) (time((time_t *) NULL))); /* random seed */
#if 0
srand(371); /* non-random seed */
#endif
hinted[3] = yes(65, 1, 0);
newloc = 1;
delhit = 0;
limit = 330;
if (hinted[3])
limit = 1000; /* better batteries if instrucs */
}

594
adventure/io.c Normal file
View File

@@ -0,0 +1,594 @@
/* $NetBSD: io.c,v 1.10 1998/09/14 09:29:08 hubertf Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* The game adventure was originally written in Fortran by Will Crowther
* and Don Woods. It was later translated to C and enhanced by Jim
* Gillogly. This code is derived from software contributed to Berkeley
* by Jim Gillogly at The Rand Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: io.c,v 1.10 1998/09/14 09:29:08 hubertf Exp $");
#endif
#endif /* not lint */
/* Re-coding of advent in C: file i/o and user i/o */
#include <err.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "hdr.h"
#include "extern.h"
void
getin(wrd1, wrd2) /* get command from user */
char **wrd1, **wrd2; /* no prompt, usually */
{
char *s;
static char wd1buf[MAXSTR], wd2buf[MAXSTR];
int first, numch;
*wrd1 = wd1buf; /* return ptr to internal str */
*wrd2 = wd2buf;
wd2buf[0] = 0; /* in case it isn't set here */
for (s = wd1buf, first = 1, numch = 0;;) {
if ((*s = getchar()) >= 'A' && *s <= 'Z')
*s = *s - ('A' - 'a');
/* convert to upper case */
switch (*s) { /* start reading from user */
case '\n':
*s = 0;
return;
case ' ':
if (s == wd1buf || s == wd2buf) /* initial blank */
continue;
*s = 0;
if (first) { /* finished 1st wd; start 2nd */
first = numch = 0;
s = wd2buf;
break;
} else { /* finished 2nd word */
FLUSHLINE;
*s = 0;
return;
}
case EOF:
printf("user closed input stream, quitting...\n");
exit(0);
default:
if (++numch >= MAXSTR) { /* string too long */
printf("Give me a break!!\n");
wd1buf[0] = wd2buf[0] = 0;
FLUSHLINE;
return;
}
s++;
}
}
}
int
yes(x, y, z) /* confirm with rspeak */
int x, y, z;
{
int result = TRUE; /* pacify gcc */
int ch;
for (;;) {
rspeak(x); /* tell him what we want */
if ((ch = getchar()) == 'y')
result = TRUE;
else if (ch == 'n')
result = FALSE;
else if (ch == EOF) {
printf("user closed input stream, quitting...\n");
exit(0);
}
FLUSHLINE;
if (ch == 'y' || ch == 'n')
break;
printf("Please answer the question.\n");
}
if (result == TRUE)
rspeak(y);
if (result == FALSE)
rspeak(z);
return (result);
}
int
yesm(x, y, z) /* confirm with mspeak */
int x, y, z;
{
int result = TRUE; /* pacify gcc */
int ch;
for (;;) {
mspeak(x); /* tell him what we want */
if ((ch = getchar()) == 'y')
result = TRUE;
else if (ch == 'n')
result = FALSE;
else if (ch == EOF) {
printf("user closed input stream, quitting...\n");
exit(0);
}
FLUSHLINE;
if (ch == 'y' || ch == 'n')
break;
printf("Please answer the question.\n");
}
if (result == TRUE)
mspeak(y);
if (result == FALSE)
mspeak(z);
return (result);
}
/* FILE *inbuf,*outbuf; */
char *inptr; /* Pointer into virtual disk */
int outsw = 0; /* putting stuff to data file? */
const char iotape[] = "Ax3F'\003tt$8h\315qer*h\017nGKrX\207:!l";
const char *tape = iotape; /* pointer to encryption tape */
int
next()
{ /* next virtual char, bump adr */
int ch;
ch = (*inptr ^ random()) & 0xFF; /* Decrypt input data */
if (outsw) { /* putting data in tmp file */
if (*tape == 0)
tape = iotape; /* rewind encryption tape */
*inptr = ch ^ *tape++; /* re-encrypt and replace value */
}
inptr++;
return (ch);
}
char breakch; /* tell which char ended rnum */
void
rdata()
{ /* "read" data from virtual file */
int sect;
char ch;
inptr = data_file; /* Pointer to virtual data file */
srandom(SEED); /* which is lightly encrypted. */
clsses = 1;
for (;;) { /* read data sections */
sect = next() - '0'; /* 1st digit of section number */
#ifdef VERBOSE
printf("Section %c", sect + '0');
#endif
if ((ch = next()) != LF) { /* is there a second digit? */
FLUSHLF;
#ifdef VERBOSE
putchar(ch);
#endif
sect = 10 * sect + ch - '0';
}
#ifdef VERBOSE
putchar('\n');
#endif
switch (sect) {
case 0: /* finished reading database */
return;
case 1: /* long form descriptions */
rdesc(1);
break;
case 2: /* short form descriptions */
rdesc(2);
break;
case 3: /* travel table */
rtrav();
break;
case 4: /* vocabulary */
rvoc();
break;
case 5: /* object descriptions */
rdesc(5);
break;
case 6: /* arbitrary messages */
rdesc(6);
break;
case 7: /* object locations */
rlocs();
break;
case 8: /* action defaults */
rdflt();
break;
case 9: /* liquid assets */
rliq();
break;
case 10: /* class messages */
rdesc(10);
break;
case 11: /* hints */
rhints();
break;
case 12: /* magic messages */
rdesc(12);
break;
default:
printf("Invalid data section number: %d\n", sect);
for (;;)
putchar(next());
}
if (breakch != LF) /* routines return after "-1" */
FLUSHLF;
}
}
char nbf[12];
int
rnum()
{ /* read initial location num */
char *s;
tape = iotape; /* restart encryption tape */
for (s = nbf, *s = 0;; s++)
if ((*s = next()) == TAB || *s == '\n' || *s == LF)
break;
breakch = *s; /* save char for rtrav() */
*s = 0; /* got the number as ascii */
if (nbf[0] == '-')
return (-1); /* end of data */
return (atoi(nbf)); /* convert it to integer */
}
char *seekhere;
void
rdesc(sect) /* read description-format msgs */
int sect;
{
int locc;
char *seekstart, *maystart;
seekhere = inptr; /* Where are we in virtual file? */
outsw = 1; /* these msgs go into tmp file */
for (oldloc = -1, seekstart = seekhere;;) {
maystart = inptr; /* maybe starting new entry */
if ((locc = rnum()) != oldloc && oldloc >= 0 /* finished msg */
&& !(sect == 5 && (locc == 0 || locc >= 100))) { /* unless sect 5 */
switch (sect) { /* now put it into right table */
case 1:/* long descriptions */
ltext[oldloc].seekadr = seekhere;
ltext[oldloc].txtlen = maystart - seekstart;
break;
case 2:/* short descriptions */
stext[oldloc].seekadr = seekhere;
stext[oldloc].txtlen = maystart - seekstart;
break;
case 5:/* object descriptions */
ptext[oldloc].seekadr = seekhere;
ptext[oldloc].txtlen = maystart - seekstart;
break;
case 6:/* random messages */
if (oldloc > RTXSIZ)
errx(1,"Too many random msgs");
rtext[oldloc].seekadr = seekhere;
rtext[oldloc].txtlen = maystart - seekstart;
break;
case 10: /* class messages */
ctext[clsses].seekadr = seekhere;
ctext[clsses].txtlen = maystart - seekstart;
cval[clsses++] = oldloc;
break;
case 12: /* magic messages */
if (oldloc > MAGSIZ)
errx(1,"Too many magic msgs");
mtext[oldloc].seekadr = seekhere;
mtext[oldloc].txtlen = maystart - seekstart;
break;
default:
errx(1,"rdesc called with bad section");
}
seekhere += maystart - seekstart;
}
if (locc < 0) {
outsw = 0; /* turn off output */
seekhere += 3; /* -1<delimiter> */
return;
}
if (sect != 5 || (locc > 0 && locc < 100)) {
if (oldloc != locc) /* starting a new message */
seekstart = maystart;
oldloc = locc;
}
FLUSHLF; /* scan the line */
}
}
void
rtrav()
{ /* read travel table */
int locc;
struct travlist *t = NULL;
char *s;
char buf[12];
int len, m, n, entries = 0;
for (oldloc = -1;;) { /* get another line */
if ((locc = rnum()) != oldloc && oldloc >= 0) { /* end of entry */
t->next = 0; /* terminate the old entry */
/* printf("%d:%d entries\n",oldloc,entries); */
/* twrite(oldloc); */
}
if (locc == -1)
return;
if (locc != oldloc) { /* getting a new entry */
t = travel[locc] = (struct travlist *) malloc(sizeof(struct travlist));
if ( t == NULL)
errx(1, "Out of memory!");
/* printf("New travel list for %d\n",locc); */
entries = 0;
oldloc = locc;
}
for (s = buf;; s++) /* get the newloc number /ASCII */
if ((*s = next()) == TAB || *s == LF)
break;
*s = 0;
len = length(buf) - 1; /* quad long number handling */
/* printf("Newloc: %s (%d chars)\n",buf,len); */
if (len < 4) { /* no "m" conditions */
m = 0;
n = atoi(buf); /* newloc mod 1000 = newloc */
} else { /* a long integer */
n = atoi(buf + len - 3);
buf[len - 3] = 0; /* terminate newloc/1000 */
m = atoi(buf);
}
while (breakch != LF) { /* only do one line at a time */
if (entries++) {
t = t->next = (struct travlist *) malloc(sizeof(struct travlist));
if (t == NULL)
errx(1, "Out of memory!");
}
t->tverb = rnum(); /* get verb from the file */
t->tloc = n; /* table entry mod 1000 */
t->conditions = m; /* table entry / 1000 */
/* printf("entry %d for %d\n",entries,locc); */
}
}
}
#ifdef DEBUG
void
twrite(loq) /* travel options from this loc */
int loq;
{
struct travlist *t;
printf("If");
speak(&ltext[loq]);
printf("then\n");
for (t = travel[loq]; t != 0; t = t->next) {
printf("verb %d takes you to ", t->tverb);
if (t->tloc <= 300)
speak(&ltext[t->tloc]);
else
if (t->tloc <= 500)
printf("special code %d\n", t->tloc - 300);
else
rspeak(t->tloc - 500);
printf("under conditions %d\n", t->conditions);
}
}
#endif /* DEBUG */
void
rvoc()
{
char *s; /* read the vocabulary */
int index;
char buf[6];
for (;;) {
index = rnum();
if (index < 0)
break;
for (s = buf, *s = 0;; s++) /* get the word */
if ((*s = next()) == TAB || *s == '\n' || *s == LF
|| *s == ' ')
break;
/* terminate word with newline, LF, tab, blank */
if (*s != '\n' && *s != LF)
FLUSHLF;/* can be comments */
*s = 0;
/* printf("\"%s\"=%d\n",buf,index); */
vocab(buf, -2, index);
}
/* prht(); */
}
void
rlocs()
{ /* initial object locations */
for (;;) {
if ((obj = rnum()) < 0)
break;
plac[obj] = rnum(); /* initial loc for this obj */
if (breakch == TAB) /* there's another entry */
fixd[obj] = rnum();
else
fixd[obj] = 0;
}
}
void
rdflt()
{ /* default verb messages */
for (;;) {
if ((verb = rnum()) < 0)
break;
actspk[verb] = rnum();
}
}
void
rliq()
{ /* liquid assets &c: cond bits */
int bitnum;
for (;;) { /* read new bit list */
if ((bitnum = rnum()) < 0)
break;
for (;;) { /* read locs for bits */
cond[rnum()] |= setbit[bitnum];
if (breakch == LF)
break;
}
}
}
void
rhints()
{
int hintnum, i;
hntmax = 0;
for (;;) {
if ((hintnum = rnum()) < 0)
break;
for (i = 1; i < 5; i++)
hints[hintnum][i] = rnum();
if (hintnum > hntmax)
hntmax = hintnum;
}
}
void
rspeak(msg)
int msg;
{
if (msg != 0)
speak(&rtext[msg]);
}
void
mspeak(msg)
int msg;
{
if (msg != 0)
speak(&mtext[msg]);
}
void
speak(msg) /* read, decrypt, and print a message (not
* ptext) */
const struct text *msg; /* msg is a pointer to seek address and length
* of mess */
{
char *s, nonfirst;
s = msg->seekadr;
nonfirst = 0;
while (s - msg->seekadr < msg->txtlen) { /* read a line at a time */
tape = iotape; /* restart decryption tape */
while ((*s++ ^ *tape++) != TAB); /* read past loc num */
/* assume tape is longer than location number */
/* plus the lookahead put together */
if ((*s ^ *tape) == '>' &&
(*(s + 1) ^ *(tape + 1)) == '$' &&
(*(s + 2) ^ *(tape + 2)) == '<')
break;
if (blklin && !nonfirst++)
putchar('\n');
do {
if (*tape == 0)
tape = iotape; /* rewind decryp tape */
putchar(*s ^ *tape);
} while ((*s++ ^ *tape++) != LF); /* better end with LF */
}
}
void
pspeak(m, skip) /* read, decrypt an print a ptext message */
int m; /* msg is the number of all the p msgs for
* this place */
int skip; /* assumes object 1 doesn't have prop 1, obj 2
* no prop 2 &c */
{
char *s, nonfirst;
char *numst, save;
struct text *msg;
char *tbuf;
msg = &ptext[m];
if ((tbuf = (char *) malloc(msg->txtlen + 1)) == NULL)
errx(1, "Out of memory!");
memcpy(tbuf, msg->seekadr, msg->txtlen + 1); /* Room to null */
s = tbuf;
nonfirst = 0;
while (s - tbuf < msg->txtlen) { /* read line at a time */
tape = iotape; /* restart decryption tape */
for (numst = s; (*s ^= *tape++) != TAB; s++); /* get number */
save = *s; /* Temporarily trash the string (cringe) */
*s++ = 0; /* decrypting number within the string */
if (atoi(numst) != 100 * skip && skip >= 0) {
while ((*s++ ^ *tape++) != LF) /* flush the line */
if (*tape == 0)
tape = iotape;
continue;
}
if ((*s ^ *tape) == '>' && (*(s + 1) ^ *(tape + 1)) == '$' &&
(*(s + 2) ^ *(tape + 2)) == '<')
break;
if (blklin && !nonfirst++)
putchar('\n');
do {
if (*tape == 0)
tape = iotape;
putchar(*s ^ *tape);
} while ((*s++ ^ *tape++) != LF); /* better end with LF */
if (skip < 0)
break;
}
free(tbuf);
}

768
adventure/main.c Normal file
View File

@@ -0,0 +1,768 @@
/* $NetBSD: main.c,v 1.12 1998/09/14 09:29:08 hubertf Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* The game adventure was originally written in Fortran by Will Crowther
* and Don Woods. It was later translated to C and enhanced by Jim
* Gillogly. This code is derived from software contributed to Berkeley
* by Jim Gillogly at The Rand Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/2/93";
#else
__RCSID("$NetBSD: main.c,v 1.12 1998/09/14 09:29:08 hubertf Exp $");
#endif
#endif /* not lint */
/* Re-coding of advent in C: main program */
#include <sys/file.h>
#include <err.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include "hdr.h"
#include "extern.h"
int main __P((int, char **));
int
main(argc, argv)
int argc;
char **argv;
{
int i;
int rval, ll;
struct text *kk;
/* revoke setgid privileges */
setregid(getgid(), getgid());
init(); /* Initialize everything */
signal(SIGINT, trapdel);
if (argc > 1) { /* Restore file specified */
/* Restart is label 8305 (Fortran) */
i = restore(argv[1]); /* See what we've got */
switch (i) {
case 0: /* The restore worked fine */
yea = Start();
k = null;
unlink(argv[1]); /* Don't re-use the save */
goto l8; /* Get where we're going */
case 1: /* Couldn't open it */
errx(1,"can't open file"); /* So give up */
case 2: /* Oops -- file was altered */
rspeak(202); /* You dissolve */
exit(1); /* File could be non-adventure */
} /* So don't unlink it. */
}
startup(); /* prepare for a user */
for (;;) { /* main command loop (label 2) */
if (newloc < 9 && newloc != 0 && closng) {
rspeak(130); /* if closing leave only by */
newloc = loc; /* main office */
if (!panic)
clock2 = 15;
panic = TRUE;
}
rval = fdwarf(); /* dwarf stuff */
if (rval == 99)
die(99);
l2000: if (loc == 0)
die(99); /* label 2000 */
kk = &stext[loc];
if ((abb[loc] % abbnum) == 0 || kk->seekadr == 0)
kk = &ltext[loc];
if (!forced(loc) && dark()) {
if (wzdark && pct(35)) {
die(90);
goto l2000;
}
kk = &rtext[16];
}
#if 0
l2001:
#endif
if (toting(bear))
rspeak(141); /* 2001 */
speak(kk);
k = 1;
if (forced(loc))
goto l8;
if (loc == 33 && pct(25) && !closng)
rspeak(8);
if (!dark()) {
abb[loc]++;
for (i = atloc[loc]; i != 0; i = links[i]) { /* 2004 */
obj = i;
if (obj > 100)
obj -= 100;
if (obj == steps && toting(nugget))
continue;
if (prop[obj] < 0) {
if (closed)
continue;
prop[obj] = 0;
if (obj == rug || obj == chain)
prop[obj] = 1;
tally--;
if (tally == tally2 && tally != 0)
if (limit > 35)
limit = 35;
}
ll = prop[obj]; /* 2006 */
if (obj == steps && loc == fixed[steps])
ll = 1;
pspeak(obj, ll);
} /* 2008 */
goto l2012;
l2009: k = 54; /* 2009 */
l2010: spk = k;
l2011: rspeak(spk);
}
l2012: verb = 0; /* 2012 */
obj = 0;
l2600: checkhints(); /* to 2600-2602 */
if (closed) {
if (prop[oyster] < 0 && toting(oyster))
pspeak(oyster, 1);
for (i = 1; i < 100; i++)
if (toting(i) && prop[i] < 0) /* 2604 */
prop[i] = -1 - prop[i];
}
wzdark = dark(); /* 2605 */
if (knfloc > 0 && knfloc != loc)
knfloc = 1;
getin(&wd1, &wd2);
if (delhit) { /* user typed a DEL */
delhit = 0; /* reset counter */
copystr("quit", wd1); /* pretend he's quitting */
*wd2 = 0;
}
l2608: if ((foobar = -foobar) > 0)
foobar = 0; /* 2608 */
/* should check here for "magic mode" */
turns++;
if (demo && turns >= SHORT)
done(1); /* to 13000 */
if (verb == say && *wd2 != 0)
verb = 0;
if (verb == say)
goto l4090;
if (tally == 0 && loc >= 15 && loc != 33)
clock1--;
if (clock1 == 0) {
closing(); /* to 10000 */
goto l19999;
}
if (clock1 < 0)
clock2--;
if (clock2 == 0) {
caveclose(); /* to 11000 */
continue; /* back to 2 */
}
if (prop[lamp] == 1)
limit--;
if (limit <= 30 && here(batter) && prop[batter] == 0
&& here(lamp)) {
rspeak(188); /* 12000 */
prop[batter] = 1;
if (toting(batter))
drop(batter, loc);
limit = limit + 2500;
lmwarn = FALSE;
goto l19999;
}
if (limit == 0) {
limit = -1; /* 12400 */
prop[lamp] = 0;
rspeak(184);
goto l19999;
}
if (limit < 0 && loc <= 8) {
rspeak(185); /* 12600 */
gaveup = TRUE;
done(2); /* to 20000 */
}
if (limit <= 30) {
if (lmwarn || !here(lamp))
goto l19999; /* 12200 */
lmwarn = TRUE;
spk = 187;
if (place[batter] == 0)
spk = 183;
if (prop[batter] == 1)
spk = 189;
rspeak(spk);
}
l19999: k = 43;
if (liqloc(loc) == water)
k = 70;
if (weq(wd1, "enter") &&
(weq(wd2, "strea") || weq(wd2, "water")))
goto l2010;
if (weq(wd1, "enter") && *wd2 != 0)
goto l2800;
if ((!weq(wd1, "water") && !weq(wd1, "oil"))
|| (!weq(wd2, "plant") && !weq(wd2, "door")))
goto l2610;
if (at(vocab(wd2, 1, 0)))
copystr("pour", wd2);
l2610: if (weq(wd1, "west"))
if (++iwest == 10)
rspeak(17);
l2630: i = vocab(wd1, -1, 0);
if (i == -1) {
spk = 60; /* 3000 */
if (pct(20))
spk = 61;
if (pct(20))
spk = 13;
rspeak(spk);
goto l2600;
}
k = i % 1000;
kq = i / 1000 + 1;
switch (kq) {
case 1:
goto l8;
case 2:
goto l5000;
case 3:
goto l4000;
case 4:
goto l2010;
default:
bug(22);
}
l8:
switch (march()) {
case 2:
continue; /* i.e. goto l2 */
case 99:
die(99);
goto l2000;
default:
bug(110);
}
l2800: copystr(wd2, wd1);
*wd2 = 0;
goto l2610;
l4000: verb = k;
spk = actspk[verb];
if (*wd2 != 0 && verb != say)
goto l2800;
if (verb == say)
obj = *wd2;
if (obj != 0)
goto l4090;
#if 0
l4080:
#endif
switch (verb) {
case 1: /* take = 8010 */
if (atloc[loc] == 0 || links[atloc[loc]] != 0)
goto l8000;
for (i = 1; i <= 5; i++)
if (dloc[i] == loc && dflag >= 2)
goto l8000;
obj = atloc[loc];
goto l9010;
case 2:
case 3:
case 9: /* 8000 : drop,say,wave */
case 10:
case 16:
case 17: /* calm,rub,toss */
case 19:
case 21:
case 28: /* find,feed,break */
case 29: /* wake */
l8000: printf("%s what?\n", wd1);
obj = 0;
goto l2600;
case 4:
case 6: /* 8040 open,lock */
spk = 28;
if (here(clam))
obj = clam;
if (here(oyster))
obj = oyster;
if (at(door))
obj = door;
if (at(grate))
obj = grate;
if (obj != 0 && here(chain))
goto l8000;
if (here(chain))
obj = chain;
if (obj == 0)
goto l2011;
goto l9040;
case 5:
goto l2009; /* nothing */
case 7:
goto l9070; /* on */
case 8:
goto l9080; /* off */
case 11:
goto l8000; /* walk */
case 12:
goto l9120; /* kill */
case 13:
goto l9130; /* pour */
case 14: /* eat: 8140 */
if (!here(food))
goto l8000;
l8142: dstroy(food);
spk = 72;
goto l2011;
case 15:
goto l9150; /* drink */
case 18: /* quit: 8180 */
gaveup = yes(22, 54, 54);
if (gaveup)
done(2); /* 8185 */
goto l2012;
case 20: /* invent=8200 */
spk = 98;
for (i = 1; i <= 100; i++) {
if (i != bear && toting(i)) {
if (spk == 98)
rspeak(99);
blklin = FALSE;
pspeak(i, -1);
blklin = TRUE;
spk = 0;
}
}
if (toting(bear))
spk = 141;
goto l2011;
case 22:
goto l9220; /* fill */
case 23:
goto l9230; /* blast */
case 24: /* score: 8240 */
scorng = TRUE;
printf("If you were to quit now, you would score");
printf(" %d out of a possible ", score());
printf("%d.", mxscor);
scorng = FALSE;
gaveup = yes(143, 54, 54);
if (gaveup)
done(2);
goto l2012;
case 25: /* foo: 8250 */
k = vocab(wd1, 3, 0);
spk = 42;
if (foobar == 1 - k)
goto l8252;
if (foobar != 0)
spk = 151;
goto l2011;
l8252: foobar = k;
if (k != 4)
goto l2009;
foobar = 0;
if (place[eggs] == plac[eggs]
|| (toting(eggs) && loc == plac[eggs]))
goto l2011;
if (place[eggs] == 0 && place[troll] == 0 && prop[troll] == 0)
prop[troll] = 1;
k = 2;
if (here(eggs))
k = 1;
if (loc == plac[eggs])
k = 0;
move(eggs, plac[eggs]);
pspeak(eggs, k);
goto l2012;
case 26: /* brief=8260 */
spk = 156;
abbnum = 10000;
detail = 3;
goto l2011;
case 27: /* read=8270 */
if (here(magzin))
obj = magzin;
if (here(tablet))
obj = obj * 100 + tablet;
if (here(messag))
obj = obj * 100 + messag;
if (closed && toting(oyster))
obj = oyster;
if (obj > 100 || obj == 0 || dark())
goto l8000;
goto l9270;
case 30: /* suspend=8300 */
spk = 201;
if (demo)
goto l2011;
printf("I can suspend your adventure for you so");
printf(" you can resume later, but\n");
printf("you will have to wait at least");
printf(" %d minutes before continuing.", latncy);
if (!yes(200, 54, 54))
goto l2012;
datime(&saved, &savet);
ciao(); /* Do we quit? */
continue; /* Maybe not */
case 31: /* hours=8310 */
printf("Colossal cave is closed 9am-5pm Mon ");
printf("through Fri except holidays.\n");
goto l2012;
default:
bug(23);
}
l4090:
switch (verb) {
case 1: /* take = 9010 */
l9010: switch (trtake()) {
case 2011:
goto l2011;
case 9220:
goto l9220;
case 2009:
goto l2009;
case 2012:
goto l2012;
default:
bug(102);
}
l9020: case 2: /* drop = 9020 */
switch (trdrop()) {
case 2011:
goto l2011;
case 19000:
done(3);
case 2012:
goto l2012;
default:
bug(105);
}
#if 0
l9030:
#endif
case 3:
switch (trsay()) {
case 2012:
goto l2012;
case 2630:
goto l2630;
default:
bug(107);
}
l9040: case 4:
case 6: /* open, close */
switch (tropen()) {
case 2011:
goto l2011;
case 2010:
goto l2010;
default:
bug(106);
}
case 5:
goto l2009; /* nothing */
case 7: /* on 9070 */
l9070: if (!here(lamp))
goto l2011;
spk = 184;
if (limit < 0)
goto l2011;
prop[lamp] = 1;
rspeak(39);
if (wzdark)
goto l2000;
goto l2012;
case 8: /* off */
l9080: if (!here(lamp))
goto l2011;
prop[lamp] = 0;
rspeak(40);
if (dark())
rspeak(16);
goto l2012;
case 9: /* wave */
if ((!toting(obj)) && (obj != rod || !toting(rod2)))
spk = 29;
if (obj != rod || !at(fissur) || !toting(obj) || closng)
goto l2011;
prop[fissur] = 1 - prop[fissur];
pspeak(fissur, 2 - prop[fissur]);
goto l2012;
case 10:
case 11:
case 18: /* calm, walk, quit */
case 24:
case 25:
case 26: /* score, foo, brief */
case 30:
case 31: /* suspend, hours */
goto l2011;
l9120: case 12:/* kill */
switch (trkill()) {
case 8000:
goto l8000;
case 8:
goto l8;
case 2011:
goto l2011;
case 2608:
goto l2608;
case 19000:
done(3);
default:
bug(112);
}
l9130: case 13:/* pour */
if (obj == bottle || obj == 0)
obj = liq();
if (obj == 0)
goto l8000;
if (!toting(obj))
goto l2011;
spk = 78;
if (obj != oil && obj != water)
goto l2011;
prop[bottle] = 1;
place[obj] = 0;
spk = 77;
if (!(at(plant) || at(door)))
goto l2011;
if (at(door)) {
prop[door] = 0; /* 9132 */
if (obj == oil)
prop[door] = 1;
spk = 113 + prop[door];
goto l2011;
}
spk = 112;
if (obj != water)
goto l2011;
pspeak(plant, prop[plant] + 1);
prop[plant] = (prop[plant] + 2) % 6;
prop[plant2] = prop[plant] / 2;
k = null;
goto l8;
case 14: /* 9140 - eat */
if (obj == food)
goto l8142;
if (obj == bird || obj == snake || obj == clam || obj == oyster
|| obj == dwarf || obj == dragon || obj == troll
|| obj == bear)
spk = 71;
goto l2011;
l9150: case 15:/* 9150 - drink */
if (obj == 0 && liqloc(loc) != water && (liq() != water
|| !here(bottle)))
goto l8000;
if (obj != 0 && obj != water)
spk = 110;
if (spk == 110 || liq() != water || !here(bottle))
goto l2011;
prop[bottle] = 1;
place[water] = 0;
spk = 74;
goto l2011;
case 16: /* 9160: rub */
if (obj != lamp)
spk = 76;
goto l2011;
case 17: /* 9170: throw */
switch (trtoss()) {
case 2011:
goto l2011;
case 9020:
goto l9020;
case 9120:
goto l9120;
case 8:
goto l8;
case 9210:
goto l9210;
default:
bug(113);
}
case 19:
case 20: /* 9190: find, invent */
if (at(obj) || (liq() == obj && at(bottle))
|| k == liqloc(loc))
spk = 94;
for (i = 1; i <= 5; i++)
if (dloc[i] == loc && dflag >= 2 && obj == dwarf)
spk = 94;
if (closed)
spk = 138;
if (toting(obj))
spk = 24;
goto l2011;
l9210: case 21:/* feed */
switch (trfeed()) {
case 2011:
goto l2011;
default:
bug(114);
}
l9220: case 22:/* fill */
switch (trfill()) {
case 2011:
goto l2011;
case 8000:
goto l8000;
case 9020:
goto l9020;
default:
bug(115);
}
l9230: case 23:/* blast */
if (prop[rod2] < 0 || !closed)
goto l2011;
bonus = 133;
if (loc == 115)
bonus = 134;
if (here(rod2))
bonus = 135;
rspeak(bonus);
done(2);
l9270: case 27:/* read */
if (dark())
goto l5190;
if (obj == magzin)
spk = 190;
if (obj == tablet)
spk = 196;
if (obj == messag)
spk = 191;
if (obj == oyster && hinted[2] && toting(oyster))
spk = 194;
if (obj != oyster || hinted[2] || !toting(oyster)
|| !closed)
goto l2011;
hinted[2] = yes(192, 193, 54);
goto l2012;
#if 0
l9280:
#endif
case 28: /* break */
if (obj == mirror)
spk = 148;
if (obj == vase && prop[vase] == 0) {
spk = 198;
if (toting(vase))
drop(vase, loc);
prop[vase] = 2;
fixed[vase] = -1;
goto l2011;
}
if (obj != mirror || !closed)
goto l2011;
rspeak(197);
done(3);
#if 0
l9290:
#endif
case 29: /* wake */
if (obj != dwarf || !closed)
goto l2011;
rspeak(199);
done(3);
default:
bug(24);
}
l5000:
obj = k;
if (fixed[k] != loc && !here(k))
goto l5100;
l5010: if (*wd2 != 0)
goto l2800;
if (verb != 0)
goto l4090;
printf("What do you want to do with the %s?\n", wd1);
goto l2600;
l5100: if (k != grate)
goto l5110;
if (loc == 1 || loc == 4 || loc == 7)
k = dprssn;
if (loc > 9 && loc < 15)
k = entrnc;
if (k != grate)
goto l8;
l5110: if (k != dwarf)
goto l5120;
for (i = 1; i <= 5; i++)
if (dloc[i] == loc && dflag >= 2)
goto l5010;
l5120: if ((liq() == k && here(bottle)) || k == liqloc(loc))
goto l5010;
if (obj != plant || !at(plant2) || prop[plant2] == 0)
goto l5130;
obj = plant2;
goto l5010;
l5130: if (obj != knife || knfloc != loc)
goto l5140;
knfloc = -1;
spk = 116;
goto l2011;
l5140: if (obj != rod || !here(rod2))
goto l5190;
obj = rod2;
goto l5010;
l5190: if ((verb == find || verb == invent) && *wd2 == 0)
goto l5010;
printf("I see no %s here\n", wd1);
goto l2012;
}
}

192
adventure/save.c Normal file
View File

@@ -0,0 +1,192 @@
/* $NetBSD: save.c,v 1.5 1998/09/13 00:07:24 hubertf Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* The game adventure was originally written in Fortran by Will Crowther
* and Don Woods. It was later translated to C and enhanced by Jim
* Gillogly. This code is derived from software contributed to Berkeley
* by Jim Gillogly at The Rand Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)save.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: save.c,v 1.5 1998/09/13 00:07:24 hubertf Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#include <stdlib.h>
#include "hdr.h"
#include "extern.h"
struct savestruct {
void *address;
int width;
};
struct savestruct save_array[] =
{
{&abbnum, sizeof(abbnum)},
{&attack, sizeof(attack)},
{&blklin, sizeof(blklin)},
{&bonus, sizeof(bonus)},
{&chloc, sizeof(chloc)},
{&chloc2, sizeof(chloc2)},
{&clock1, sizeof(clock1)},
{&clock2, sizeof(clock2)},
{&closed, sizeof(closed)},
{&closng, sizeof(closng)},
{&daltlc, sizeof(daltlc)},
{&demo, sizeof(demo)},
{&detail, sizeof(detail)},
{&dflag, sizeof(dflag)},
{&dkill, sizeof(dkill)},
{&dtotal, sizeof(dtotal)},
{&foobar, sizeof(foobar)},
{&gaveup, sizeof(gaveup)},
{&holdng, sizeof(holdng)},
{&iwest, sizeof(iwest)},
{&k, sizeof(k)},
{&k2, sizeof(k2)},
{&knfloc, sizeof(knfloc)},
{&kq, sizeof(kq)},
{&latncy, sizeof(latncy)},
{&limit, sizeof(limit)},
{&lmwarn, sizeof(lmwarn)},
{&loc, sizeof(loc)},
{&maxdie, sizeof(maxdie)},
{&mxscor, sizeof(mxscor)},
{&newloc, sizeof(newloc)},
{&numdie, sizeof(numdie)},
{&obj, sizeof(obj)},
{&oldlc2, sizeof(oldlc2)},
{&oldloc, sizeof(oldloc)},
{&panic, sizeof(panic)},
{&saved, sizeof(saved)},
{&savet, sizeof(savet)},
{&scorng, sizeof(scorng)},
{&spk, sizeof(spk)},
{&stick, sizeof(stick)},
{&tally, sizeof(tally)},
{&tally2, sizeof(tally2)},
{&tkk, sizeof(tkk)},
{&turns, sizeof(turns)},
{&verb, sizeof(verb)},
{&wd1, sizeof(wd1)},
{&wd2, sizeof(wd2)},
{&wzdark, sizeof(wzdark)},
{&yea, sizeof(yea)},
{atloc, sizeof(atloc)},
{dloc, sizeof(dloc)},
{dseen, sizeof(dseen)},
{fixed, sizeof(fixed)},
{hinted, sizeof(hinted)},
{links, sizeof(links)},
{odloc, sizeof(odloc)},
{place, sizeof(place)},
{prop, sizeof(prop)},
{tk, sizeof(tk)},
{NULL, 0}
};
int
save(outfile) /* Two passes on data: first to get checksum,
* second */
const char *outfile; /* to output the data using checksum to start
* random #s */
{
FILE *out;
struct savestruct *p;
char *s;
long sum;
int i;
crc_start();
for (p = save_array; p->address != NULL; p++)
sum = crc(p->address, p->width);
srandom((int) sum);
if ((out = fopen(outfile, "wb")) == NULL) {
fprintf(stderr,
"Hmm. The name \"%s\" appears to be magically blocked.\n",
outfile);
return 1;
}
fwrite(&sum, sizeof(sum), 1, out); /* Here's the random() key */
for (p = save_array; p->address != NULL; p++) {
for (s = p->address, i = 0; i < p->width; i++, s++)
*s = (*s ^ random()) & 0xFF; /* Lightly encrypt */
fwrite(p->address, p->width, 1, out);
}
fclose(out);
return 0;
}
int
restore(infile)
const char *infile;
{
FILE *in;
struct savestruct *p;
char *s;
long sum, cksum = 0;
int i;
if ((in = fopen(infile, "rb")) == NULL) {
fprintf(stderr,
"Hmm. The file \"%s\" appears to be magically blocked.\n",
infile);
return 1;
}
fread(&sum, sizeof(sum), 1, in); /* Get the seed */
srandom((int) sum);
for (p = save_array; p->address != NULL; p++) {
fread(p->address, p->width, 1, in);
for (s = p->address, i = 0; i < p->width; i++, s++)
*s = (*s ^ random()) & 0xFF; /* Lightly decrypt */
}
fclose(in);
crc_start(); /* See if she cheated */
for (p = save_array; p->address != NULL; p++)
cksum = crc(p->address, p->width);
if (sum != cksum) /* Tsk tsk */
return 2; /* Altered the file */
/* We successfully restored, so this really was a save file */
/* Get rid of the file, but don't bother checking that we did */
return 0;
}

125
adventure/setup.c Normal file
View File

@@ -0,0 +1,125 @@
/* $NetBSD: setup.c,v 1.5 1998/09/13 15:23:40 hubertf Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Jim Gillogly at The Rand Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)setup.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: setup.c,v 1.5 1998/09/13 15:23:40 hubertf Exp $");
#endif
#endif /* not lint */
/*
* Setup: keep the structure of the original Adventure port, but use an
* internal copy of the data file, serving as a sort of virtual disk. It's
* lightly encrypted to prevent casual snooping of the executable.
*
* Also do appropriate things to tabs so that bogus editors will do the right
* thing with the data file.
*
*/
#define SIG1 " * Jim Gillogly"
#define SIG2 " * Sterday, 6 Thrimidge S.R. 1993, 15:24"
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include "hdr.h" /* SEED lives in there; keep them coordinated. */
#define USAGE "Usage: setup file > data.c (file is typically glorkz)"
#define YES 1
#define NO 0
#define LINE 10 /* How many values do we get on a line? */
int main __P((int, char *[]));
int
main(argc, argv)
int argc;
char *argv[];
{
FILE *infile;
int c, count, linestart;
if (argc != 2)
errx(1, USAGE);
if ((infile = fopen(argv[1], "r")) == NULL)
err(1, "Can't read file %s", argv[1]);
puts("/*\n * data.c: created by setup from the ascii data file.");
puts(SIG1);
puts(SIG2);
puts(" */");
printf("\n\nchar data_file[] =\n{");
srandom(SEED);
count = 0;
linestart = YES;
while ((c = getc(infile)) != EOF) {
if (linestart && c == ' ') { /* Convert first spaces to tab */
printf("0x%02x,", (unsigned int)('\t' ^ random()) & 0xFF);
while ((c = getc(infile)) == ' ' && c != EOF);
/* Drop the non-whitespace character through */
linestart = NO;
}
switch (c) {
case '\t':
linestart = NO; /* Don't need to convert spaces */
break;
case '\n':
linestart = YES; /* Ready to convert spaces
* again */
break;
}
if (count++ % LINE == 0) /* Finished a line? */
printf("\n\t");
printf("0x%02x,", (unsigned int)(c ^ random()) & 0xFF);
}
puts("\n\t0\n};");
fclose(infile);
exit(0);
}

1058
adventure/subr.c Normal file

File diff suppressed because it is too large Load Diff

229
adventure/vocab.c Normal file
View File

@@ -0,0 +1,229 @@
/* $NetBSD: vocab.c,v 1.9 1998/09/14 09:29:09 hubertf Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* The game adventure was originally written in Fortran by Will Crowther
* and Don Woods. It was later translated to C and enhanced by Jim
* Gillogly. This code is derived from software contributed to Berkeley
* by Jim Gillogly at The Rand Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)vocab.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: vocab.c,v 1.9 1998/09/14 09:29:09 hubertf Exp $");
#endif
#endif /* not lint */
/* Re-coding of advent in C: data structure routines */
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include "hdr.h"
#include "extern.h"
void
dstroy(object)
int object;
{
move(object, 0);
}
void
juggle(object)
int object;
{
int i, j;
i = place[object];
j = fixed[object];
move(object, i);
move(object + 100, j);
}
void
move(object, where)
int object, where;
{
int from;
if (object <= 100)
from = place[object];
else
from = fixed[object - 100];
if (from > 0 && from <= 300)
carry(object, from);
drop(object, where);
}
int
put(object, where, pval)
int object, where, pval;
{
move(object, where);
return (-1 - pval);
}
void
carry(object, where)
int object, where;
{
int temp;
if (object <= 100) {
if (place[object] == -1)
return;
place[object] = -1;
holdng++;
}
if (atloc[where] == object) {
atloc[where] = links[object];
return;
}
for (temp = atloc[where]; links[temp] != object; temp = links[temp]);
links[temp] = links[object];
}
void
drop(object, where)
int object, where;
{
if (object > 100)
fixed[object - 100] = where;
else {
if (place[object] == -1)
holdng--;
place[object] = where;
}
if (where <= 0)
return;
links[object] = atloc[where];
atloc[where] = object;
}
int
vocab(word, type, value) /* look up or store a word */
const char *word;
int type; /* -2 for store, -1 for user word, >=0 for
* canned lookup */
int value; /* used for storing only */
{
int adr;
const char *s;
char *t;
int hash, i;
struct hashtab *h;
for (hash = 0, s = word, i = 0; i < 5 && *s; i++) /* some kind of hash */
hash += *s++; /* add all chars in the word */
hash = (hash * 3719) & 077777; /* pulled that one out of a hat */
hash %= HTSIZE; /* put it into range of table */
for (adr = hash;; adr++) { /* look for entry in table */
if (adr == HTSIZE)
adr = 0;/* wrap around */
h = &voc[adr]; /* point at the entry */
switch (type) {
case -2: /* fill in entry */
if (h->val) /* already got an entry? */
goto exitloop2;
h->val = value;
h->atab = malloc(length(word));
if (h->atab == NULL)
errx(1, "Out of memory!");
for (s = word, t = h->atab; *s;)
*t++ = *s++ ^ '=';
*t = 0 ^ '=';
/* encrypt slightly to thwart core reader */
/* printf("Stored \"%s\" (%d ch) as entry %d\n", */
/* word, length(word), adr); */
return (0); /* entry unused */
case -1: /* looking up user word */
if (h->val == 0)
return (-1); /* not found */
for (s = word, t = h->atab; *t ^ '=';)
if ((*s++ ^ '=') != *t++)
goto exitloop2;
if ((*s ^ '=') != *t && s - word < 5)
goto exitloop2;
/* the word matched o.k. */
return (h->val);
default: /* looking up known word */
if (h->val == 0)
errx(1,"Unable to find %s in vocab", word);
for (s = word, t = h->atab; *t ^ '=';)
if ((*s++ ^ '=') != *t++)
goto exitloop2;
/* the word matched o.k. */
if (h->val / 1000 != type)
continue;
return (h->val % 1000);
}
exitloop2: /* hashed entry does not match */
if (adr + 1 == hash || (adr == HTSIZE && hash == 0))
errx(1,"Hash table overflow");
}
}
void
prht()
{ /* print hash table */
int i, j, l;
char *c;
struct hashtab *h;
for (i = 0; i < HTSIZE / 10 + 1; i++) {
printf("%4d", i * 10);
for (j = 0; j < 10; j++) {
if (i * 10 + j >= HTSIZE)
break;
h = &voc[i * 10 + j];
putchar(' ');
if (h->val == 0) {
printf("-----");
continue;
}
for (l = 0, c = h->atab; l < 5; l++)
if ((*c ^ '='))
putchar(*c++ ^ '=');
else
putchar(' ');
}
putchar('\n');
}
}

164
adventure/wizard.c Normal file
View File

@@ -0,0 +1,164 @@
/* $NetBSD: wizard.c,v 1.8 1998/08/24 22:07:37 hubertf Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* The game adventure was originally written in Fortran by Will Crowther
* and Don Woods. It was later translated to C and enhanced by Jim
* Gillogly. This code is derived from software contributed to Berkeley
* by Jim Gillogly at The Rand Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)wizard.c 8.1 (Berkeley) 6/2/93";
#else
__RCSID("$NetBSD: wizard.c,v 1.8 1998/08/24 22:07:37 hubertf Exp $");
#endif
#endif /* not lint */
/* Re-coding of advent in C: privileged operations */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "hdr.h"
#include "extern.h"
void
datime(d, t)
int *d, *t;
{
time_t tvec;
struct tm *tptr;
time(&tvec);
tptr = localtime(&tvec);
/* day since 1977 (mod leap) */
*d = (tptr->tm_yday + 365 * (tptr->tm_year - 77)
+ (tptr->tm_year - 77) / 4 - (tptr->tm_year - 1) / 100
+ (tptr->tm_year + 299) / 400);
/* bug: this will overflow in the year 2066 AD (with 16 bit int) */
/* it will be attributed to Wm the C's millenial celebration */
/* and minutes since midnite */
*t = tptr->tm_hour * 60 + tptr->tm_min;
} /* pretty painless */
char magic[6];
void
poof()
{
strcpy(magic, DECR('d', 'w', 'a', 'r', 'f'));
latncy = 45;
}
int
Start()
{
int d, t, delay;
datime(&d, &t);
delay = (d - saved) * 1440 + (t - savet); /* good for about a
* month */
if (delay >= latncy) {
saved = -1;
return (FALSE);
}
printf("This adventure was suspended a mere %d minute%s ago.",
delay, delay == 1 ? "" : "s");
if (delay <= latncy / 3) {
mspeak(2);
exit(0);
}
mspeak(8);
if (!wizard()) {
mspeak(9);
exit(0);
}
saved = -1;
return (FALSE);
}
int
wizard()
{ /* not as complex as advent/10 (for now) */
char *word, *x;
if (!yesm(16, 0, 7))
return (FALSE);
mspeak(17);
getin(&word, &x);
if (!weq(word, magic)) {
mspeak(20);
return (FALSE);
}
mspeak(19);
return (TRUE);
}
void
ciao()
{
char *c;
char fname[80];
printf("What would you like to call the saved version?\n");
/* XXX - should use fgetln to avoid arbitrary limit */
for (c = fname;; c++) {
int ch;
ch = getchar();
if (ch == '\n' || ch == EOF)
break;
*c = ch;
}
*c = 0;
if (save(fname) != 0)
return; /* Save failed */
printf("To resume, say \"adventure %s\".\n", fname);
printf("\"With these rooms I might now have been familiarly acquainted.\"\n");
exit(0);
}
int
ran(range)
int range;
{
long i;
i = rand() % range;
return (i);
}

8
arithmetic/Makefile.bsd Normal file
View File

@@ -0,0 +1,8 @@
# $NetBSD: Makefile,v 1.4 1995/03/21 11:59:28 cgd Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= arithmetic
MAN= arithmetic.6
HIDEGAME=hidegame
.include <bsd.prog.mk>

10
arithmetic/Makefrag Normal file
View File

@@ -0,0 +1,10 @@
# Makefrag - makefile fragment for arithmetic
arithmetic_DIRS := $(GAMESDIR) $(MAN6DIR)
arithmetic_all: arithmetic/arithmetic arithmetic/arithmetic.6
arithmetic_install: arithmetic/arithmetic
$(INSTALL_BINARY) arithmetic/arithmetic $(INSTALL_PREFIX)$(GAMESDIR)/arithmetic
$(HIDE_GAME) arithmetic
$(INSTALL_MANUAL) arithmetic/arithmetic.6

107
arithmetic/arithmetic.6 Normal file
View File

@@ -0,0 +1,107 @@
.\" $NetBSD: arithmetic.6,v 1.6 1998/04/28 07:19:28 fair Exp $
.\"
.\" Copyright (c) 1989, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" Eamonn McManus of Trinity College Dublin.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)arithmetic.6 8.1 (Berkeley) 5/31/93
.\"
.Dd May 31, 1993
.Dt ARITHMETIC 6
.Os BSD 4
.Sh NAME
.Nm arithmetic
.Nd quiz on simple arithmetic
.Sh SYNOPSIS
.Nm
.Op Fl o Ar +\-x/
.Op Fl r Ar range
.Sh DESCRIPTION
.Nm
asks you to solve problems in simple arithmetic.
Each question must be answered correctly before going on to the next.
After every 20 problems, it prints the score so far and the time taken.
You can quit at any time by typing the interrupt or end-of-file character.
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl o
By default,
.Nm
asks questions on addition of numbers from 0 to 10, and corresponding
subtraction.
By supplying one or more of the characters
.Ar +\-x/ ,
you can ask for problems in addition, subtraction, multiplication, and
division, respectively.
If you give one of these characters more than once, that kind of problem
will be asked correspondingly more often.
.It Fl r
If a
.Ar range
is supplied,
.Nm
selects the numbers in its problems in the following way.
For addition and multiplication, the numbers to be added or multiplied
are between 0 and
.Ar range ,
inclusive.
For subtraction and division, both the required result and the number to
divide by or subtract will be between 0 and
.Ar range .
(Of course,
.Nm
will not ask you to divide by 0.) The default
.I range
is 10.
.El
.Pp
When you get a problem wrong,
.Nm
will remember the numbers involved, and will tend to select those numbers
more often than others, in problems of the same sort.
Eventually it will forgive and forget.
.Pp
.Nm
cannot be persuaded to tell you the right answer.
You must work it out for yourself.
.Sh DIAGNOSTICS
.Dq What?
if you get a question wrong.
.Dq Right!
if you get it right.
.Dq Please type a number.
if arithmetic doesn't understand what you typed.
.Sh SEE ALSO
.Xr bc 1 ,
.Xr dc 1

396
arithmetic/arithmetic.c Normal file
View File

@@ -0,0 +1,396 @@
/* $NetBSD: arithmetic.c,v 1.12 1998/09/14 09:13:46 hubertf Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Eamonn McManus of Trinity College Dublin.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)arithmetic.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: arithmetic.c,v 1.12 1998/09/14 09:13:46 hubertf Exp $");
#endif
#endif /* not lint */
/*
* By Eamonn McManus, Trinity College Dublin <emcmanus@cs.tcd.ie>.
*
* The operation of this program mimics that of the standard Unix game
* `arithmetic'. I've made it as close as I could manage without examining
* the source code. The principal differences are:
*
* The method of biasing towards numbers that had wrong answers in the past
* is different; original `arithmetic' seems to retain the bias forever,
* whereas this program lets the bias gradually decay as it is used.
*
* Original `arithmetic' delays for some period (3 seconds?) after printing
* the score. I saw no reason for this delay, so I scrapped it.
*
* There is no longer a limitation on the maximum range that can be supplied
* to the program. The original program required it to be less than 100.
* Anomalous results may occur with this program if ranges big enough to
* allow overflow are given.
*
* I have obviously not attempted to duplicate bugs in the original. It
* would go into an infinite loop if invoked as `arithmetic / 0'. It also
* did not recognise an EOF in its input, and would continue trying to read
* after it. It did not check that the input was a valid number, treating any
* garbage as 0. Finally, it did not flush stdout after printing its prompt,
* so in the unlikely event that stdout was not a terminal, it would not work
* properly.
*/
#include <sys/types.h>
#include <err.h>
#include <ctype.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
int getrandom __P((int, int, int));
void intr __P((int)) __attribute__((__noreturn__));
int main __P((int, char *[]));
int opnum __P((int));
void penalise __P((int, int, int));
int problem __P((void));
void showstats __P((void));
void usage __P((void)) __attribute__((__noreturn__));
const char keylist[] = "+-x/";
const char defaultkeys[] = "+-";
const char *keys = defaultkeys;
int nkeys = sizeof(defaultkeys) - 1;
int rangemax = 10;
int nright, nwrong;
time_t qtime;
#define NQUESTS 20
/*
* Select keys from +-x/ to be asked addition, subtraction, multiplication,
* and division problems. More than one key may be given. The default is
* +-. Specify a range to confine the operands to 0 - range. Default upper
* bound is 10. After every NQUESTS questions, statistics on the performance
* so far are printed.
*/
int
main(argc, argv)
int argc;
char **argv;
{
extern char *optarg;
extern int optind;
int ch, cnt;
/* Revoke setgid privileges */
setregid(getgid(), getgid());
while ((ch = getopt(argc, argv, "r:o:")) != -1)
switch(ch) {
case 'o': {
const char *p;
for (p = keys = optarg; *p; ++p)
if (!strchr(keylist, *p))
errx(1, "arithmetic: unknown key.");
nkeys = p - optarg;
break;
}
case 'r':
if ((rangemax = atoi(optarg)) <= 0)
errx(1, "arithmetic: invalid range.");
break;
case '?':
default:
usage();
}
if (argc -= optind)
usage();
/* Seed the random-number generator. */
srandom((int)time((time_t *)NULL));
(void)signal(SIGINT, intr);
/* Now ask the questions. */
for (;;) {
for (cnt = NQUESTS; cnt--;)
if (problem() == EOF)
exit(0);
showstats();
}
/* NOTREACHED */
}
/* Handle interrupt character. Print score and exit. */
void
intr(dummy)
int dummy __attribute__((unused));
{
showstats();
exit(0);
}
/* Print score. Original `arithmetic' had a delay after printing it. */
void
showstats()
{
if (nright + nwrong > 0) {
(void)printf("\n\nRights %d; Wrongs %d; Score %d%%",
nright, nwrong, (int)(100L * nright / (nright + nwrong)));
if (nright > 0)
(void)printf("\nTotal time %ld seconds; %.1f seconds per problem\n\n",
(long)qtime, (float)qtime / nright);
}
(void)printf("\n");
}
/*
* Pick a problem and ask it. Keeps asking the same problem until supplied
* with the correct answer, or until EOF or interrupt is typed. Problems are
* selected such that the right operand and either the left operand (for +, x)
* or the correct result (for -, /) are in the range 0 to rangemax. Each wrong
* answer causes the numbers in the problem to be penalised, so that they are
* more likely to appear in subsequent problems.
*/
int
problem()
{
char *p;
time_t start, finish;
int left, op, right, result;
char line[80];
right = left = result = 0;
op = keys[random() % nkeys];
if (op != '/')
right = getrandom(rangemax + 1, op, 1);
retry:
/* Get the operands. */
switch (op) {
case '+':
left = getrandom(rangemax + 1, op, 0);
result = left + right;
break;
case '-':
result = getrandom(rangemax + 1, op, 0);
left = right + result;
break;
case 'x':
left = getrandom(rangemax + 1, op, 0);
result = left * right;
break;
case '/':
right = getrandom(rangemax, op, 1) + 1;
result = getrandom(rangemax + 1, op, 0);
left = right * result + random() % right;
break;
}
/*
* A very big maxrange could cause negative values to pop
* up, owing to overflow.
*/
if (result < 0 || left < 0)
goto retry;
(void)printf("%d %c %d = ", left, op, right);
(void)fflush(stdout);
(void)time(&start);
/*
* Keep looping until the correct answer is given, or until EOF or
* interrupt is typed.
*/
for (;;) {
if (!fgets(line, sizeof(line), stdin)) {
(void)printf("\n");
return(EOF);
}
for (p = line; *p && isspace(*p); ++p);
if (!isdigit(*p)) {
(void)printf("Please type a number.\n");
continue;
}
if (atoi(p) == result) {
(void)printf("Right!\n");
++nright;
break;
}
/* Wrong answer; penalise and ask again. */
(void)printf("What?\n");
++nwrong;
penalise(right, op, 1);
if (op == 'x' || op == '+')
penalise(left, op, 0);
else
penalise(result, op, 0);
}
/*
* Accumulate the time taken. Obviously rounding errors happen here;
* however they should cancel out, because some of the time you are
* charged for a partially elapsed second at the start, and some of
* the time you are not charged for a partially elapsed second at the
* end.
*/
(void)time(&finish);
qtime += finish - start;
return(0);
}
/*
* Here is the code for accumulating penalties against the numbers for which
* a wrong answer was given. The right operand and either the left operand
* (for +, x) or the result (for -, /) are stored in a list for the particular
* operation, and each becomes more likely to appear again in that operation.
* Initially, each number is charged a penalty of WRONGPENALTY, giving it that
* many extra chances of appearing. Each time it is selected because of this,
* its penalty is decreased by one; it is removed when it reaches 0.
*
* The penalty[] array gives the sum of all penalties in the list for
* each operation and each operand. The penlist[] array has the lists of
* penalties themselves.
*/
int penalty[sizeof(keylist) - 1][2];
struct penalty {
int value, penalty; /* Penalised value and its penalty. */
struct penalty *next;
} *penlist[sizeof(keylist) - 1][2];
#define WRONGPENALTY 5 /* Perhaps this should depend on maxrange. */
/*
* Add a penalty for the number `value' to the list for operation `op',
* operand number `operand' (0 or 1). If we run out of memory, we just
* forget about the penalty (how likely is this, anyway?).
*/
void
penalise(value, op, operand)
int value, op, operand;
{
struct penalty *p;
op = opnum(op);
if ((p = (struct penalty *)malloc((u_int)sizeof(*p))) == NULL)
return;
p->next = penlist[op][operand];
penlist[op][operand] = p;
penalty[op][operand] += p->penalty = WRONGPENALTY;
p->value = value;
}
/*
* Select a random value from 0 to maxval - 1 for operand `operand' (0 or 1)
* of operation `op'. The random number we generate is either used directly
* as a value, or represents a position in the penalty list. If the latter,
* we find the corresponding value and return that, decreasing its penalty.
*/
int
getrandom(maxval, op, operand)
int maxval, op, operand;
{
int value;
struct penalty **pp, *p;
op = opnum(op);
value = random() % (maxval + penalty[op][operand]);
/*
* 0 to maxval - 1 is a number to be used directly; bigger values
* are positions to be located in the penalty list.
*/
if (value < maxval)
return(value);
value -= maxval;
/*
* Find the penalty at position `value'; decrement its penalty and
* delete it if it reaches 0; return the corresponding value.
*/
for (pp = &penlist[op][operand]; (p = *pp) != NULL; pp = &p->next) {
if (p->penalty > value) {
value = p->value;
penalty[op][operand]--;
if (--(p->penalty) <= 0) {
p = p->next;
(void)free((char *)*pp);
*pp = p;
}
return(value);
}
value -= p->penalty;
}
/*
* We can only get here if the value from the penalty[] array doesn't
* correspond to the actual sum of penalties in the list. Provide an
* obscure message.
*/
errx(1, "arithmetic: bug: inconsistent penalties.");
/* NOTREACHED */
}
/* Return an index for the character op, which is one of [+-x/]. */
int
opnum(op)
int op;
{
char *p;
if (op == 0 || (p = strchr(keylist, op)) == NULL)
errx(1, "arithmetic: bug: op %c not in keylist %s",
op, keylist);
return(p - keylist);
}
/* Print usage message and quit. */
void
usage()
{
extern char *__progname; /* from crt0.o */
(void)fprintf(stderr, "usage: %s [-o +-x/] [-r range]\n",
__progname);
exit(1);
}

4
atc/BUGS Normal file
View File

@@ -0,0 +1,4 @@
log restarts if interrupted
Still refreshes after exit
Should ^Z be disabled?
does not exit after hup

23
atc/Makefile.bsd Normal file
View File

@@ -0,0 +1,23 @@
# $NetBSD: Makefile,v 1.19 1998/09/13 15:22:59 hubertf Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= atc
CPPFLAGS+=-DBSD -I${.CURDIR} -I. -DYY_NO_UNPUT
SRCS= extern.c grammar.y graphics.c input.c lex.l list.c log.c \
main.c tunable.c update.c
YHEADER=1
MAN= atc.6
LDADD= -ll -lm -lcurses
DPADD= ${LIBL} ${LIBM} ${LIBCURSES}
GAMES= Game_List Killer crossover default easy game_2 \
Atlantis OHare Tic-Tac-Toe airports box crosshatch game_3 \
game_4 novice two-corners
HIDEGAME=hidegame
SETGIDGAME=yes
FILES=${GAMES:S@^@${.CURDIR}/games/@g}
FILESDIR=/usr/share/games/atc
FILESMODE=440
lex.o: grammar.h
.include <bsd.prog.mk>

27
atc/Makefrag Normal file
View File

@@ -0,0 +1,27 @@
# Makefrag - makefile fragment for atc
atc_CLEANFILES := grammar.c grammar.h y.tab.* lex.c lex.yy.c
atc_DEFS := -DBSD -DYY_NO_UNPUT
atc_DIRS := $(GAMESDIR) $(MAN6DIR)
atc_all: atc/atc atc/atc.6
atc/grammar.c: atc/grammar.y
cd atc && $(YACC) -d grammar.y
mv atc/y.tab.c $@
mv atc/y.tab.h atc/grammar.h
touch atc/grammar.h
atc/grammar.h: atc/grammar.c
atc/lex.d: atc/grammar.h
atc/lex.c: atc/lex.l
cd atc && $(LEX) lex.l
mv atc/lex.yy.c $@
atc_install: atc_all
$(INSTALL_SCORE_GAME) atc/atc $(INSTALL_PREFIX)$(GAMESDIR)/atc
$(HIDE_GAME) atc
$(INSTALL_SCORE_FILE) $(ATC_SCOREFILE)
$(INSTALL_MANUAL) atc/atc.6

600
atc/atc.6 Normal file
View File

@@ -0,0 +1,600 @@
.\" $NetBSD: atc.6,v 1.4 1998/07/24 23:36:59 briggs Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" Ed James.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)atc.6 8.1 (Berkeley) 5/31/93
.\"
. \" XP - exdented paragraph
.de XP
.RT
.if \\n(1T .sp \\n(PDu
.ne 1.1
.if !\\n(IP .nr IP +1
.in +\\n(I\\n(IRu
.ti -\\n(I\\n(IRu
..
.\" Copyright (c) 1986 Ed James. All rights reserved.
.\"
.TH ATC 6 "May 31, 1993"
.UC
.SH NAME
atc \- air traffic controller game
.SH SYNOPSIS
.B atc
-[u?lstp] [-[gf] game_name] [-r random seed]
.SH DESCRIPTION
.LP
.I Atc
lets you try your hand at the nerve wracking duties of the air traffic
controller without endangering the lives of millions of
travelers each year.
Your responsibilities require you to direct the flight of jets
and prop planes into and out of the flight arena and airports.
The speed (update time) and frequency of the planes depend on the
difficulty of the chosen arena.
.SH OPTIONS
.LP
.TP 8
.B \-u
Print the usage line and exit.
.TP
.B \-?
Same as
.B \-u.
.TP
.B \-l
Print a list of available games and exit.
The first game name printed is the default game.
.TP
.B \-s
Print the score list (formerly the Top Ten list).
.TP
.B \-t
Same as
.B \-s.
.TP
.B \-p
Print the path to the special directory where
.I atc
expects to find its private files. This is used during the
installation of the program.
.TP
.B "\-g game"
Play the named game. If the game listed is not one of the
ones printed from the
.B \-l
option, the default game is played.
.TP
.B "\-f game"
Same as
.B \-g.
.TP
.B "\-r seed"
Set the random seed. The purpose of this flag is questionable.
.SH GOALS
.LP
Your goal in
.I atc
is to keep the game going as long as possible.
There is no winning state, except to beat the times of other players.
You will need to: launch planes at airports (by instructing them to
increase their altitude); land planes at airports (by instructing them to
go to altitude zero when exactly over the airport); and maneuver planes
out of exit points.
.LP
Several things will cause the end of the game.
Each plane has a destination (see information area), and
sending a plane to the wrong destination is an error.
Planes can run out of fuel, or can collide. Collision is defined as
adjacency in all three dimensions. A plane leaving the arena
in any other way than through its destination exit is an error as well.
.LP
Scores are sorted in order of the number of planes safe. The other
statistics are provided merely for fun. There is no penalty for
taking longer than another player (except in the case of ties).
.LP
Suspending a game is not permitted. If you get a talk message, tough.
When was the last time an Air Traffic Controller got called away to
the phone?
.SH "THE DISPLAY"
.LP
Depending on the terminal you run
.I atc
on, the screen will be divided into 4 areas.
It should be stressed that the terminal driver portion of the
game was designed to be reconfigurable, so the display format can vary
depending the version you are playing. The descriptions here are based
on the ascii version
of the game. The game rules and input format, however,
should remain consistent.
Control-L redraws the screen, should it become muddled.
.SS RADAR
.IP
The first screen area is the radar display, showing the relative locations
of the planes, airports, standard entry/exit points, radar
beacons, and "lines" which simply serve to aid you in guiding
the planes.
.IP
Planes are shown as a single letter with an altitude. If
the numerical altitude is a single digit, then it represents
thousands of feet.
Some distinction is made between the prop
planes and the jets. On ascii terminals, prop planes are
represented by a upper case letter, jets by a lower case letter.
.IP
Airports are shown as a number and some indication of the direction
planes must be going to land at the airport.
On ascii terminals, this is one of '^', '>', '<', and 'v', to indicate
north (0 degrees), east (90), west (270) and south (180), respectively.
The planes will also
take off in this direction.
.IP
Beacons are represented as circles or asterisks and a number.
Their purpose is to offer a place of easy reference to the plane pilots.
See 'the delay command' under the input section of this manual.
.IP
Entry/exit points are displayed as numbers along the border of the
radar screen. Planes will enter the arena from these points without
warning. These points have a direction associated with them, and
planes will always enter the arena from this direction. On the
ascii version of
.I atc,
this direction is not displayed. It will become apparent
what this direction is as the game progresses.
.IP
Incoming planes will always enter at the same altitude: 7000 feet.
For a plane to successfully depart through an entry/exit point,
it must be flying at 9000 feet.
It is not necessary for the planes to be flying in any particular
direction when they leave the arena (yet).
.SS "INFORMATION AREA"
.IP
The second area of the display is the information area, which lists
the time (number of updates since start), and the number of planes you
have directed safely out of the arena.
Below this is a list of planes currently in the air, followed by a
blank line, and then a list of planes on the ground (at airports).
Each line lists the plane name and its current altitude,
an optional asterisk indicating low fuel, the plane's destination,
and the plane's current command. Changing altitude is not considered
to be a command and is therefore not displayed. The following are
some possible information lines:
.IP
B4*A0: Circle @ b1
.br
g7 E4: 225
.IP
The first example shows a prop plane named 'B' that is flying at 4000
feet. It is low on fuel (note the '*'). It's destination is
Airport #0.
The next command it expects
to do is circle when it reaches Beacon #1.
The second example shows a jet named 'g' at 7000 feet, destined for
Exit #4. It is just now executing a turn to 225 degrees (South-West).
.SS "INPUT AREA"
.IP
The third area of the display is the input area. It is here that
your input is reflected. See the INPUT heading of this manual
for more details.
.SS "AUTHOR AREA"
.IP
This area is used simply to give credit where credit is due. :-)
.SH INPUT
.LP
A command completion interface is built into
the game. At any time, typing '?' will list possible input characters.
Typing a backspace (your erase character) backs up, erasing the last part
of the command. When a command is complete, a return enters it, and
any semantic checking is done at that time. If no errors are detected,
the command is sent to the appropriate plane. If an error is discovered
during the check, the offending statement will be underscored and a
(hopefully) descriptive message will be printed under it.
.LP
The command syntax is broken into two parts:
.I "Immediate Only"
and
.I Delayable
commands.
.I "Immediate Only"
commands happen on the next
update.
.I Delayable
commands also happen on the next update unless they
are followed by an optional predicate called the
.I Delay
command.
.LP
In the following tables, the syntax
.B [0\-9]
means any single digit, and
.B <dir>
refers to the keys around the 's' key, namely ``wedcxzaq''.
In absolute references, 'q' refers to North-West or 315 degrees, and 'w'
refers to North, or 0 degrees.
In relative references, 'q' refers to -45 degrees or 45 degrees left, and 'w'
refers to 0 degrees, or no change in direction.
.LP
All commands start with a plane letter. This indicates the recipient
of the command. Case is ignored.
.SS "IMMEDIATE ONLY COMMANDS"
.RS
.B "\- a Altitude:"
.RS
Affect a plane's altitude (and take off).
.RE
.RS
.B "\- [0\-9] Number:"
.RS
Go to the given altitude (thousands of feet).
.RE
.B "\- c/+ Climb:"
.RS
Relative altitude change.
.RE
.RS
.B "\- [0\-9] Number:"
.RS
Difference in thousands of feet.
.RE
.RE
.B "\- d/\- Descend:"
.RS
Relative altitude change.
.RE
.RS
.B "\- [0\-9] Number:"
.RS
Difference in thousands of feet.
.RE
.RE
.RE
.B "\- m Mark:"
.RS
Display in highlighted mode. Command is displayed normally.
.RE
.B "\- i Ignore:"
.RS
Do not display highlighted. Command is displayed as a
line of dashes if there is no command.
.RE
.B "\- u Unmark:"
.RS
Same as ignore, but if a delayed command is processed,
the plane will become marked. This is useful if you want
to forget about a plane during part, but not all, of its
journey.
.RE
.RE
.SS "DELAYABLE COMMANDS"
.RS
.B "\- c Circle:"
.RS
Have the plane circle (clockwise by default).
.RE
.RS
.B "\- l Left:"
.RS
Circle counterclockwise.
.RE
.B "\- r Right:"
.RS
Circle clockwise.
.RE
.RE
.B "\- t Turn:"
.RS
Change direction.
.RE
.RS
.B "\- l Left:"
.RS
Turn counterclockwise (45 degrees by default).
.RE
.RS
.B "\- <dir> Direction:"
.RS
Turn ccw the given number of degrees.
Zero degrees is no turn. A ccw turn
of -45 degrees is 45 cw.
.RE
.RE
.B "\- r Right:"
.RS
Turn clockwise (45 degrees by default).
.RE
.RS
.B "\- <dir> Direction:"
.RS
Same as turn left <dir>.
.RE
.RE
.B "\- L Left 90:"
.RS
Turn counterclockwise 90 degrees.
.RE
.B "\- R Right 90:"
.RS
Turn clockwise 90 degrees.
.RE
.B "\- <dir> Direction:"
.RS
Turn to the absolute compass heading given.
The shortest turn will be taken.
.RE
.B "\- t Towards:"
.RS
Turn towards a beacon, airport or exit. The turn is
just an estimate.
.RE
.RS
.B "\- b/* Beacon:"
.RS
Turn towards the beacon.
.RE
.RS
.B "\- [0-9] Number:"
.RS
The beacon number.
.RE
.RE
.B "\- e Exit:"
.RS
Turn towards the exit.
.RE
.RS
.B "\- [0-9] Number:"
.RS
The exit number.
.RE
.RE
.B "\- a Airport:"
.RS
Turn towards the airport.
.RE
.RS
.B "\- [0-9] Number:"
.RS
The airport number.
.RE
.RE
.RE
.RE
.RE
.SS THE DELAY COMMAND
.LP
The
.B Delay
(a/@)
command may be appended to any
.B Delayable
command. It allows the controller to instruct a plane to do an action
when the plane reaches a particular beacon (or other objects in future
versions).
.sp
.RS
.B "\- a/@ At:"
.RS
Do the given delayable command when the plane reaches the given beacon.
.RE
.RS
.B "\- b/* Beacon:"
.RS
This is redundant to allow for expansion.
.RE
.RS
.B "\- [0-9] Number:"
.RS
The beacon number.
.RE
.RE
.RE
.RE
.SS "MARKING, UNMARKING AND IGNORING"
.LP
Planes are
.B marked
when they enter the arena. This means they are displayed in highlighted
mode on the radar display. A plane may also be either
.B unmarked
or
.B ignored.
An
.B unmarked
plane is drawn in unhighlighted mode, and a line of dashes is displayed in
the command field of the information area. The plane will remain this
way until a mark command has been issued. Any other command will be issued,
but the command line will return to a line of dashes when the command
is completed.
.LP
An
.B ignored
plane is treated the same as an unmarked plane, except that it will
automatically switch to
.B marked
status when a delayed command has been processed. This is useful if
you want to forget about a plane for a while, but its flight path has
not yet been completely set.
.LP
As with all of the commands, marking, unmarking and ignoring will take effect
at the beginning of the next update. Do not be surprised if the plane does
not immediately switch to unhighlighted mode.
.SS EXAMPLES
.RS
.TP 16
atlab1
a: turn left at beacon #1
.TP 16
cc
C: circle
.TP 16
gtte4ab2
g: turn towards exit #4 at beacon #2
.TP 16
ma+2
m: altitude: climb 2000 feet
.TP 16
stq
S: turn to 315
.TP 16
xi
x: ignore
.RE
.SH "OTHER INFORMATION"
.LP
Jets move every update; prop planes move every other update.
.LP
All planes turn a most 90 degrees per movement.
.LP
Planes enter at 7000 feet and leave at 9000 feet.
.LP
Planes flying at an altitude of 0 crash if they are not over an airport.
.LP
Planes waiting at airports can only be told to take off (climb in altitude).
.SH "NEW GAMES"
.LP
The
.B Game_List
file lists the currently available play fields. New field description
file names must be placed in this file to be 'playable'. If a player
specifies a game not in this file, his score will not be logged.
.LP
The game field description files are broken into two parts. The first
part is the definition section. Here, the four tunable game parameters
must be set. These variables are set with the syntax:
.IP
variable = number;
.LP
Variable may be one of:
.B update,
indicating the number of seconds between forced updates;
.B newplane,
indicating (about) the number of updates between new plane entries;
.B width,
indicating the width of the play field; and
.B height,
indicating the height of the play field.
.LP
The second part of the field description files describes the locations
of the exits, the beacons, the airports and the lines.
The syntax is as follows:
.IP
beacon: (x y) ... ;
.br
airport: (x y direction) ... ;
.br
exit: (x y direction) ... ;
.br
line: [ (x1 y1) (x2 y2) ] ... ;
.LP
For beacons, a simple x, y coordinate pair is used (enclosed in parenthesis).
Airports and exits require a third value, a direction, which is one
of
.B wedcxzaq.
For airports, this is the direction that planes must be going to take
off and land, and for exits, this is the direction that planes will going
when they
.B enter
the arena. This may not seem intuitive, but as there is no restriction on
direction of exit, this is appropriate.
Lines are slightly different, since they need two coordinate pairs to
specify the line endpoints. These endpoints must be enclosed in
square brackets.
.LP
All statements are semi-colon (;) terminated. Multiple item statements
accumulate. Each definition must occur exactly once, before any
item statements. Comments begin with a hash (#) symbol
and terminate with a newline.
The coordinates are between zero and width-1 and height-1
inclusive. All of the exit coordinates must lie on the borders, and
all of the beacons and airports must lie inside of the borders.
Line endpoints may be anywhere within the field, so long as
the lines are horizontal, vertical or
.B "exactly diagonal."
.SS "FIELD FILE EXAMPLE"
.RS
.sp
.nf
.TA 1i 1i
.ta 1i 1i
# This is the default game.
update = 5;
newplane = 5;
width = 30;
height = 21;
exit: ( 12 0 x ) ( 29 0 z ) ( 29 7 a ) ( 29 17 a )
( 9 20 e ) ( 0 13 d ) ( 0 7 d ) ( 0 0 c ) ;
beacon: ( 12 7 ) ( 12 17 ) ;
airport: ( 20 15 w ) ( 20 18 d ) ;
line: [ ( 1 1 ) ( 6 6 ) ]
[ ( 12 1 ) ( 12 6 ) ]
[ ( 13 7 ) ( 28 7 ) ]
[ ( 28 1 ) ( 13 16 ) ]
[ ( 1 13 ) ( 11 13 ) ]
[ ( 12 8 ) ( 12 16 ) ]
[ ( 11 18 ) ( 10 19 ) ]
[ ( 13 17 ) ( 28 17 ) ]
[ ( 1 7 ) ( 11 7 ) ] ;
.fi
.RE
.SH FILES
.LP
Files are kept in a special directory. See the OPTIONS for a way to
print this path out.
.TP 16
.B ATC_score
Where the scores are kept.
.TP 16
.B Game_List
The list of playable games.
.SH AUTHOR
.LP
Ed James, UC Berkeley: edjames@ucbvax.berkeley.edu, ucbvax!edjames
.LP
This game is based on someone's description of the overall flavor
of a game written for some unknown PC many years ago, maybe.
.SH BUGS
.LP
The screen sometimes refreshes after you have quit.
.LP
Yet Another Curses Bug was discovered during the development of this game.
If your curses library clrtobot.o is version 5.1 or earlier,
you will have erase problems with the backspace operator in the input
window.

89
atc/def.h Normal file
View File

@@ -0,0 +1,89 @@
/* $NetBSD: def.h,v 1.4 1998/09/11 12:53:28 hubertf Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)def.h 8.1 (Berkeley) 5/31/93
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#define AUTHOR_STR "ATC - by Ed James"
#ifndef PI
#define PI 3.14159265358979323846
#endif
#define LOWFUEL 15
#define REALLOC 10
#define SGN(x) ((x < 0) ? -1 : ((x > 0) ? 1 : 0))
#define ABS(x) ((x < 0) ? -(x) : (x))
#define DIR_FROM_DXDY(dx,dy) ((int) (atan2((double)(dy), (double)(dx)) \
* MAXDIR / (2 * PI) + 2.5 + MAXDIR) % MAXDIR)
#define MAXDIR 8
#define D_LEFT 1
#define D_RIGHT 2
#define D_UP 3
#define D_DOWN 4
#define T_NODEST 0
#define T_BEACON 1
#define T_EXIT 2
#define T_AIRPORT 3
#undef S_NONE
#undef S_GONE
#undef S_MARKED
#undef S_UNMARKED
#undef S_IGNORED
#define S_NONE 0
#define S_GONE 1
#define S_MARKED 2
#define S_UNMARKED 3
#define S_IGNORED 4
#define INPUT_LINES 3
#define PLANE_COLS 20

82
atc/extern.c Normal file
View File

@@ -0,0 +1,82 @@
/* $NetBSD: extern.c,v 1.5 1997/10/10 02:07:04 lukem Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)extern.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: extern.c,v 1.5 1997/10/10 02:07:04 lukem Exp $");
#endif
#endif /* not lint */
#include "include.h"
char GAMES[] = "Game_List";
int clck, safe_planes, start_time, test_mode;
const char *file;
FILE *filein, *fileout;
C_SCREEN screen, *sp = &screen;
LIST air, ground;
struct termios tty_start, tty_new;
DISPLACEMENT displacement[MAXDIR] = {
{ 0, -1 },
{ 1, -1 },
{ 1, 0 },
{ 1, 1 },
{ 0, 1 },
{ -1, 1 },
{ -1, 0 },
{ -1, -1 }
};

140
atc/extern.h Normal file
View File

@@ -0,0 +1,140 @@
/* $NetBSD: extern.h,v 1.6 1998/09/13 15:27:26 hubertf Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)extern.h 8.1 (Berkeley) 5/31/93
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
extern char GAMES[];
extern const char *file;
extern int clck, safe_planes, start_time, test_mode;
extern FILE *filein, *fileout;
extern C_SCREEN screen, *sp;
extern LIST air, ground;
extern struct termios tty_start, tty_new;
extern DISPLACEMENT displacement[MAXDIR];
int addplane __P((void));
void append __P((LIST *, PLANE *));
void check_adir __P((int, int, int));
void check_edge __P((int, int));
void check_edir __P((int, int, int));
void check_line __P((int, int, int, int));
void check_linepoint __P((int, int));
void check_point __P((int, int));
int checkdefs __P((void));
int compar __P((const void *, const void *));
void delete __P((LIST *, PLANE *));
int dir_deg __P((int));
int dir_no __P((char));
void done_screen __P((void));
void draw_all __P((void));
void draw_line __P((WINDOW *, int, int, int, int, const char *));
void erase_all __P((void));
int getAChar __P((void));
int getcommand __P((void));
int gettoken __P((void));
void init_gr __P((void));
void ioaddstr __P((int, const char *));
void ioclrtobot __P((void));
void ioclrtoeol __P((int));
void ioerror __P((int, int, const char *));
void iomove __P((int));
int list_games __P((void));
int log_score __P((int));
void log_score_quit __P((int)) __attribute__((__noreturn__));
void loser __P((const PLANE *, const char *)) __attribute__((__noreturn__));
int main __P((int, char *[]));
char name __P((const PLANE *));
int next_plane __P((void));
void noise __P((void));
int number __P((char));
void open_score_file __P((void));
void planewin __P((void));
int pop __P((void));
void push __P((int, int));
void quit __P((int));
int read_file __P((const char *));
void redraw __P((void));
void rezero __P((void));
void setup_screen __P((const C_SCREEN *));
int too_close __P((const PLANE *p1, const PLANE *p2, int));
void update __P((int));
int yyerror __P((const char *));
int yylex __P((void));
int yyparse __P((void));
const char *Left __P((char));
const char *Right __P((char));
const char *airport __P((char));
const char *beacon __P((char));
const char *benum __P((char));
const char *circle __P((char));
const char *climb __P((char));
const char *command __P((const PLANE *));
const char *default_game __P((void));
const char *delayb __P((char));
const char *descend __P((char));
const char *ex_it __P((char));
PLANE *findplane __P((int));
const char *ignore __P((char));
const char *left __P((char));
const char *mark __P((char));
PLANE *newplane __P((void));
const char *okay_game __P((const char *));
const char *rel_dir __P((char));
const char *right __P((char));
const char *setalt __P((char));
const char *setplane __P((char));
const char *setrelalt __P((char));
const char *timestr __P((int));
const char *to_dir __P((char));
const char *turn __P((char));
const char *unmark __P((char));

31
atc/games/Atlantis Normal file
View File

@@ -0,0 +1,31 @@
update = 5;
newplane = 5;
width = 30;
height = 21;
exit: ( 10 0 x )
( 29 6 a )
( 27 20 q )
( 0 16 d ) ;
beacon: ( 10 6 ) ( 23 6 )
( 23 16 ) ( 15 16 ) ( 7 16 )
( 7 9 ) ( 15 6 ) ;
airport: ( 23 8 x ) ( 15 12 w ) ;
line: [ ( 10 1 ) ( 10 5 ) ]
[ ( 11 6 ) ( 14 6 ) ]
[ ( 16 6 ) ( 22 6 ) ]
[ ( 24 6 ) ( 28 6 ) ]
[ ( 1 16 ) ( 6 16 ) ]
[ ( 8 16 ) ( 14 16 ) ]
[ ( 16 16 ) ( 22 16 ) ]
[ ( 23 7 ) ( 23 7 ) ]
[ ( 23 9 ) ( 23 15 ) ]
[ ( 15 7 ) ( 15 11 ) ]
[ ( 15 13 ) ( 15 15 ) ]
[ ( 7 10 ) ( 7 15 ) ]
[ ( 9 7 ) ( 8 8 ) ]
[ ( 6 10 ) ( 1 15 ) ]
[ ( 24 17 ) ( 26 19 ) ] ;

15
atc/games/Game_List Normal file
View File

@@ -0,0 +1,15 @@
default
easy
crossover
Killer
game_2
Atlantis
OHare
Tic-Tac-Toe
airports
box
crosshatch
game_3
game_4
novice
two-corners

21
atc/games/Killer Normal file
View File

@@ -0,0 +1,21 @@
update = 1;
newplane = 4;
width = 30;
height = 21;
exit: ( 29 7 a ) ( 29 17 a )
( 0 7 d ) ( 0 0 c ) ;
beacon: ( 12 7 ) ( 12 17 ) ( 14 10 ) ( 20 15 ) ;
airport: ( 20 18 d ) ;
line: [ ( 1 1 ) ( 6 6 ) ]
[ ( 12 1 ) ( 12 6 ) ]
[ ( 13 7 ) ( 28 7 ) ]
[ ( 28 1 ) ( 13 16 ) ]
[ ( 1 13 ) ( 11 13 ) ]
[ ( 12 8 ) ( 12 16 ) ]
[ ( 11 18 ) ( 10 19 ) ]
[ ( 13 17 ) ( 28 17 ) ]
[ ( 1 7 ) ( 11 7 ) ] ;

14
atc/games/Makefrag Normal file
View File

@@ -0,0 +1,14 @@
# Makefrag - makefile fragment for atc/games
atc_games_DIRS := $(ATC_DIR)
atc_games_GAMES := atc/games/Game_List atc/games/default atc/games/easy \
atc/games/crossover atc/games/Killer atc/games/game_2 \
atc/games/Atlantis atc/games/OHare atc/games/Tic-Tac-Toe \
atc/games/airports atc/games/box atc/games/crosshatch \
atc/games/game_3 atc/games/game_4 atc/games/novice \
atc/games/two-corners
atc_games_all: $(atc_games_GAMES)
atc_games_install:
set -e; for g in Game_List `cat atc/games/Game_List`; do $(INSTALL_DATA) atc/games/$$g $(INSTALL_PREFIX)$(ATC_DIR)/$$g; done

23
atc/games/OHare Normal file
View File

@@ -0,0 +1,23 @@
update = 5;
newplane = 5;
width = 30;
height = 21;
exit: ( 6 0 x ) ( 18 0 x )
( 29 5 a ) ( 29 13 a )
( 14 20 e ) ( 6 20 w ) ;
beacon: ( 6 5 ) ( 18 5 )
( 6 13 ) ;
airport: ( 8 8 d ) ;
line: [ ( 6 1 ) ( 6 4 ) ]
[ ( 18 1 ) ( 18 4 ) ]
[ ( 6 6 ) ( 6 12 ) ]
[ ( 6 14 ) ( 6 19 ) ]
[ ( 28 6 ) ( 15 19 ) ]
[ ( 7 13 ) ( 20 13 ) ]
[ ( 22 13 ) ( 28 13 ) ]
[ ( 7 5 ) ( 17 5 ) ]
[ ( 19 5 ) ( 28 5 ) ] ;

25
atc/games/Tic-Tac-Toe Normal file
View File

@@ -0,0 +1,25 @@
update = 5;
newplane = 5;
width = 30;
height = 21;
exit: ( 10 0 x ) ( 19 0 x )
( 29 7 a ) ( 29 13 a )
( 19 20 w ) ( 10 20 w )
( 0 13 d ) ( 0 7 d ) ;
beacon: ( 10 7 ) ( 19 7 )
( 19 13 ) ( 10 13 ) ;
line: [ ( 10 1 ) ( 10 6 ) ]
[ ( 19 1 ) ( 19 6 ) ]
[ ( 1 7 ) ( 9 7 ) ]
[ ( 11 7 ) ( 18 7 ) ]
[ ( 20 7 ) ( 28 7 ) ]
[ ( 10 8 ) ( 10 12 ) ]
[ ( 19 8 ) ( 19 12 ) ]
[ ( 1 13 ) ( 9 13 ) ]
[ ( 11 13 ) ( 18 13 ) ]
[ ( 20 13 ) ( 28 13 ) ]
[ ( 10 14 ) ( 10 19 ) ]
[ ( 19 14 ) ( 19 19 ) ] ;

30
atc/games/airports Normal file
View File

@@ -0,0 +1,30 @@
update = 6;
newplane = 6;
width = 30;
height = 21;
exit: ( 13 0 x ) ( 0 10 d ) ;
beacon: ( 6 3 ) ( 19 4 ) ( 27 4 )
( 27 10 )
( 27 16 ) ( 13 16 ) ( 6 16 )
( 13 10 )
( 19 10 ) ;
airport: ( 6 5 w ) ( 23 4 a )
( 19 7 w ) ( 25 10 d )
( 24 16 a ) ( 13 13 x )
( 6 13 w ) ;
line: [ ( 13 1 ) ( 13 9 ) ]
[ ( 13 11 ) ( 13 12 ) ]
[ ( 13 14 ) ( 13 15 ) ]
[ ( 7 16 ) ( 12 16 ) ]
[ ( 18 5 ) ( 14 9 ) ]
[ ( 6 14 ) ( 6 15 ) ]
[ ( 6 11 ) ( 6 12 ) ]
[ ( 6 6 ) ( 6 9 ) ]
[ ( 1 10 ) ( 12 10 ) ]
[ ( 27 5 ) ( 27 9 ) ]
[ ( 27 11 ) ( 27 15 ) ] ;

45
atc/games/box Normal file
View File

@@ -0,0 +1,45 @@
update = 5;
newplane = 6;
width = 29;
height = 21;
exit: ( 0 0 c ) ( 14 0 x ) ( 28 0 z )
( 28 10 a )
( 28 20 q ) ( 14 20 w ) ( 0 20 e )
( 0 10 d ) ;
beacon: ( 4 4 ) ( 14 4 ) ( 24 4 )
( 24 10 )
( 24 16 ) ( 14 16 ) ( 4 16 )
( 4 10 )
( 14 13 ) ( 14 7 ) ;
airport: ( 9 7 a ) ( 19 7 d )
( 19 13 d ) ( 9 13 a ) ;
line: [ ( 1 1 ) ( 3 3 ) ]
[ ( 14 1 ) ( 14 3 ) ]
[ ( 27 1 ) ( 25 3 ) ]
[ ( 5 4 ) ( 13 4 ) ]
[ ( 15 4 ) ( 23 4 ) ]
[ ( 4 5 ) ( 4 9 ) ]
[ ( 14 5 ) ( 14 6 ) ]
[ ( 24 5 ) ( 24 9 ) ]
[ ( 10 7 ) ( 13 7 ) ]
[ ( 15 7 ) ( 18 7 ) ]
[ ( 14 8 ) ( 14 9 ) ]
[ ( 1 10 ) ( 3 10 ) ]
[ ( 5 10 ) ( 23 10 ) ]
[ ( 25 10 ) ( 27 10 ) ]
[ ( 4 11 ) ( 4 15 ) ]
[ ( 14 11 ) ( 14 12 ) ]
[ ( 24 11 ) ( 24 15 ) ]
[ ( 10 13 ) ( 13 13 ) ]
[ ( 15 13 ) ( 18 13 ) ]
[ ( 14 14 ) ( 14 15 ) ]
[ ( 5 16 ) ( 13 16 ) ]
[ ( 15 16 ) ( 23 16 ) ]
[ ( 3 17 ) ( 1 19 ) ]
[ ( 14 17 ) ( 14 19 ) ]
[ ( 25 17 ) ( 27 19 ) ] ;

39
atc/games/crosshatch Normal file
View File

@@ -0,0 +1,39 @@
update = 5;
newplane = 5;
width = 30;
height = 21;
exit: ( 0 10 d ) ( 6 0 x )
( 12 0 x ) ( 18 0 x )
( 24 0 x ) ( 29 10 a )
( 24 20 w ) ( 18 20 w )
( 12 20 w ) ( 6 20 w ) ;
beacon: ( 6 10 ) ( 12 10 ) ( 18 10 ) ( 24 10 )
( 6 5 ) ( 12 5 ) ( 18 5 ) ( 24 5 )
( 12 15 ) ( 18 15 ) ;
airport: ( 9 15 a ) ( 21 15 d ) ( 15 5 d ) ;
line: [ ( 6 1 ) ( 6 4 ) ]
[ ( 12 1 ) ( 12 4 ) ]
[ ( 18 1 ) ( 18 4 ) ]
[ ( 24 1 ) ( 24 4 ) ]
[ ( 6 6 ) ( 6 9 ) ]
[ ( 12 6 ) ( 12 9 ) ]
[ ( 18 6 ) ( 18 9 ) ]
[ ( 24 6 ) ( 24 9 ) ]
[ ( 12 11 ) ( 12 14 ) ]
[ ( 18 11 ) ( 18 14 ) ]
[ ( 6 11 ) ( 6 19 ) ]
[ ( 24 11 ) ( 24 19 ) ]
[ ( 12 16 ) ( 12 19 ) ]
[ ( 18 16 ) ( 18 19 ) ]
[ ( 7 5 ) ( 11 5 ) ]
[ ( 19 5 ) ( 23 5 ) ]
[ ( 13 15 ) ( 17 15 ) ]
[ ( 1 10 ) ( 5 10 ) ]
[ ( 7 10 ) ( 11 10 ) ]
[ ( 13 10 ) ( 17 10 ) ]
[ ( 19 10 ) ( 23 10 ) ]
[ ( 25 10 ) ( 29 10 ) ] ;

14
atc/games/crossover Normal file
View File

@@ -0,0 +1,14 @@
update = 5;
newplane = 5;
width = 29;
height = 21;
exit: ( 0 0 c ) ( 8 0 c ) ( 20 0 z ) ( 28 0 z )
( 28 20 q ) ( 20 20 q ) ( 8 20 e ) ( 0 20 e );
beacon: ( 14 6 ) ( 18 10 ) ( 14 14 ) ( 10 10 );
line: [ ( 0 0 ) ( 20 20 ) ]
[ ( 8 0 ) ( 28 20 ) ]
[ ( 20 0 ) ( 0 20 ) ]
[ ( 28 0 ) ( 8 20 ) ];

21
atc/games/default Normal file
View File

@@ -0,0 +1,21 @@
update = 5;
newplane = 10;
width = 30;
height = 21;
exit: ( 12 0 x ) ( 29 0 z ) ( 29 7 a ) ( 29 17 a )
( 9 20 e ) ( 0 13 d ) ( 0 7 d ) ( 0 0 c ) ;
beacon: ( 12 7 ) ( 12 17 ) ;
airport: ( 20 15 w ) ( 20 18 d ) ;
line: [ ( 1 1 ) ( 6 6 ) ]
[ ( 12 1 ) ( 12 6 ) ]
[ ( 13 7 ) ( 28 7 ) ]
[ ( 28 1 ) ( 13 16 ) ]
[ ( 1 13 ) ( 11 13 ) ]
[ ( 12 8 ) ( 12 16 ) ]
[ ( 11 18 ) ( 10 19 ) ]
[ ( 13 17 ) ( 28 17 ) ]
[ ( 1 7 ) ( 11 7 ) ] ;

15
atc/games/easy Normal file
View File

@@ -0,0 +1,15 @@
update = 7;
newplane = 12;
width = 15;
height = 15;
exit: ( 7 0 x ) ( 14 0 z ) ( 12 14 q ) ( 0 14 e ) ;
beacon: ( 12 7 ) ;
airport: ( 7 8 w ) ;
line: [ ( 1 1 ) ( 6 6 ) ]
[ ( 7 9 ) ( 12 14 ) ]
[ ( 7 0 ) ( 7 14 ) ]
[ ( 1 7 ) ( 11 7 ) ] ;

22
atc/games/game_2 Normal file
View File

@@ -0,0 +1,22 @@
update = 5;
newplane = 8;
width = 30;
height = 21;
exit: ( 12 0 x ) ( 29 0 z ) ( 29 6 a ) ( 29 13 a )
( 9 20 e ) ( 0 13 d ) ( 0 6 d ) ( 0 0 c ) ;
beacon: ( 12 17 ) ( 23 6 ) ( 23 13 ) ( 25 17 )
( 12 6 ) ( 12 13 ) ( 6 6 ) ;
airport: ( 18 17 d ) ;
line: [ ( 1 1 ) ( 16 16 ) ]
[ ( 1 6 ) ( 28 6 ) ]
[ ( 12 1 ) ( 12 17 ) ]
[ ( 10 19 ) ( 28 1 ) ]
[ ( 13 17 ) ( 17 17 ) ]
[ ( 1 13 ) ( 28 13 ) ]
[ ( 19 17 ) ( 24 17 ) ]
[ ( 19 17 ) ( 22 14 ) ]
[ ( 26 16 ) ( 28 14 ) ] ;

17
atc/games/game_3 Normal file
View File

@@ -0,0 +1,17 @@
update = 5;
newplane = 5;
width = 30;
height = 21;
exit: ( 12 0 x ) ( 0 6 d ) ( 29 12 a ) ( 26 20 q ) ;
beacon: ( 12 6 ) ;
airport: ( 8 11 x ) ;
line: [ ( 12 1 ) ( 12 5 ) ]
[ ( 1 6 ) ( 11 6 ) ]
[ ( 8 7 ) ( 8 10 ) ]
[ ( 28 12 ) ( 19 12 ) ]
[ ( 13 7 ) ( 25 19 ) ] ;

37
atc/games/game_4 Normal file
View File

@@ -0,0 +1,37 @@
update = 5;
newplane = 5;
width = 30;
height = 21;
exit: ( 9 0 c ) ( 29 0 z ) ( 29 20 q ) ( 9 20 e )
( 0 20 e ) ( 0 10 d ) ( 0 0 c ) ;
beacon: ( 5 5 ) ( 14 5 ) ( 24 5 ) ( 24 9 ) ( 24 11 )
( 24 15 ) ( 14 15 ) ( 5 15 ) ( 5 10 ) ( 14 10 ) ;
airport: ( 19 9 a ) ( 19 11 a ) ;
line: [ ( 1 1 ) ( 4 4 ) ]
[ ( 10 1 ) ( 13 4 ) ]
[ ( 28 1 ) ( 25 4 ) ]
[ ( 6 5 ) ( 13 5 ) ]
[ ( 15 5 ) ( 23 5 ) ]
[ ( 1 10 ) ( 13 10 ) ]
[ ( 15 10 ) ( 17 10 ) ]
[ ( 18 9 ) ( 18 9 ) ]
[ ( 18 11 ) ( 18 11 ) ]
[ ( 20 9 ) ( 23 9 ) ]
[ ( 20 11 ) ( 23 11 ) ]
[ ( 6 15 ) ( 13 15 ) ]
[ ( 15 15 ) ( 24 15 ) ]
[ ( 1 19 ) ( 4 16 ) ]
[ ( 10 19 ) ( 13 16 ) ]
[ ( 28 19 ) ( 25 16 ) ]
[ ( 5 6 ) ( 5 9 ) ]
[ ( 5 11 ) ( 5 14 ) ]
[ ( 14 6 ) ( 14 9 ) ]
[ ( 14 11 ) ( 14 14 ) ]
[ ( 24 6 ) ( 24 8 ) ]
[ ( 24 10 ) ( 24 10 ) ]
[ ( 24 12 ) ( 24 14 ) ] ;

15
atc/games/novice Normal file
View File

@@ -0,0 +1,15 @@
update = 6;
newplane = 6;
width = 30;
height = 21;
exit: ( 0 2 c ) ( 29 2 z )
( 29 18 q ) ( 0 18 e ) ;
beacon: ( 8 10 ) ( 21 10 ) ;
line: [ ( 1 3 ) ( 7 9 ) ]
[ ( 7 11 ) ( 1 17 ) ]
[ ( 28 3 ) ( 22 9 ) ]
[ ( 22 11 ) ( 28 17 ) ]
[ ( 9 10 ) ( 20 10 ) ] ;

21
atc/games/two-corners Normal file
View File

@@ -0,0 +1,21 @@
update = 5;
newplane = 5;
width = 30;
height = 21;
exit: ( 0 0 c ) ( 10 0 x ) ( 29 10 a )
( 29 20 q )
( 19 20 w ) ( 0 10 d ) ;
beacon: ( 10 10 ) ( 19 10 ) ;
airport: ( 15 15 x ) ;
line: [ ( 1 1 ) ( 9 9 ) ]
[ ( 10 1 ) ( 10 9 ) ]
[ ( 1 10 ) ( 9 10 ) ]
[ ( 11 10 ) ( 18 10 ) ]
[ ( 15 11 ) ( 15 14 ) ]
[ ( 20 10 ) ( 28 10 ) ]
[ ( 19 11 ) ( 19 19 ) ]
[ ( 20 11 ) ( 28 19 ) ] ;

411
atc/grammar.y Normal file
View File

@@ -0,0 +1,411 @@
/* $NetBSD: grammar.y,v 1.4 1997/10/10 02:07:08 lukem Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
%token <ival> HeightOp
%token <ival> WidthOp
%token <ival> UpdateOp
%token <ival> NewplaneOp
%token <cval> DirOp
%token <ival> ConstOp
%token <ival> LineOp
%token <ival> AirportOp
%token <ival> BeaconOp
%token <ival> ExitOp
%union {
int ival;
char cval;
}
%{
#include "include.h"
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)grammar.y 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: grammar.y,v 1.4 1997/10/10 02:07:08 lukem Exp $");
#endif
#endif /* not lint */
int errors = 0;
int line = 1;
%}
%%
file:
bunch_of_defs { if (checkdefs() < 0) return (errors); } bunch_of_lines
{
if (sp->num_exits + sp->num_airports < 2)
yyerror("Need at least 2 airports and/or exits.");
return (errors);
}
;
bunch_of_defs:
def bunch_of_defs
| def
;
def:
udef
| ndef
| wdef
| hdef
;
udef:
UpdateOp '=' ConstOp ';'
{
if (sp->update_secs != 0)
return (yyerror("Redefinition of 'update'."));
else if ($3 < 1)
return (yyerror("'update' is too small."));
else
sp->update_secs = $3;
}
;
ndef:
NewplaneOp '=' ConstOp ';'
{
if (sp->newplane_time != 0)
return (yyerror("Redefinition of 'newplane'."));
else if ($3 < 1)
return (yyerror("'newplane' is too small."));
else
sp->newplane_time = $3;
}
;
hdef:
HeightOp '=' ConstOp ';'
{
if (sp->height != 0)
return (yyerror("Redefinition of 'height'."));
else if ($3 < 3)
return (yyerror("'height' is too small."));
else
sp->height = $3;
}
;
wdef:
WidthOp '=' ConstOp ';'
{
if (sp->height != 0)
return (yyerror("Redefinition of 'width'."));
else if ($3 < 3)
return (yyerror("'width' is too small."));
else
sp->width = $3;
}
;
bunch_of_lines:
line bunch_of_lines
{}
| line
{}
;
line:
BeaconOp ':' Bpoint_list ';'
{}
| ExitOp ':' Epoint_list ';'
{}
| LineOp ':' Lline_list ';'
{}
| AirportOp ':' Apoint_list ';'
{}
;
Bpoint_list:
Bpoint Bpoint_list
{}
| Bpoint
{}
;
Bpoint:
'(' ConstOp ConstOp ')'
{
if (sp->num_beacons % REALLOC == 0) {
if (sp->beacon == NULL)
sp->beacon = (BEACON *) malloc((sp->num_beacons
+ REALLOC) * sizeof (BEACON));
else
sp->beacon = (BEACON *) realloc(sp->beacon,
(sp->num_beacons + REALLOC) *
sizeof (BEACON));
if (sp->beacon == NULL)
return (yyerror("No memory available."));
}
sp->beacon[sp->num_beacons].x = $2;
sp->beacon[sp->num_beacons].y = $3;
check_point($2, $3);
sp->num_beacons++;
}
;
Epoint_list:
Epoint Epoint_list
{}
| Epoint
{}
;
Epoint:
'(' ConstOp ConstOp DirOp ')'
{
int dir;
if (sp->num_exits % REALLOC == 0) {
if (sp->exit == NULL)
sp->exit = (EXIT *) malloc((sp->num_exits +
REALLOC) * sizeof (EXIT));
else
sp->exit = (EXIT *) realloc(sp->exit,
(sp->num_exits + REALLOC) *
sizeof (EXIT));
if (sp->exit == NULL)
return (yyerror("No memory available."));
}
dir = dir_no($4);
sp->exit[sp->num_exits].x = $2;
sp->exit[sp->num_exits].y = $3;
sp->exit[sp->num_exits].dir = dir;
check_edge($2, $3);
check_edir($2, $3, dir);
sp->num_exits++;
}
;
Apoint_list:
Apoint Apoint_list
{}
| Apoint
{}
;
Apoint:
'(' ConstOp ConstOp DirOp ')'
{
int dir;
if (sp->num_airports % REALLOC == 0) {
if (sp->airport == NULL)
sp->airport=(AIRPORT *)malloc((sp->num_airports
+ REALLOC) * sizeof(AIRPORT));
else
sp->airport = (AIRPORT *) realloc(sp->airport,
(sp->num_airports + REALLOC) *
sizeof(AIRPORT));
if (sp->airport == NULL)
return (yyerror("No memory available."));
}
dir = dir_no($4);
sp->airport[sp->num_airports].x = $2;
sp->airport[sp->num_airports].y = $3;
sp->airport[sp->num_airports].dir = dir;
check_point($2, $3);
check_adir($2, $3, dir);
sp->num_airports++;
}
;
Lline_list:
Lline Lline_list
{}
| Lline
{}
;
Lline:
'[' '(' ConstOp ConstOp ')' '(' ConstOp ConstOp ')' ']'
{
if (sp->num_lines % REALLOC == 0) {
if (sp->line == NULL)
sp->line = (LINE *) malloc((sp->num_lines +
REALLOC) * sizeof (LINE));
else
sp->line = (LINE *) realloc(sp->line,
(sp->num_lines + REALLOC) *
sizeof (LINE));
if (sp->line == NULL)
return (yyerror("No memory available."));
}
sp->line[sp->num_lines].p1.x = $3;
sp->line[sp->num_lines].p1.y = $4;
sp->line[sp->num_lines].p2.x = $7;
sp->line[sp->num_lines].p2.y = $8;
check_line($3, $4, $7, $8);
sp->num_lines++;
}
;
%%
void
check_edge(x, y)
int x, y;
{
if (!(x == 0) && !(x == sp->width - 1) &&
!(y == 0) && !(y == sp->height - 1))
yyerror("edge value not on edge.");
}
void
check_point(x, y)
int x, y;
{
if (x < 1 || x >= sp->width - 1)
yyerror("X value out of range.");
if (y < 1 || y >= sp->height - 1)
yyerror("Y value out of range.");
}
void
check_linepoint(x, y)
int x, y;
{
if (x < 0 || x >= sp->width)
yyerror("X value out of range.");
if (y < 0 || y >= sp->height)
yyerror("Y value out of range.");
}
void
check_line(x1, y1, x2, y2)
int x1, y1, x2, y2;
{
int d1, d2;
check_linepoint(x1, y1);
check_linepoint(x2, y2);
d1 = ABS(x2 - x1);
d2 = ABS(y2 - y1);
if (!(d1 == d2) && !(d1 == 0) && !(d2 == 0))
yyerror("Bad line endpoints.");
}
int
yyerror(s)
const char *s;
{
fprintf(stderr, "\"%s\": line %d: %s\n", file, line, s);
errors++;
return (errors);
}
void
check_edir(x, y, dir)
int x, y, dir;
{
int bad = 0;
if (x == sp->width - 1)
x = 2;
else if (x != 0)
x = 1;
if (y == sp->height - 1)
y = 2;
else if (y != 0)
y = 1;
switch (x * 10 + y) {
case 00: if (dir != 3) bad++; break;
case 01: if (dir < 1 || dir > 3) bad++; break;
case 02: if (dir != 1) bad++; break;
case 10: if (dir < 3 || dir > 5) bad++; break;
case 11: break;
case 12: if (dir > 1 && dir < 7) bad++; break;
case 20: if (dir != 5) bad++; break;
case 21: if (dir < 5) bad++; break;
case 22: if (dir != 7) bad++; break;
default:
yyerror("Unknown value in checkdir! Get help!");
break;
}
if (bad)
yyerror("Bad direction for entrance at exit.");
}
void
check_adir(x, y, dir)
int x __attribute__((unused)), y __attribute__((unused)), dir __attribute__((unused));
{
}
int
checkdefs()
{
int err = 0;
if (sp->width == 0) {
yyerror("'width' undefined.");
err++;
}
if (sp->height == 0) {
yyerror("'height' undefined.");
err++;
}
if (sp->update_secs == 0) {
yyerror("'update' undefined.");
err++;
}
if (sp->newplane_time == 0) {
yyerror("'newplane' undefined.");
err++;
}
if (err)
return (-1);
else
return (0);
}

443
atc/graphics.c Normal file
View File

@@ -0,0 +1,443 @@
/* $NetBSD: graphics.c,v 1.4 1997/10/10 02:07:11 lukem Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)graphics.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: graphics.c,v 1.4 1997/10/10 02:07:11 lukem Exp $");
#endif
#endif /* not lint */
#include "include.h"
#define C_TOPBOTTOM '-'
#define C_LEFTRIGHT '|'
#define C_AIRPORT '='
#define C_LINE '+'
#define C_BACKROUND '.'
#define C_BEACON '*'
#define C_CREDIT '*'
WINDOW *radar, *cleanradar, *credit, *input, *planes;
int
getAChar()
{
int c;
errno = 0;
while ((c = getchar()) == EOF && errno == EINTR)
clearerr(stdin);
return(c);
}
void
erase_all()
{
PLANE *pp;
for (pp = air.head; pp != NULL; pp = pp->next) {
wmove(cleanradar, pp->ypos, pp->xpos * 2);
wmove(radar, pp->ypos, pp->xpos * 2);
waddch(radar, winch(cleanradar));
wmove(cleanradar, pp->ypos, pp->xpos * 2 + 1);
wmove(radar, pp->ypos, pp->xpos * 2 + 1);
waddch(radar, winch(cleanradar));
}
}
void
draw_all()
{
PLANE *pp;
for (pp = air.head; pp != NULL; pp = pp->next) {
if (pp->status == S_MARKED)
wstandout(radar);
wmove(radar, pp->ypos, pp->xpos * 2);
waddch(radar, name(pp));
waddch(radar, '0' + pp->altitude);
if (pp->status == S_MARKED)
wstandend(radar);
}
wrefresh(radar);
planewin();
wrefresh(input); /* return cursor */
fflush(stdout);
}
void
init_gr()
{
static char buffer[BUFSIZ];
initscr();
setbuf(stdout, buffer);
input = newwin(INPUT_LINES, COLS - PLANE_COLS, LINES - INPUT_LINES, 0);
credit = newwin(INPUT_LINES, PLANE_COLS, LINES - INPUT_LINES,
COLS - PLANE_COLS);
planes = newwin(LINES - INPUT_LINES, PLANE_COLS, 0, COLS - PLANE_COLS);
}
void
setup_screen(scp)
const C_SCREEN *scp;
{
int i, j;
char str[3];
const char *airstr;
str[2] = '\0';
if (radar != NULL)
delwin(radar);
radar = newwin(scp->height, scp->width * 2, 0, 0);
if (cleanradar != NULL)
delwin(cleanradar);
cleanradar = newwin(scp->height, scp->width * 2, 0, 0);
/* minus one here to prevent a scroll */
for (i = 0; i < PLANE_COLS - 1; i++) {
wmove(credit, 0, i);
waddch(credit, C_CREDIT);
wmove(credit, INPUT_LINES - 1, i);
waddch(credit, C_CREDIT);
}
wmove(credit, INPUT_LINES / 2, 1);
waddstr(credit, AUTHOR_STR);
for (i = 1; i < scp->height - 1; i++) {
for (j = 1; j < scp->width - 1; j++) {
wmove(radar, i, j * 2);
waddch(radar, C_BACKROUND);
}
}
/*
* Draw the lines first, since people like to draw lines
* through beacons and exit points.
*/
str[0] = C_LINE;
for (i = 0; i < scp->num_lines; i++) {
str[1] = ' ';
draw_line(radar, scp->line[i].p1.x, scp->line[i].p1.y,
scp->line[i].p2.x, scp->line[i].p2.y, str);
}
str[0] = C_TOPBOTTOM;
str[1] = C_TOPBOTTOM;
wmove(radar, 0, 0);
for (i = 0; i < scp->width - 1; i++)
waddstr(radar, str);
waddch(radar, C_TOPBOTTOM);
str[0] = C_TOPBOTTOM;
str[1] = C_TOPBOTTOM;
wmove(radar, scp->height - 1, 0);
for (i = 0; i < scp->width - 1; i++)
waddstr(radar, str);
waddch(radar, C_TOPBOTTOM);
for (i = 1; i < scp->height - 1; i++) {
wmove(radar, i, 0);
waddch(radar, C_LEFTRIGHT);
wmove(radar, i, (scp->width - 1) * 2);
waddch(radar, C_LEFTRIGHT);
}
str[0] = C_BEACON;
for (i = 0; i < scp->num_beacons; i++) {
str[1] = '0' + i;
wmove(radar, scp->beacon[i].y, scp->beacon[i].x * 2);
waddstr(radar, str);
}
for (i = 0; i < scp->num_exits; i++) {
wmove(radar, scp->exit[i].y, scp->exit[i].x * 2);
waddch(radar, '0' + i);
}
airstr = "^?>?v?<?";
for (i = 0; i < scp->num_airports; i++) {
str[0] = airstr[scp->airport[i].dir];
str[1] = '0' + i;
wmove(radar, scp->airport[i].y, scp->airport[i].x * 2);
waddstr(radar, str);
}
overwrite(radar, cleanradar);
wrefresh(radar);
wrefresh(credit);
fflush(stdout);
}
void
draw_line(w, x, y, lx, ly, s)
WINDOW *w;
int x, y, lx, ly;
const char *s;
{
int dx, dy;
dx = SGN(lx - x);
dy = SGN(ly - y);
for (;;) {
wmove(w, y, x * 2);
waddstr(w, s);
if (x == lx && y == ly)
break;
x += dx;
y += dy;
}
}
void
ioclrtoeol(pos)
int pos;
{
wmove(input, 0, pos);
wclrtoeol(input);
wrefresh(input);
fflush(stdout);
}
void
iomove(pos)
int pos;
{
wmove(input, 0, pos);
wrefresh(input);
fflush(stdout);
}
void
ioaddstr(pos, str)
int pos;
const char *str;
{
wmove(input, 0, pos);
waddstr(input, str);
wrefresh(input);
fflush(stdout);
}
void
ioclrtobot()
{
wclrtobot(input);
wrefresh(input);
fflush(stdout);
}
void
ioerror(pos, len, str)
int pos, len;
const char *str;
{
int i;
wmove(input, 1, pos);
for (i = 0; i < len; i++)
waddch(input, '^');
wmove(input, 2, 0);
waddstr(input, str);
wrefresh(input);
fflush(stdout);
}
void
quit(dummy)
int dummy __attribute__((unused));
{
int c, y, x;
#ifdef BSD
struct itimerval itv;
#endif
getyx(input, y, x);
wmove(input, 2, 0);
waddstr(input, "Really quit? (y/n) ");
wclrtobot(input);
wrefresh(input);
fflush(stdout);
c = getchar();
if (c == EOF || c == 'y') {
/* disable timer */
#ifdef BSD
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
#endif
#ifdef SYSV
alarm(0);
#endif
fflush(stdout);
clear();
refresh();
endwin();
log_score(0);
exit(0);
}
wmove(input, 2, 0);
wclrtobot(input);
wmove(input, y, x);
wrefresh(input);
fflush(stdout);
}
void
planewin()
{
PLANE *pp;
int warning = 0;
#ifdef BSD
werase(planes);
#endif
wmove(planes, 0,0);
#ifdef SYSV
wclrtobot(planes);
#endif
wprintw(planes, "Time: %-4d Safe: %d", clck, safe_planes);
wmove(planes, 2, 0);
waddstr(planes, "pl dt comm");
for (pp = air.head; pp != NULL; pp = pp->next) {
if (waddch(planes, '\n') == ERR) {
warning++;
break;
}
waddstr(planes, command(pp));
}
waddch(planes, '\n');
for (pp = ground.head; pp != NULL; pp = pp->next) {
if (waddch(planes, '\n') == ERR) {
warning++;
break;
}
waddstr(planes, command(pp));
}
if (warning) {
wmove(planes, LINES - INPUT_LINES - 1, 0);
waddstr(planes, "---- more ----");
wclrtoeol(planes);
}
wrefresh(planes);
fflush(stdout);
}
void
loser(p, s)
const PLANE *p;
const char *s;
{
int c;
#ifdef BSD
struct itimerval itv;
#endif
/* disable timer */
#ifdef BSD
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
#endif
#ifdef SYSV
alarm(0);
#endif
wmove(input, 0, 0);
wclrtobot(input);
/* p may be NULL if we ran out of memory */
if (p == NULL)
wprintw(input, "%s\n\nHit space for top players list...", s);
else
wprintw(input, "Plane '%c' %s\n\nHit space for top players list...",
name(p), s);
wrefresh(input);
fflush(stdout);
while ((c = getchar()) != EOF && c != ' ')
;
clear(); /* move to top of screen */
refresh();
endwin();
log_score(0);
exit(0);
}
void
redraw()
{
clear();
refresh();
touchwin(radar);
wrefresh(radar);
touchwin(planes);
wrefresh(planes);
touchwin(credit);
wrefresh(credit);
/* refresh input last to get cursor in right place */
touchwin(input);
wrefresh(input);
fflush(stdout);
}
void
done_screen()
{
clear();
refresh();
endwin(); /* clean up curses */
}

74
atc/include.h Normal file
View File

@@ -0,0 +1,74 @@
/* $NetBSD: include.h,v 1.6 1997/10/10 02:07:14 lukem Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)include.h 8.1 (Berkeley) 5/31/93
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <ctype.h>
#include <curses.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "def.h"
#include "struct.h"
#include "extern.h"
#include "tunable.h"

682
atc/input.c Normal file
View File

@@ -0,0 +1,682 @@
/* $NetBSD: input.c,v 1.10 1998/09/13 15:20:31 hubertf Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: input.c,v 1.10 1998/09/13 15:20:31 hubertf Exp $");
#endif
#endif not lint
#include "include.h"
#include "pathnames.h"
#define MAXRULES 6
#define MAXDEPTH 15
#define RETTOKEN '\n'
#define REDRAWTOKEN '\014' /* CTRL(L) */
#define SHELLTOKEN '!'
#define HELPTOKEN '?'
#define ALPHATOKEN 256
#define NUMTOKEN 257
typedef struct {
int token;
int to_state;
const char *str;
const char *(*func) __P((char));
} RULE;
typedef struct {
int num_rules;
RULE *rule;
} STATE;
typedef struct {
char str[20];
int state;
int rule;
int ch;
int pos;
} STACK;
#define T_RULE stack[level].rule
#define T_STATE stack[level].state
#define T_STR stack[level].str
#define T_POS stack[level].pos
#define T_CH stack[level].ch
#define NUMELS(a) (sizeof (a) / sizeof (*(a)))
#define NUMSTATES NUMELS(st)
RULE state0[] = { { ALPHATOKEN, 1, "%c:", setplane},
{ RETTOKEN, -1, "", NULL },
{ HELPTOKEN, 12, " [a-z]<ret>", NULL }},
state1[] = { { 't', 2, " turn", turn },
{ 'a', 3, " altitude:", NULL },
{ 'c', 4, " circle", circle },
{ 'm', 7, " mark", mark },
{ 'u', 7, " unmark", unmark },
{ 'i', 7, " ignore", ignore },
{ HELPTOKEN, 12, " tacmui", NULL }},
state2[] = { { 'l', 6, " left", left },
{ 'r', 6, " right", right },
{ 'L', 4, " left 90", Left },
{ 'R', 4, " right 90", Right },
{ 't', 11, " towards", NULL },
{ 'w', 4, " to 0", to_dir },
{ 'e', 4, " to 45", to_dir },
{ 'd', 4, " to 90", to_dir },
{ 'c', 4, " to 135", to_dir },
{ 'x', 4, " to 180", to_dir },
{ 'z', 4, " to 225", to_dir },
{ 'a', 4, " to 270", to_dir },
{ 'q', 4, " to 315", to_dir },
{ HELPTOKEN, 12, " lrLRt<dir>", NULL }},
state3[] = { { '+', 10, " climb", climb },
{ 'c', 10, " climb", climb },
{ '-', 10, " descend", descend },
{ 'd', 10, " descend", descend },
{ NUMTOKEN, 7, " %c000 feet", setalt },
{ HELPTOKEN, 12, " +-cd[0-9]", NULL }},
state4[] = { { '@', 9, " at", NULL },
{ 'a', 9, " at", NULL },
{ RETTOKEN, -1, "", NULL },
{ HELPTOKEN, 12, " @a<ret>", NULL }},
state5[] = { { NUMTOKEN, 7, "%c", delayb },
{ HELPTOKEN, 12, " [0-9]", NULL }},
state6[] = { { '@', 9, " at", NULL },
{ 'a', 9, " at", NULL },
{ 'w', 4, " 0", rel_dir },
{ 'e', 4, " 45", rel_dir },
{ 'd', 4, " 90", rel_dir },
{ 'c', 4, " 135", rel_dir },
{ 'x', 4, " 180", rel_dir },
{ 'z', 4, " 225", rel_dir },
{ 'a', 4, " 270", rel_dir },
{ 'q', 4, " 315", rel_dir },
{ RETTOKEN, -1, "", NULL },
{ HELPTOKEN, 12, " @a<dir><ret>",NULL }},
state7[] = { { RETTOKEN, -1, "", NULL },
{ HELPTOKEN, 12, " <ret>", NULL }},
state8[] = { { NUMTOKEN, 4, "%c", benum },
{ HELPTOKEN, 12, " [0-9]", NULL }},
state9[] = { { 'b', 5, " beacon #", NULL },
{ '*', 5, " beacon #", NULL },
{ HELPTOKEN, 12, " b*", NULL }},
state10[] = { { NUMTOKEN, 7, " %c000 ft", setrelalt},
{ HELPTOKEN, 12, " [0-9]", NULL }},
state11[] = { { 'b', 8, " beacon #", beacon },
{ '*', 8, " beacon #", beacon },
{ 'e', 8, " exit #", ex_it },
{ 'a', 8, " airport #", airport },
{ HELPTOKEN, 12, " b*ea", NULL }},
state12[] = { { -1, -1, "", NULL }};
#define DEF_STATE(s) { NUMELS(s), (s) }
STATE st[] = {
DEF_STATE(state0), DEF_STATE(state1), DEF_STATE(state2),
DEF_STATE(state3), DEF_STATE(state4), DEF_STATE(state5),
DEF_STATE(state6), DEF_STATE(state7), DEF_STATE(state8),
DEF_STATE(state9), DEF_STATE(state10), DEF_STATE(state11),
DEF_STATE(state12)
};
PLANE p;
STACK stack[MAXDEPTH];
int level;
int tval;
int dest_type, dest_no, dir;
int
pop()
{
if (level == 0)
return (-1);
level--;
ioclrtoeol(T_POS);
strcpy(T_STR, "");
T_RULE = -1;
T_CH = -1;
return (0);
}
void
rezero()
{
iomove(0);
level = 0;
T_STATE = 0;
T_RULE = -1;
T_CH = -1;
T_POS = 0;
strcpy(T_STR, "");
}
void
push(ruleno, ch)
int ruleno, ch;
{
int newstate, newpos;
(void)sprintf(T_STR, st[T_STATE].rule[ruleno].str, tval);
T_RULE = ruleno;
T_CH = ch;
newstate = st[T_STATE].rule[ruleno].to_state;
newpos = T_POS + strlen(T_STR);
ioaddstr(T_POS, T_STR);
if (level == 0)
ioclrtobot();
level++;
T_STATE = newstate;
T_POS = newpos;
T_RULE = -1;
strcpy(T_STR, "");
}
int
getcommand()
{
int c, i, done;
const char *s, *(*func) __P((char));
PLANE *pp;
rezero();
do {
c = gettoken();
if (c == tty_new.c_cc[VERASE]) {
if (pop() < 0)
noise();
} else if (c == tty_new.c_cc[VKILL]) {
while (pop() >= 0)
;
} else {
done = 0;
for (i = 0; i < st[T_STATE].num_rules; i++) {
if (st[T_STATE].rule[i].token == c ||
st[T_STATE].rule[i].token == tval) {
push(i, (c >= ALPHATOKEN) ? tval : c);
done = 1;
break;
}
}
if (!done)
noise();
}
} while (T_STATE != -1);
if (level == 1)
return (1); /* forced update */
dest_type = T_NODEST;
for (i = 0; i < level; i++) {
func = st[stack[i].state].rule[stack[i].rule].func;
if (func != NULL)
if ((s = (*func)(stack[i].ch)) != NULL) {
ioerror(stack[i].pos, strlen(stack[i].str), s);
return (-1);
}
}
pp = findplane(p.plane_no);
if (pp->new_altitude != p.new_altitude)
pp->new_altitude = p.new_altitude;
else if (pp->status != p.status)
pp->status = p.status;
else {
pp->new_dir = p.new_dir;
pp->delayd = p.delayd;
pp->delayd_no = p.delayd_no;
}
return (0);
}
void
noise()
{
putchar('\07');
fflush(stdout);
}
int
gettoken()
{
while ((tval = getAChar()) == REDRAWTOKEN || tval == SHELLTOKEN)
{
if (tval == SHELLTOKEN)
{
#ifdef BSD
struct itimerval itv;
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
#endif
#ifdef SYSV
int aval;
aval = alarm(0);
#endif
if (fork() == 0) /* child */
{
char *shell, *base;
done_screen();
/* run user's favorite shell */
if ((shell = getenv("SHELL")) != NULL)
{
base = strrchr(shell, '/');
if (base == NULL)
base = shell;
else
base++;
execl(shell, base, 0);
}
else
execl(_PATH_BSHELL, "sh", 0);
exit(0); /* oops */
}
wait(0);
tcsetattr(fileno(stdin), TCSADRAIN, &tty_new);
#ifdef BSD
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 1;
itv.it_interval.tv_sec = sp->update_secs;
itv.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
#endif
#ifdef SYSV
alarm(aval);
#endif
}
redraw();
}
if (isdigit(tval))
return (NUMTOKEN);
else if (isalpha(tval))
return (ALPHATOKEN);
else
return (tval);
}
const char *
setplane(c)
char c;
{
PLANE *pp;
pp = findplane(number(c));
if (pp == NULL)
return ("Unknown Plane");
memcpy(&p, pp, sizeof (p));
p.delayd = 0;
return (NULL);
}
const char *
turn(c)
char c;
{
if (p.altitude == 0)
return ("Planes at airports may not change direction");
return (NULL);
}
const char *
circle(c)
char c;
{
if (p.altitude == 0)
return ("Planes cannot circle on the ground");
p.new_dir = MAXDIR;
return (NULL);
}
const char *
left(c)
char c;
{
dir = D_LEFT;
p.new_dir = p.dir - 1;
if (p.new_dir < 0)
p.new_dir += MAXDIR;
return (NULL);
}
const char *
right(c)
char c;
{
dir = D_RIGHT;
p.new_dir = p.dir + 1;
if (p.new_dir >= MAXDIR)
p.new_dir -= MAXDIR;
return (NULL);
}
const char *
Left(c)
char c;
{
p.new_dir = p.dir - 2;
if (p.new_dir < 0)
p.new_dir += MAXDIR;
return (NULL);
}
const char *
Right(c)
char c;
{
p.new_dir = p.dir + 2;
if (p.new_dir >= MAXDIR)
p.new_dir -= MAXDIR;
return (NULL);
}
const char *
delayb(ch)
char ch;
{
int xdiff, ydiff;
unsigned char c;
c = ch - '0';
if (c >= sp->num_beacons)
return ("Unknown beacon");
xdiff = sp->beacon[(int)c].x - p.xpos;
xdiff = SGN(xdiff);
ydiff = sp->beacon[(int)c].y - p.ypos;
ydiff = SGN(ydiff);
if (xdiff != displacement[p.dir].dx || ydiff != displacement[p.dir].dy)
return ("Beacon is not in flight path");
p.delayd = 1;
p.delayd_no = c;
if (dest_type != T_NODEST) {
switch (dest_type) {
case T_BEACON:
xdiff = sp->beacon[dest_no].x - sp->beacon[(int)c].x;
ydiff = sp->beacon[dest_no].y - sp->beacon[(int)c].y;
break;
case T_EXIT:
xdiff = sp->exit[dest_no].x - sp->beacon[(int)c].x;
ydiff = sp->exit[dest_no].y - sp->beacon[(int)c].y;
break;
case T_AIRPORT:
xdiff = sp->airport[dest_no].x - sp->beacon[(int)c].x;
ydiff = sp->airport[dest_no].y - sp->beacon[(int)c].y;
break;
default:
return ("Bad case in delayb! Get help!");
break;
}
if (xdiff == 0 && ydiff == 0)
return ("Would already be there");
p.new_dir = DIR_FROM_DXDY(xdiff, ydiff);
if (p.new_dir == p.dir)
return ("Already going in that direction");
}
return (NULL);
}
const char *
beacon(c)
char c;
{
dest_type = T_BEACON;
return (NULL);
}
const char *
ex_it(c)
char c;
{
dest_type = T_EXIT;
return (NULL);
}
const char *
airport(c)
char c;
{
dest_type = T_AIRPORT;
return (NULL);
}
const char *
climb(c)
char c;
{
dir = D_UP;
return (NULL);
}
const char *
descend(c)
char c;
{
dir = D_DOWN;
return (NULL);
}
const char *
setalt(c)
char c;
{
if ((p.altitude == c - '0') && (p.new_altitude == p.altitude))
return ("Already at that altitude");
p.new_altitude = c - '0';
return (NULL);
}
const char *
setrelalt(c)
char c;
{
if (c == 0)
return ("altitude not changed");
switch (dir) {
case D_UP:
p.new_altitude = p.altitude + c - '0';
break;
case D_DOWN:
p.new_altitude = p.altitude - (c - '0');
break;
default:
return ("Unknown case in setrelalt! Get help!");
break;
}
if (p.new_altitude < 0)
return ("Altitude would be too low");
else if (p.new_altitude > 9)
return ("Altitude would be too high");
return (NULL);
}
const char *
benum(ch)
char ch;
{
unsigned char c;
dest_no = c = ch - '0';
switch (dest_type) {
case T_BEACON:
if (c >= sp->num_beacons)
return ("Unknown beacon");
p.new_dir = DIR_FROM_DXDY(sp->beacon[(int)c].x - p.xpos,
sp->beacon[(int)c].y - p.ypos);
break;
case T_EXIT:
if (c >= sp->num_exits)
return ("Unknown exit");
p.new_dir = DIR_FROM_DXDY(sp->exit[(int)c].x - p.xpos,
sp->exit[(int)c].y - p.ypos);
break;
case T_AIRPORT:
if (c >= sp->num_airports)
return ("Unknown airport");
p.new_dir = DIR_FROM_DXDY(sp->airport[(int)c].x - p.xpos,
sp->airport[(int)c].y - p.ypos);
break;
default:
return ("Unknown case in benum! Get help!");
break;
}
return (NULL);
}
const char *
to_dir(c)
char c;
{
p.new_dir = dir_no(c);
return (NULL);
}
const char *
rel_dir(c)
char c;
{
int angle;
angle = dir_no(c);
switch (dir) {
case D_LEFT:
p.new_dir = p.dir - angle;
if (p.new_dir < 0)
p.new_dir += MAXDIR;
break;
case D_RIGHT:
p.new_dir = p.dir + angle;
if (p.new_dir >= MAXDIR)
p.new_dir -= MAXDIR;
break;
default:
return ("Bizarre direction in rel_dir! Get help!");
break;
}
return (NULL);
}
const char *
mark(c)
char c;
{
if (p.altitude == 0)
return ("Cannot mark planes on the ground");
if (p.status == S_MARKED)
return ("Already marked");
p.status = S_MARKED;
return (NULL);
}
const char *
unmark(c)
char c;
{
if (p.altitude == 0)
return ("Cannot unmark planes on the ground");
if (p.status == S_UNMARKED)
return ("Already unmarked");
p.status = S_UNMARKED;
return (NULL);
}
const char *
ignore(c)
char c;
{
if (p.altitude == 0)
return ("Cannot ignore planes on the ground");
if (p.status == S_IGNORED)
return ("Already ignored");
p.status = S_IGNORED;
return (NULL);
}
int
dir_no(ch)
char ch;
{
int dir;
dir = -1;
switch (ch) {
case 'w': dir = 0; break;
case 'e': dir = 1; break;
case 'd': dir = 2; break;
case 'c': dir = 3; break;
case 'x': dir = 4; break;
case 'z': dir = 5; break;
case 'a': dir = 6; break;
case 'q': dir = 7; break;
default:
fprintf(stderr, "bad character in dir_no\n");
break;
}
return (dir);
}

79
atc/lex.l Normal file
View File

@@ -0,0 +1,79 @@
%{
/* $NetBSD: lex.l,v 1.6 1998/04/09 00:32:32 tv Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lex.l 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: lex.l,v 1.6 1998/04/09 00:32:32 tv Exp $");
#endif
#endif /* not lint */
#include "include.h"
#undef ECHO /* XXX: work around lex(1) vs termios lameness */
#include "grammar.h"
extern int line;
%}
%%
[0-9]+ { yylval.ival = atoi(yytext); return(ConstOp); }
height { return(HeightOp); }
width { return(WidthOp); }
newplane { return(NewplaneOp); }
update { return(UpdateOp); }
airport { return(AirportOp); }
line { return(LineOp); }
exit { return(ExitOp); }
beacon { return(BeaconOp); }
[wedcxzaq] { yylval.cval = *yytext; return (DirOp); }
[ \t]+ { }
#[^\n]*\n { line++; }
\n { line++; }
. { return *yytext; }

124
atc/list.c Normal file
View File

@@ -0,0 +1,124 @@
/* $NetBSD: list.c,v 1.4 1997/10/10 02:07:23 lukem Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)list.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: list.c,v 1.4 1997/10/10 02:07:23 lukem Exp $");
#endif
#endif /* not lint */
#include "include.h"
PLANE *
newplane()
{
return ((PLANE *) calloc(1, sizeof (PLANE)));
}
void
append(l, p)
LIST *l;
PLANE *p;
{
PLANE *q = NULL, *r = NULL;
if (l->head == NULL) {
p->next = p->prev = NULL;
l->head = l->tail = p;
} else {
q = l -> head;
while (q != NULL && q->plane_no < p->plane_no) {
r = q;
q = q -> next;
}
if (q) {
if (r) {
p->prev = r;
r->next = p;
p->next = q;
q->prev = p;
} else {
p->next = q;
p->prev = NULL;
q->prev = p;
l->head = p;
}
} else {
l->tail->next = p;
p->next = NULL;
p->prev = l->tail;
l->tail = p;
}
}
}
void
delete(l, p)
LIST *l;
PLANE *p;
{
if (l->head == NULL)
loser(p, "deleted a non-existant plane! Get help!");
if (l->head == p && l->tail == p)
l->head = l->tail = NULL;
else if (l->head == p) {
l->head = p->next;
l->head->prev = NULL;
} else if (l->tail == p) {
l->tail = p->prev;
l->tail->next = NULL;
} else {
p->prev->next = p->next;
p->next->prev = p->prev;
}
}

297
atc/log.c Normal file
View File

@@ -0,0 +1,297 @@
/* $NetBSD: log.c,v 1.7 1998/07/24 23:22:26 hubertf Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)log.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: log.c,v 1.7 1998/07/24 23:22:26 hubertf Exp $");
#endif
#endif not lint
#include "include.h"
#include "pathnames.h"
static FILE *score_fp;
int
compar(va, vb)
const void *va, *vb;
{
const SCORE *a, *b;
a = (const SCORE *)va;
b = (const SCORE *)vb;
if (b->planes == a->planes)
return (b->time - a->time);
else
return (b->planes - a->planes);
}
#define SECAMIN 60
#define MINAHOUR 60
#define HOURADAY 24
#define SECAHOUR (SECAMIN * MINAHOUR)
#define SECADAY (SECAHOUR * HOURADAY)
#define DAY(t) ((t) / SECADAY)
#define HOUR(t) (((t) % SECADAY) / SECAHOUR)
#define MIN(t) (((t) % SECAHOUR) / SECAMIN)
#define SEC(t) ((t) % SECAMIN)
const char *
timestr(t)
int t;
{
static char s[80];
if (DAY(t) > 0)
(void)sprintf(s, "%dd+%02dhrs", DAY(t), HOUR(t));
else if (HOUR(t) > 0)
(void)sprintf(s, "%d:%02d:%02d", HOUR(t), MIN(t), SEC(t));
else if (MIN(t) > 0)
(void)sprintf(s, "%d:%02d", MIN(t), SEC(t));
else if (SEC(t) > 0)
(void)sprintf(s, ":%02d", SEC(t));
else
*s = '\0';
return (s);
}
void
open_score_file()
{
mode_t old_mask;
int score_fd;
int flags;
old_mask = umask(0);
score_fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0664);
umask(old_mask);
if (score_fd < 0) {
warn("open %s", _PATH_SCORE);
return;
}
/* Set the close-on-exec flag. If this fails for any reason, quit
* rather than leave the score file open to tampering. */
flags = fcntl(score_fd, F_GETFD);
if (flags < 0)
err(1, "fcntl F_GETFD");
flags |= FD_CLOEXEC;
if (fcntl(score_fd, F_SETFD, flags) == -1)
err(1, "fcntl F_SETFD");
/*
* This is done to take advantage of stdio, while still
* allowing a O_CREAT during the open(2) of the log file.
*/
score_fp = fdopen(score_fd, "r+");
if (score_fp == NULL) {
warn("fdopen %s", _PATH_SCORE);
return;
}
}
int
log_score(list_em)
int list_em;
{
int i, num_scores = 0, good, changed = 0, found = 0;
struct passwd *pw;
char *cp;
SCORE score[100], thisscore;
struct utsname name;
long offset;
if (score_fp == NULL) {
warnx("no score file available");
return (-1);
}
#ifdef BSD
if (flock(fileno(score_fp), LOCK_EX) < 0)
#endif
#ifdef SYSV
while (lockf(fileno(score_fp), F_LOCK, 1) < 0)
#endif
{
warn("flock %s", _PATH_SCORE);
return (-1);
}
for (;;) {
good = fscanf(score_fp, SCORE_SCANF_FMT,
score[num_scores].name,
score[num_scores].host,
score[num_scores].game,
&score[num_scores].planes,
&score[num_scores].time,
&score[num_scores].real_time);
if (good != 6 || ++num_scores >= NUM_SCORES)
break;
}
if (!test_mode && !list_em) {
if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) {
fprintf(stderr,
"getpwuid failed for uid %d. Who are you?\n",
(int)getuid());
return (-1);
}
strcpy(thisscore.name, pw->pw_name);
uname(&name);
strncpy(thisscore.host, name.nodename, sizeof(thisscore.host)-1);
thisscore.host[sizeof(thisscore.host) - 1] = '\0';
cp = strrchr(file, '/');
if (cp == NULL) {
fprintf(stderr, "log: where's the '/' in %s?\n", file);
return (-1);
}
cp++;
strcpy(thisscore.game, cp);
thisscore.time = clck;
thisscore.planes = safe_planes;
thisscore.real_time = time(0) - start_time;
for (i = 0; i < num_scores; i++) {
if (strcmp(thisscore.name, score[i].name) == 0 &&
strcmp(thisscore.host, score[i].host) == 0 &&
strcmp(thisscore.game, score[i].game) == 0) {
if (thisscore.time > score[i].time) {
score[i].time = thisscore.time;
score[i].planes = thisscore.planes;
score[i].real_time =
thisscore.real_time;
changed++;
}
found++;
break;
}
}
if (!found) {
for (i = 0; i < num_scores; i++) {
if (thisscore.time > score[i].time) {
if (num_scores < NUM_SCORES)
num_scores++;
memcpy(&score[num_scores - 1],
&score[i],
sizeof (score[i]));
memcpy(&score[i], &thisscore,
sizeof (score[i]));
changed++;
break;
}
}
}
if (!found && !changed && num_scores < NUM_SCORES) {
memcpy(&score[num_scores], &thisscore,
sizeof (score[num_scores]));
num_scores++;
changed++;
}
if (changed) {
if (found)
puts("You beat your previous score!");
else
puts("You made the top players list!");
qsort(score, num_scores, sizeof (*score), compar);
rewind(score_fp);
for (i = 0; i < num_scores; i++)
fprintf(score_fp, "%s %s %s %d %d %d\n",
score[i].name, score[i].host,
score[i].game, score[i].planes,
score[i].time, score[i].real_time);
fflush(score_fp);
if (ferror(score_fp))
warn("error writing %s", _PATH_SCORE);
/* It is just possible that updating an entry could
* have reduced the length of the file, so we
* truncate it. The seeks are required for stream/fd
* synchronisation by POSIX.1. */
offset = ftell(score_fp);
lseek(fileno(score_fp), 0, SEEK_SET);
ftruncate(fileno(score_fp), offset);
rewind(score_fp);
} else {
if (found)
puts("You didn't beat your previous score.");
else
puts("You didn't make the top players list.");
}
putchar('\n');
}
#ifdef BSD
flock(fileno(score_fp), LOCK_UN);
#endif
#ifdef SYSV
/* lock will evaporate upon close */
#endif
fclose(score_fp);
printf("%2s: %-8s %-8s %-18s %4s %9s %4s\n", "#", "name", "host",
"game", "time", "real time", "planes safe");
puts("-------------------------------------------------------------------------------");
for (i = 0; i < num_scores; i++) {
cp = strchr(score[i].host, '.');
if (cp != NULL)
*cp = '\0';
printf("%2d: %-8s %-8s %-18s %4d %9s %4d\n", i + 1,
score[i].name, score[i].host, score[i].game,
score[i].time, timestr(score[i].real_time),
score[i].planes);
}
putchar('\n');
return (0);
}
void
log_score_quit(dummy)
int dummy __attribute__((unused));
{
(void)log_score(0);
exit(0);
}

335
atc/main.c Normal file
View File

@@ -0,0 +1,335 @@
/* $NetBSD: main.c,v 1.7 1998/09/13 15:20:31 hubertf Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1990, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: main.c,v 1.7 1998/09/13 15:20:31 hubertf Exp $");
#endif
#endif /* not lint */
#include "include.h"
#include "pathnames.h"
int
main(ac, av)
int ac __attribute__((unused));
char *av[];
{
int seed;
int f_usage = 0, f_list = 0, f_showscore = 0;
int f_printpath = 0;
const char *file = NULL;
char *name, *ptr;
struct sigaction sa;
#ifdef BSD
struct itimerval itv;
#endif
/* Open the score file then revoke setgid privileges */
open_score_file();
setregid(getgid(), getgid());
start_time = seed = time(0);
name = *av++;
while (*av) {
#ifndef SAVEDASH
if (**av == '-')
++*av;
else
break;
#endif
ptr = *av++;
while (*ptr) {
switch (*ptr) {
case '?':
case 'u':
f_usage++;
break;
case 'l':
f_list++;
break;
case 's':
case 't':
f_showscore++;
break;
case 'p':
f_printpath++;
break;
case 'r':
seed = atoi(*av);
av++;
break;
case 'f':
case 'g':
file = *av;
av++;
break;
default:
warnx("unknown option '%c'\n", *ptr);
f_usage++;
break;
}
ptr++;
}
}
srandom(seed);
if (f_usage)
fprintf(stderr,
"Usage: %s -[u?lstp] [-[gf] game_name] [-r random seed]\n",
name);
if (f_showscore)
log_score(1);
if (f_list)
list_games();
if (f_printpath) {
char buf[100];
strcpy(buf, _PATH_GAMES);
buf[strlen(buf) - 1] = '\0';
puts(buf);
}
if (f_usage || f_showscore || f_list || f_printpath)
exit(0);
if (file == NULL)
file = default_game();
else
file = okay_game(file);
if (file == NULL || read_file(file) < 0)
exit(1);
init_gr();
setup_screen(sp);
addplane();
signal(SIGINT, quit);
signal(SIGQUIT, quit);
#ifdef BSD
signal(SIGTSTP, SIG_IGN);
signal(SIGSTOP, SIG_IGN);
#endif
signal(SIGHUP, log_score_quit);
signal(SIGTERM, log_score_quit);
tcgetattr(fileno(stdin), &tty_start);
tty_new = tty_start;
tty_new.c_lflag &= ~(ICANON|ECHO);
tty_new.c_iflag |= ICRNL;
tty_new.c_cc[VMIN] = 1;
tty_new.c_cc[VTIME] = 0;
tcsetattr(fileno(stdin), TCSADRAIN, &tty_new);
sa.sa_handler = update;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGALRM);
sigaddset(&sa.sa_mask, SIGINT);
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, (struct sigaction *)0);
#ifdef BSD
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 1;
itv.it_interval.tv_sec = sp->update_secs;
itv.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
#endif
#ifdef SYSV
alarm(sp->update_secs);
#endif
for (;;) {
if (getcommand() != 1)
planewin();
else {
#ifdef BSD
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
#endif
#ifdef SYSV
alarm(0);
#endif
update(0);
#ifdef BSD
itv.it_value.tv_sec = sp->update_secs;
itv.it_value.tv_usec = 0;
itv.it_interval.tv_sec = sp->update_secs;
itv.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
#endif
#ifdef SYSV
alarm(sp->update_secs);
#endif
}
}
}
int
read_file(s)
const char *s;
{
extern FILE *yyin;
int retval;
file = s;
yyin = fopen(s, "r");
if (yyin == NULL) {
warn("fopen %s", s);
return (-1);
}
retval = yyparse();
fclose(yyin);
if (retval != 0)
return (-1);
else
return (0);
}
const char *
default_game()
{
FILE *fp;
static char file[256];
char line[256], games[256];
strcpy(games, _PATH_GAMES);
strcat(games, GAMES);
if ((fp = fopen(games, "r")) == NULL) {
warn("fopen %s", games);
return (NULL);
}
if (fgets(line, sizeof(line), fp) == NULL) {
fprintf(stderr, "%s: no default game available\n", games);
return (NULL);
}
fclose(fp);
line[strlen(line) - 1] = '\0';
strcpy(file, _PATH_GAMES);
strcat(file, line);
return (file);
}
const char *
okay_game(s)
const char *s;
{
FILE *fp;
static char file[256];
const char *ret = NULL;
char line[256], games[256];
strcpy(games, _PATH_GAMES);
strcat(games, GAMES);
if ((fp = fopen(games, "r")) == NULL) {
warn("fopen %s", games);
return (NULL);
}
while (fgets(line, sizeof(line), fp) != NULL) {
line[strlen(line) - 1] = '\0';
if (strcmp(s, line) == 0) {
strcpy(file, _PATH_GAMES);
strcat(file, line);
ret = file;
break;
}
}
fclose(fp);
if (ret == NULL) {
test_mode = 1;
ret = s;
fprintf(stderr, "%s: %s: game not found\n", games, s);
fprintf(stderr, "Your score will not be logged.\n");
sleep(2); /* give the guy time to read it */
}
return (ret);
}
int
list_games()
{
FILE *fp;
char line[256], games[256];
int num_games = 0;
strcpy(games, _PATH_GAMES);
strcat(games, GAMES);
if ((fp = fopen(games, "r")) == NULL) {
warn("fopen %s", games);
return (-1);
}
puts("available games:");
while (fgets(line, sizeof(line), fp) != NULL) {
printf(" %s", line);
num_games++;
}
fclose(fp);
if (num_games == 0) {
fprintf(stderr, "%s: no games available\n", games);
return (-1);
}
return (0);
}

41
atc/pathnames.h.in Normal file
View File

@@ -0,0 +1,41 @@
/* $NetBSD: pathnames.h,v 1.3 1995/03/21 15:04:28 cgd 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pathnames.h 8.1 (Berkeley) 5/31/93
*/
#include <paths.h>
#define _PATH_GAMES "@atc_dir@/"
#define _PATH_SCORE "@atc_scorefile@"

115
atc/struct.h Normal file
View File

@@ -0,0 +1,115 @@
/* $NetBSD: struct.h,v 1.3 1995/03/21 15:04:31 cgd Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)struct.h 8.1 (Berkeley) 5/31/93
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
typedef struct {
int x, y;
int dir; /* used only sometimes */
} SCREEN_POS;
typedef struct {
SCREEN_POS p1, p2;
} LINE;
typedef SCREEN_POS EXIT;
typedef SCREEN_POS BEACON;
typedef SCREEN_POS AIRPORT;
typedef struct {
int width, height;
int update_secs;
int newplane_time;
int num_exits;
int num_lines;
int num_beacons;
int num_airports;
EXIT *exit;
LINE *line;
BEACON *beacon;
AIRPORT *airport;
} C_SCREEN;
typedef struct plane {
struct plane *next, *prev;
int status;
int plane_no;
int plane_type;
int orig_no;
int orig_type;
int dest_no;
int dest_type;
int altitude;
int new_altitude;
int dir;
int new_dir;
int fuel;
int xpos;
int ypos;
int delayd;
int delayd_no;
} PLANE;
typedef struct {
PLANE *head, *tail;
} LIST;
typedef struct {
char name[10];
char host[256];
char game[256];
int planes;
int time;
int real_time;
} SCORE;
#define SCORE_SCANF_FMT "%9s %255s %255s %d %d %d"
typedef struct displacement {
int dx;
int dy;
} DISPLACEMENT;

63
atc/tunable.c Normal file
View File

@@ -0,0 +1,63 @@
/* $NetBSD: tunable.c,v 1.4 1997/10/10 02:07:32 lukem Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)tunable.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: tunable.c,v 1.4 1997/10/10 02:07:32 lukem Exp $");
#endif
#endif /* not lint */
/*
* NUM_SCORES - Number of scores that are kept track of.
* Keep this greater than 0, but less than 100.
* 4 lines are printed above the score, one below + your prompt, so
* to prevent scrolling: 6 + NUM_SCORES <= 24 (lines on an average terminal).
*/
int NUM_SCORES = 18;

50
atc/tunable.h Normal file
View File

@@ -0,0 +1,50 @@
/* $NetBSD: tunable.h,v 1.3 1995/03/21 15:04:35 cgd Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)tunable.h 8.1 (Berkeley) 5/31/93
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
extern int NUM_SCORES;

423
atc/update.c Normal file
View File

@@ -0,0 +1,423 @@
/* $NetBSD: update.c,v 1.7 1998/09/11 12:53:29 hubertf Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Ed James.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
*
* Copy permission is hereby granted provided that this notice is
* retained on all partial or complete copies.
*
* For more info on this and all of my stuff, mail edjames@berkeley.edu.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)update.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: update.c,v 1.7 1998/09/11 12:53:29 hubertf Exp $");
#endif
#endif not lint
#include "include.h"
void
update(dummy)
int dummy __attribute__((unused));
{
int i, dir_diff, unclean;
PLANE *pp, *p1, *p2;
#ifdef SYSV
alarm(0);
signal(SIGALRM, update);
#endif
clck++;
erase_all();
/* put some planes in the air */
do {
unclean = 0;
for (pp = ground.head; pp != NULL; pp = pp->next) {
if (pp->new_altitude > 0) {
delete(&ground, pp);
append(&air, pp);
unclean = 1;
break;
}
}
} while (unclean);
/* do altitude change and basic movement */
for (pp = air.head; pp != NULL; pp = pp->next) {
/* type 0 only move every other turn */
if (pp->plane_type == 0 && clck & 1)
continue;
pp->fuel--;
if (pp->fuel < 0)
loser(pp, "ran out of fuel.");
pp->altitude += SGN(pp->new_altitude - pp->altitude);
if (!pp->delayd) {
dir_diff = pp->new_dir - pp->dir;
/*
* Allow for circle commands
*/
if (pp->new_dir >= 0 && pp->new_dir < MAXDIR) {
if (dir_diff > MAXDIR/2)
dir_diff -= MAXDIR;
else if (dir_diff < -(MAXDIR/2))
dir_diff += MAXDIR;
}
if (dir_diff > 2)
dir_diff = 2;
else if (dir_diff < -2)
dir_diff = -2;
pp->dir += dir_diff;
if (pp->dir >= MAXDIR)
pp->dir -= MAXDIR;
else if (pp->dir < 0)
pp->dir += MAXDIR;
}
pp->xpos += displacement[pp->dir].dx;
pp->ypos += displacement[pp->dir].dy;
if (pp->delayd && pp->xpos == sp->beacon[pp->delayd_no].x &&
pp->ypos == sp->beacon[pp->delayd_no].y) {
pp->delayd = 0;
if (pp->status == S_UNMARKED)
pp->status = S_MARKED;
}
switch (pp->dest_type) {
case T_AIRPORT:
if (pp->xpos == sp->airport[pp->dest_no].x &&
pp->ypos == sp->airport[pp->dest_no].y &&
pp->altitude == 0) {
if (pp->dir != sp->airport[pp->dest_no].dir)
loser(pp, "landed in the wrong direction.");
else {
pp->status = S_GONE;
continue;
}
}
break;
case T_EXIT:
if (pp->xpos == sp->exit[pp->dest_no].x &&
pp->ypos == sp->exit[pp->dest_no].y) {
if (pp->altitude != 9)
loser(pp, "exited at the wrong altitude.");
else {
pp->status = S_GONE;
continue;
}
}
break;
default:
loser(pp, "has a bizarre destination, get help!");
}
if (pp->altitude > 9)
/* "this is impossible" */
loser(pp, "exceded flight ceiling.");
if (pp->altitude <= 0) {
for (i = 0; i < sp->num_airports; i++)
if (pp->xpos == sp->airport[i].x &&
pp->ypos == sp->airport[i].y) {
if (pp->dest_type == T_AIRPORT)
loser(pp,
"landed at the wrong airport.");
else
loser(pp,
"landed instead of exited.");
}
loser(pp, "crashed on the ground.");
}
if (pp->xpos < 1 || pp->xpos >= sp->width - 1 ||
pp->ypos < 1 || pp->ypos >= sp->height - 1) {
for (i = 0; i < sp->num_exits; i++)
if (pp->xpos == sp->exit[i].x &&
pp->ypos == sp->exit[i].y) {
if (pp->dest_type == T_EXIT)
loser(pp,
"exited via the wrong exit.");
else
loser(pp,
"exited instead of landed.");
}
loser(pp, "illegally left the flight arena.");
}
}
/*
* Traverse the list once, deleting the planes that are gone.
*/
for (pp = air.head; pp != NULL; pp = p2) {
p2 = pp->next;
if (pp->status == S_GONE) {
safe_planes++;
delete(&air, pp);
}
}
draw_all();
for (p1 = air.head; p1 != NULL; p1 = p1->next)
for (p2 = p1->next; p2 != NULL; p2 = p2->next)
if (too_close(p1, p2, 1)) {
static char buf[80];
(void)sprintf(buf, "collided with plane '%c'.",
name(p2));
loser(p1, buf);
}
/*
* Check every other update. Actually, only add on even updates.
* Otherwise, prop jobs show up *on* entrance. Remember that
* we don't update props on odd updates.
*/
if ((rand() % sp->newplane_time) == 0)
addplane();
#ifdef SYSV
alarm(sp->update_secs);
#endif
}
const char *
command(pp)
const PLANE *pp;
{
static char buf[50], *bp, *comm_start;
buf[0] = '\0';
bp = buf;
(void)sprintf(bp, "%c%d%c%c%d: ", name(pp), pp->altitude,
(pp->fuel < LOWFUEL) ? '*' : ' ',
(pp->dest_type == T_AIRPORT) ? 'A' : 'E', pp->dest_no);
comm_start = bp = strchr(buf, '\0');
if (pp->altitude == 0)
(void)sprintf(bp, "Holding @ A%d", pp->orig_no);
else if (pp->new_dir >= MAXDIR || pp->new_dir < 0)
strcpy(bp, "Circle");
else if (pp->new_dir != pp->dir)
(void)sprintf(bp, "%d", dir_deg(pp->new_dir));
bp = strchr(buf, '\0');
if (pp->delayd)
(void)sprintf(bp, " @ B%d", pp->delayd_no);
bp = strchr(buf, '\0');
if (*comm_start == '\0' &&
(pp->status == S_UNMARKED || pp->status == S_IGNORED))
strcpy(bp, "---------");
return (buf);
}
char
name(p)
const PLANE *p;
{
if (p->plane_type == 0)
return ('A' + p->plane_no);
else
return ('a' + p->plane_no);
}
int
number(l)
char l;
{
if (l < 'a' && l > 'z' && l < 'A' && l > 'Z')
return (-1);
else if (l >= 'a' && l <= 'z')
return (l - 'a');
else
return (l - 'A');
}
int
next_plane()
{
static int last_plane = -1;
PLANE *pp;
int found, start_plane = last_plane;
do {
found = 0;
last_plane++;
if (last_plane >= 26)
last_plane = 0;
for (pp = air.head; pp != NULL; pp = pp->next)
if (pp->plane_no == last_plane) {
found++;
break;
}
if (!found)
for (pp = ground.head; pp != NULL; pp = pp->next)
if (pp->plane_no == last_plane) {
found++;
break;
}
} while (found && last_plane != start_plane);
if (last_plane == start_plane)
return (-1);
return (last_plane);
}
int
addplane()
{
PLANE p, *pp, *p1;
int i, num_starts, close, rnd, rnd2, pnum;
memset(&p, 0, sizeof (p));
p.status = S_MARKED;
p.plane_type = random() % 2;
num_starts = sp->num_exits + sp->num_airports;
rnd = random() % num_starts;
if (rnd < sp->num_exits) {
p.dest_type = T_EXIT;
p.dest_no = rnd;
} else {
p.dest_type = T_AIRPORT;
p.dest_no = rnd - sp->num_exits;
}
/* loop until we get a plane not near another */
for (i = 0; i < num_starts; i++) {
/* loop till we get a different start point */
while ((rnd2 = random() % num_starts) == rnd)
;
if (rnd2 < sp->num_exits) {
p.orig_type = T_EXIT;
p.orig_no = rnd2;
p.xpos = sp->exit[rnd2].x;
p.ypos = sp->exit[rnd2].y;
p.new_dir = p.dir = sp->exit[rnd2].dir;
p.altitude = p.new_altitude = 7;
close = 0;
for (p1 = air.head; p1 != NULL; p1 = p1->next)
if (too_close(p1, &p, 4)) {
close++;
break;
}
if (close)
continue;
} else {
p.orig_type = T_AIRPORT;
p.orig_no = rnd2 - sp->num_exits;
p.xpos = sp->airport[p.orig_no].x;
p.ypos = sp->airport[p.orig_no].y;
p.new_dir = p.dir = sp->airport[p.orig_no].dir;
p.altitude = p.new_altitude = 0;
}
p.fuel = sp->width + sp->height;
break;
}
if (i >= num_starts)
return (-1);
pnum = next_plane();
if (pnum < 0)
return (-1);
p.plane_no = pnum;
pp = newplane();
if (pp == NULL)
loser(pp, "Out of memory!");
memcpy(pp, &p, sizeof (p));
if (pp->orig_type == T_AIRPORT)
append(&ground, pp);
else
append(&air, pp);
return (pp->dest_type);
}
PLANE *
findplane(n)
int n;
{
PLANE *pp;
for (pp = air.head; pp != NULL; pp = pp->next)
if (pp->plane_no == n)
return (pp);
for (pp = ground.head; pp != NULL; pp = pp->next)
if (pp->plane_no == n)
return (pp);
return (NULL);
}
int
too_close(p1, p2, dist)
const PLANE *p1, *p2;
int dist;
{
if (ABS(p1->altitude - p2->altitude) <= dist &&
ABS(p1->xpos - p2->xpos) <= dist && ABS(p1->ypos - p2->ypos) <= dist)
return (1);
else
return (0);
}
int
dir_deg(d)
int d;
{
switch (d) {
case 0: return (0);
case 1: return (45);
case 2: return (90);
case 3: return (135);
case 4: return (180);
case 5: return (225);
case 6: return (270);
case 7: return (315);
default:
return (-1);
}
}

8
backgammon/Makefile.bsd Normal file
View File

@@ -0,0 +1,8 @@
# $NetBSD: Makefile,v 1.5 1997/10/16 05:24:23 lukem Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
SUBDIR= common_source backgammon teachgammon
all-backgammon all-teachgammon: all-common_source
.include <bsd.subdir.mk>

View File

@@ -0,0 +1,12 @@
# $NetBSD: Makefile.inc,v 1.5 1998/02/02 14:14:55 christos Exp $
LIBCOMMON != cd ${.CURDIR}/../common_source;\
printf "xxx: .MAKE\n\t@echo \$${.OBJDIR}\n" | ${MAKE} -s -f-
CPPFLAGS+=-DV7 -I${.CURDIR}/../common_source
DPADD+= ${LIBCOMMON}/libcommon.a ${LIBTERMCAP}
LDADD+= -L${LIBCOMMON} -lcommon -ltermcap
HIDEGAME=hidegame
.include "../Makefile.inc"

5
backgammon/Makefrag Normal file
View File

@@ -0,0 +1,5 @@
# Makefrag - makefile fragment for backgammon
backgammon_all:
backgammon_install:

View File

@@ -0,0 +1,8 @@
# $NetBSD: Makefile,v 1.9 1997/10/10 08:59:34 lukem Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= backgammon
SRCS= extra.c main.c move.c text.c version.c
MAN= backgammon.6
.include <bsd.prog.mk>

View File

@@ -0,0 +1,12 @@
# Makefile - makefile fragment for backgammon/backgammon
backgammon_backgammon_DEFS := -DV7
backgammon_backgammon_DIRS := $(GAMESDIR) $(MAN6DIR)
backgammon_backgammon_INCS := -Ibackgammon/common_source
backgammon_backgammon_all: backgammon/backgammon/backgammon backgammon/backgammon/backgammon.6
backgammon_backgammon_install: backgammon_backgammon_all
$(INSTALL_BINARY) backgammon/backgammon/backgammon $(INSTALL_PREFIX)$(GAMESDIR)/backgammon
$(HIDE_GAME) backgammon
$(INSTALL_MANUAL) backgammon/backgammon/backgammon.6

View File

@@ -0,0 +1,187 @@
.\" $NetBSD: backgammon.6,v 1.7 1998/09/13 15:21:05 hubertf 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. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)backgammon.6 8.1 (Berkeley) 5/31/93
.\"
.Dd May 31, 1993
.Dt BACKGAMMON 6
.Os
.Sh NAME
.Nm backgammon
.Nd the game of backgammon
.br
.Nm teachgammon
.Nd learn to play backgammon
.Sh SYNOPSIS
.Nm
.Op Fl
.Op Fl nrwb
.Op Fl pr
.Op Fl pw
.Op Fl pb
.Op Fl t Ar term
.Op Fl s Ar file
.br
.Nm teachgammon
.Sh DESCRIPTION
This program lets you play backgammon against the computer
or against a "friend".
All commands only are one letter,
so you don't need to type a carriage return,
except at the end of a move.
The program is mostly self documenting,
so that a question mark (?) will usually get some help.
If you answer `y' when the program asks if you want the rules,
you will get text explaining the rules of the game,
some hints on strategy,
instruction on how to use the program,
and a tutorial consisting of a practice game against the computer.
A description of how to use the program can be
obtained by answering `y' when it asks if you want instructions.
.Pp
The possible arguments for backgammon
(most are unnecessary but some are very convenient)
consist of:
.Bl -tag -width indent
.It Fl n
don't ask for rules or instructions
.It Fl r
player is red (implies n)
.It Fl w
player is white (implies n)
.It Fl b
two players, red and white (implies n)
.It Fl pr
print the board before red's turn
.It Fl pw
print the board before white's turn
.It Fl pb
print the board before both player's turn
.It Fl t Ar term
terminal is type
.Ar term ,
uses
.Pa /usr/share/misc/termcap
.It Fl s Ar file
recover previously saved game from
.Ar file .
.El
.Pp
.\"
.\" Arguments may be optionally preceded by a `-'.
.\" Several arguments may be concatenated together,
.\" but not after `s' or `t' arguments,
.\" since they can be followed by an arbitrary string.
Any unrecognized arguments are ignored.
An argument of a lone `-' gets a description of possible arguments.
.Pp
If
.Ar term
has capabilities for direct cursor movement (see
.Xr termcap 5 )
.Nm
``fixes'' the board after each move,
so the board does not need to be reprinted,
unless the screen suffers some horrendous malady.
Also, any `p' option will be ignored.
(The `t' option is not necessary unless the terminal type does not match
the entry in the
.Pa /usr/share/misc/termcap
data base.)
.Sh QUICK REFERENCE
When the program prompts by typing only your color,
type a space or carriage return to roll, or
.Bl -tag -width indent
.It Ic d
to double
.It Ic p
to print the board
.It Ic q
to quit
.It Ic s
to save the game for later
.El
.Pp
When the program prompts with 'Move:', type
.Bl -tag -width indent
.It Ic p
to print the board
.It Ic q
to quit
.It Ic s
to save the game
.El
.Pp
or a
.Em move ,
which is a sequence of
.Bl -tag -width indent
.It Ic s-f
move from
.Ic s
to
.Ic f
.It Ic s/r
move one man on
.Ic s
the roll
.Ic r
separated by commas or spaces and ending with a newline.
Available abbreviations are
.Bl -tag -width indent
.It Ic s-f1-f2
means
.Ic s-f1,f1-f2
.It Ic s/r1r2
means
.Ic s/r1,s/r2
.El
.El
.Pp
Use
.Ic b
for bar and
.Ic h
for home,
or 0 or 25 as appropriate.
.Sh AUTHOR
Alan Char
.Sh FILES
.Bl -tag -width /usr/share/misc/termcap -compact
.It Pa @gamesdir@/teachgammon
rules and tutorial
.It Pa /usr/share/misc/termcap
terminal capabilities
.El
.Sh BUGS
The program's strategy needs much work.

View File

@@ -0,0 +1,48 @@
/* $NetBSD: backlocal.h,v 1.1 1997/10/10 08:59:35 lukem Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Luke Mewburn.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
void dble __P((void));
int dblgood __P((void));
int eval __P((void));
int freemen __P((int));
void movcmp __P((void));
void move __P((int));
int movegood __P((void));
void pickmove __P((void));
int trapped __P((int, int));
void trymove __P((int, int));

View File

@@ -0,0 +1,258 @@
/* $NetBSD: extra.c,v 1.4 1997/10/10 08:59:36 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)extra.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: extra.c,v 1.4 1997/10/10 08:59:36 lukem Exp $");
#endif
#endif /* not lint */
#include "back.h"
#include "backlocal.h"
#ifdef DEBUG
FILE *trace;
#endif
/*
* dble()
* Have the current player double and ask opponent to accept.
*/
void
dble()
{
int resp; /* response to y/n */
for (;;) {
writel(" doubles."); /* indicate double */
if (cturn == -pnum) { /* see if computer accepts */
if (dblgood()) { /* guess not */
writel(" Declined.\n");
nexturn();
cturn *= -2; /* indicate loss */
return;
} else {/* computer accepts */
writel(" Accepted.\n");
gvalue *= 2; /* double game value */
dlast = cturn;
if (tflag)
gwrite();
return;
}
}
/* ask if player accepts */
writel(" Does ");
writel(cturn == 1 ? color[2] : color[3]);
writel(" accept?");
/* get response from yorn, a "2" means he said "p" for print
* board. */
if ((resp = yorn('R')) == 2) {
writel(" Reprint.\n");
buflush();
wrboard();
writel(*Colorptr);
continue;
}
/* check response */
if (resp) {
/* accepted */
gvalue *= 2;
dlast = cturn;
if (tflag)
gwrite();
return;
}
nexturn(); /* declined */
cturn *= -2;
return;
}
}
/*
* dblgood ()
* Returns 1 if the computer would double in this position. This
* is not an exact science. The computer will decline a double that he
* would have made. Accumulated judgments are kept in the variable n,
* which is in "pips", i.e., the position of each man summed over all
* men, with opponent's totals negative. Thus, n should have a positive
* value of 7 for each move ahead, or a negative value of 7 for each one
* behind.
*/
int
dblgood()
{
int n; /* accumulated judgment */
int OFFC = *offptr; /* no. of computer's men off */
int OFFO = *offopp; /* no. of player's men off */
#ifdef DEBUG
int i;
if (trace == NULL)
trace = fopen("bgtrace", "w");
#endif
/* get real pip value */
n = eval() * cturn;
#ifdef DEBUG
fputs("\nDoubles:\nBoard: ", trace);
for (i = 0; i < 26; i++)
fprintf(trace, " %d", board[i]);
fprintf(trace, "\n\tpip = %d, ", n);
#endif
/* below adjusts pip value according to position judgments */
/* check men moving off board */
if (OFFC > -15 || OFFO > -15) {
if (OFFC < 0 && OFFO < 0) {
OFFC += 15;
OFFO += 15;
n += ((OFFC - OFFO) * 7) / 2;
} else
if (OFFC < 0) {
OFFC += 15;
n -= OFFO * 7 / 2;
} else
if (OFFO < 0) {
OFFO += 15;
n += OFFC * 7 / 2;
}
if (OFFC < 8 && OFFO > 8)
n -= 7;
if (OFFC < 10 && OFFO > 10)
n -= 7;
if (OFFC < 12 && OFFO > 12)
n -= 7;
if (OFFO < 8 && OFFC > 8)
n += 7;
if (OFFO < 10 && OFFC > 10)
n += 7;
if (OFFO < 12 && OFFC > 12)
n += 7;
n += ((OFFC - OFFO) * 7) / 2;
}
#ifdef DEBUG
fprintf(trace, "off = %d, ", n);
#endif
/* see if men are trapped */
n -= freemen(bar);
n += freemen(home);
n += trapped(home, -cturn);
n -= trapped(bar, cturn);
#ifdef DEBUG
fprintf(trace, "free = %d\n", n);
fprintf(trace, "\tOFFC = %d, OFFO = %d\n", OFFC, OFFO);
fflush(trace);
#endif
/* double if 2-3 moves ahead */
if (n > 10 + rnum(7))
return (1);
return (0);
}
int
freemen(b)
int b;
{
int i, inc, lim;
odds(0, 0, 0);
if (board[b] == 0)
return (0);
inc = (b == 0 ? 1 : -1);
lim = (b == 0 ? 7 : 18);
for (i = b + inc; i != lim; i += inc)
if (board[i] * inc < -1)
odds(abs(b - i), 0, abs(board[b]));
if (abs(board[b]) == 1)
return ((36 - count()) / 5);
return (count() / 5);
}
int
trapped(n, inc)
int n, inc;
{
int i, j, k;
int c, l, ct;
ct = 0;
l = n + 7 * inc;
for (i = n + inc; i != l; i += inc) {
odds(0, 0, 0);
c = abs(i - l);
if (board[i] * inc > 0) {
for (j = c; j < 13; j++)
if (board[i + inc * j] * inc < -1) {
if (j < 7)
odds(j, 0, 1);
for (k = 1; k < 7 && k < j; k++)
if (j - k < 7)
odds(k, j - k, 1);
}
ct += abs(board[i]) * (36 - count());
}
}
return (ct / 5);
}
int
eval()
{
int i, j;
for (j = i = 0; i < 26; i++)
j += (board[i] >= 0 ? i * board[i] : (25 - i) * board[i]);
if (off[1] >= 0)
j += 25 * off[1];
else
j += 25 * (off[1] + 15);
if (off[0] >= 0)
j -= 25 * off[0];
else
j -= 25 * (off[0] + 15);
return (j);
}

View File

@@ -0,0 +1,569 @@
/* $NetBSD: main.c,v 1.7 1998/08/29 22:53:03 hubertf 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: main.c,v 1.7 1998/08/29 22:53:03 hubertf Exp $");
#endif
#endif /* not lint */
#include "back.h"
#include "backlocal.h"
#include <time.h>
#define MVPAUSE 5 /* time to sleep when stuck */
#define MAXUSERS 35 /* maximum number of users */
extern const char *const instr[]; /* text of instructions */
extern const char *const message[]; /* update message */
#ifndef NCURSES_VERSION
speed_t ospeed; /* tty output speed */
#endif
const char *const helpm[] = { /* help message */
"Enter a space or newline to roll, or",
" R to reprint the board\tD to double",
" S to save the game\tQ to quit",
0
};
const char *const contin[] = { /* pause message */
"(Type a newline to continue.)",
"",
0
};
#if 0
static char user1a[] =
"Sorry, you cannot play backgammon when there are more than ";
static char user1b[] =
" users\non the system.";
static char user2a[] =
"\nThere are now more than ";
static char user2b[] =
" users on the system, so you cannot play\nanother game. ";
#endif
static const char rules[] = "\nDo you want the rules of the game?";
static const char noteach[] = "Teachgammon not available!\n\007";
static const char need[] = "Do you need instructions for this program?";
static const char askcol[] =
"Enter 'r' to play red, 'w' to play white, 'b' to play both:";
static const char rollr[] = "Red rolls a ";
static const char rollw[] = ". White rolls a ";
static const char rstart[] = ". Red starts.\n";
static const char wstart[] = ". White starts.\n";
static const char toobad1[] = "Too bad, ";
static const char unable[] = " is unable to use that roll.\n";
static const char toobad2[] = ". Too bad, ";
static const char cantmv[] = " can't move.\n";
static const char bgammon[] = "Backgammon! ";
static const char gammon[] = "Gammon! ";
static const char again[] = ".\nWould you like to play again?";
static const char svpromt[] = "Would you like to save this game?";
static const char password[] = "losfurng";
static char pbuf[10];
int
main(argc, argv)
int argc __attribute__((unused));
char **argv;
{
int i; /* non-descript index */
int l; /* non-descript index */
char c; /* non-descript character storage */
long t; /* time for random num generator */
/* revoke setgid privileges */
setregid(getgid(), getgid());
/* initialization */
bflag = 2; /* default no board */
signal(SIGINT, getout); /* trap interrupts */
if (tcgetattr(0, &old) == -1) /* get old tty mode */
errexit("backgammon(gtty)");
noech = old;
noech.c_lflag &= ~ECHO;
bg_raw = noech;
bg_raw.c_lflag &= ~ICANON; /* set up modes */
ospeed = cfgetospeed(&old); /* for termlib */
/* check user count */
#ifdef CORY
if (ucount() > MAXUSERS) {
writel(user1a);
wrint(MAXUSERS);
writel(user1b);
getout(0);
}
#endif
/* get terminal capabilities, and decide if it can cursor address */
tflag = getcaps(getenv("TERM"));
/* use whole screen for text */
if (tflag)
begscr = 0;
t = time(0);
srandom(t); /* 'random' seed */
#ifdef V7
while (*++argv != 0) /* process arguments */
#else
while (*++argv != -1) /* process arguments */
#endif
getarg(&argv);
args[acnt] = '\0';
if (tflag) { /* clear screen */
noech.c_oflag &= ~(ONLCR | OXTABS);
bg_raw.c_oflag &= ~(ONLCR | OXTABS);
clear();
}
fixtty(&bg_raw); /* go into raw mode */
/* check if restored game and save flag for later */
if ((rfl = rflag) != 0) {
text(message); /* print message */
text(contin);
wrboard(); /* print board */
/* if new game, pretend to be a non-restored game */
if (cturn == 0)
rflag = 0;
} else {
rscore = wscore = 0; /* zero score */
text(message); /* update message without pausing */
if (aflag) { /* print rules */
writel(rules);
if (yorn(0)) {
fixtty(&old); /* restore tty */
execl(TEACH, "teachgammon", args, 0);
tflag = 0; /* error! */
writel(noteach);
exit(1);
} else {/* if not rules, then instructions */
writel(need);
if (yorn(0)) { /* print instructions */
clear();
text(instr);
}
}
}
init(); /* initialize board */
if (pnum == 2) {/* ask for color(s) */
writec('\n');
writel(askcol);
while (pnum == 2) {
c = readc();
switch (c) {
case 'R': /* red */
pnum = -1;
break;
case 'W': /* white */
pnum = 1;
break;
case 'B': /* both */
pnum = 0;
break;
case 'P':
if (iroll)
break;
if (tflag)
curmove(curr, 0);
else
writec('\n');
writel("Password:");
signal(SIGALRM, getout);
cflag = 1;
alarm(10);
for (i = 0; i < 10; i++) {
pbuf[i] = readc();
if (pbuf[i] == '\n')
break;
}
if (i == 10)
while (readc() != '\n');
alarm(0);
cflag = 0;
if (i < 10)
pbuf[i] = '\0';
for (i = 0; i < 9; i++)
if (pbuf[i] != password[i])
getout(0);
iroll = 1;
if (tflag)
curmove(curr, 0);
else
writec('\n');
writel(askcol);
break;
default: /* error */
writec('\007');
}
}
} else
if (!aflag)
/* pause to read message */
text(contin);
wrboard(); /* print board */
if (tflag)
curmove(18, 0);
else
writec('\n');
}
/* limit text to bottom of screen */
if (tflag)
begscr = 17;
for (;;) { /* begin game! */
/* initial roll if needed */
if ((!rflag) || raflag)
roll();
/* perform ritual of first roll */
if (!rflag) {
if (tflag)
curmove(17, 0);
while (D0 == D1) /* no doubles */
roll();
/* print rolls */
writel(rollr);
writec(D0 + '0');
writel(rollw);
writec(D1 + '0');
/* winner goes first */
if (D0 > D1) {
writel(rstart);
cturn = 1;
} else {
writel(wstart);
cturn = -1;
}
}
/* initalize variables according to whose turn it is */
if (cturn == 1) { /* red */
home = 25;
bar = 0;
inptr = &in[1];
inopp = &in[0];
offptr = &off[1];
offopp = &off[0];
Colorptr = &color[1];
colorptr = &color[3];
colen = 3;
} else { /* white */
home = 0;
bar = 25;
inptr = &in[0];
inopp = &in[1];
offptr = &off[0];
offopp = &off[1];
Colorptr = &color[0];
colorptr = &color[2];
colen = 5;
}
/* do first move (special case) */
if (!(rflag && raflag)) {
if (cturn == pnum) /* computer's move */
move(0);
else { /* player's move */
mvlim = movallow();
/* reprint roll */
if (tflag)
curmove(cturn == -1 ? 18 : 19, 0);
proll();
getmove(); /* get player's move */
}
}
if (tflag) {
curmove(17, 0);
cline();
begscr = 18;
}
/* no longer any diff- erence between normal game and
* recovered game. */
rflag = 0;
/* move as long as it's someone's turn */
while (cturn == 1 || cturn == -1) {
/* board maintainence */
if (tflag)
refresh(); /* fix board */
else
/* redo board if -p */
if (cturn == bflag || bflag == 0)
wrboard();
/* do computer's move */
if (cturn == pnum) {
move(1);
/* see if double refused */
if (cturn == -2 || cturn == 2)
break;
/* check for winning move */
if (*offopp == 15) {
cturn *= -2;
break;
}
continue;
}
/* (player's move) */
/* clean screen if safe */
if (tflag && hflag) {
curmove(20, 0);
clend();
hflag = 1;
}
/* if allowed, give him a chance to double */
if (dlast != cturn && gvalue < 64) {
if (tflag)
curmove(cturn == -1 ? 18 : 19, 0);
writel(*Colorptr);
c = readc();
/* character cases */
switch (c) {
/* reprint board */
case 'R':
wrboard();
break;
/* save game */
case 'S':
raflag = 1;
save(1);
break;
/* quit */
case 'Q':
quit();
break;
/* double */
case 'D':
dble();
break;
/* roll */
case ' ':
case '\n':
roll();
writel(" rolls ");
writec(D0 + '0');
writec(' ');
writec(D1 + '0');
writel(". ");
/* see if he can move */
if ((mvlim = movallow()) == 0) {
/* can't move */
writel(toobad1);
writel(*colorptr);
writel(unable);
if (tflag) {
if (pnum) {
buflush();
sleep(MVPAUSE);
}
}
nexturn();
break;
}
/* get move */
getmove();
/* okay to clean screen */
hflag = 1;
break;
/* invalid character */
default:
/* print help message */
if (tflag)
curmove(20, 0);
else
writec('\n');
text(helpm);
if (tflag)
curmove(cturn == -1 ? 18 : 19, 0);
else
writec('\n');
/* don't erase */
hflag = 0;
}
} else {/* couldn't double */
/* print roll */
roll();
if (tflag)
curmove(cturn == -1 ? 18 : 19, 0);
proll();
/* can he move? */
if ((mvlim = movallow()) == 0) {
/* he can't */
writel(toobad2);
writel(*colorptr);
writel(cantmv);
buflush();
sleep(MVPAUSE);
nexturn();
continue;
}
/* get move */
getmove();
}
}
/* don't worry about who won if quit */
if (cturn == 0)
break;
/* fix cturn = winner */
cturn /= -2;
/* final board pos. */
if (tflag)
refresh();
/* backgammon? */
mflag = 0;
l = bar + 7 * cturn;
for (i = bar; i != l; i += cturn)
if (board[i] * cturn)
mflag++;
/* compute game value */
if (tflag)
curmove(20, 0);
if (*offopp == 15) {
if (mflag) {
writel(bgammon);
gvalue *= 3;
} else
if (*offptr <= 0) {
writel(gammon);
gvalue *= 2;
}
}
/* report situation */
if (cturn == -1) {
writel("Red wins ");
rscore += gvalue;
} else {
writel("White wins ");
wscore += gvalue;
}
wrint(gvalue);
writel(" point");
if (gvalue > 1)
writec('s');
writel(".\n");
/* write score */
wrscore();
/* check user count */
#ifdef CORY
if (ucount() > MAXUSERS) {
writel(user2a);
wrint(MAXUSERS);
writel(user2b);
rfl = 1;
break;
}
#endif
/* see if he wants another game */
writel(again);
if ((i = yorn('S')) == 0)
break;
init();
if (i == 2) {
writel(" Save.\n");
cturn = 0;
save(0);
}
/* yes, reset game */
wrboard();
}
/* give him a chance to save if game was recovered */
if (rfl && cturn) {
writel(svpromt);
if (yorn(0)) {
/* re-initialize for recovery */
init();
cturn = 0;
save(0);
}
}
/* leave peacefully */
getout(0);
/* NOTREACHED */
return (0);
}

View File

@@ -0,0 +1,571 @@
/* $NetBSD: move.c,v 1.6 1997/10/10 08:59:37 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)move.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: move.c,v 1.6 1997/10/10 08:59:37 lukem Exp $");
#endif
#endif /* not lint */
#include "back.h"
#include "backlocal.h"
#ifdef DEBUG
FILE *trace;
static char tests[20];
#endif
struct BOARD { /* structure of game position */
int b_board[26]; /* board position */
int b_in[2]; /* men in */
int b_off[2]; /* men off */
int b_st[4], b_fn[4]; /* moves */
struct BOARD *b_next; /* forward queue pointer */
};
struct BOARD *freeq = 0;
struct BOARD *checkq = 0;
/* these variables are values for the candidate move */
static int ch; /* chance of being hit */
static int op; /* computer's open men */
static int pt; /* comp's protected points */
static int em; /* farthest man back */
static int frc; /* chance to free comp's men */
static int frp; /* chance to free pl's men */
/* these values are the values for the move chosen (so far) */
static int chance; /* chance of being hit */
static int openmen; /* computer's open men */
static int points; /* comp's protected points */
static int endman; /* farthest man back */
static int barmen; /* men on bar */
static int menin; /* men in inner table */
static int menoff; /* men off board */
static int oldfrc; /* chance to free comp's men */
static int oldfrp; /* chance to free pl's men */
static int cp[5]; /* candidate start position */
static int cg[5]; /* candidate finish position */
static int race; /* game reduced to a race */
static int bcomp __P((struct BOARD *, struct BOARD *));
static struct BOARD *bsave __P((void));
static void binsert __P((struct BOARD *));
static void boardcopy __P((struct BOARD *));
static void makefree __P((struct BOARD *));
static void mvcheck __P((struct BOARD *, struct BOARD *));
static struct BOARD *nextfree __P((void));
void
move(okay)
int okay; /* zero if first move */
{
int i; /* index */
int l; /* last man */
l = 0;
if (okay) {
/* see if comp should double */
if (gvalue < 64 && dlast != cturn && dblgood()) {
writel(*Colorptr);
dble(); /* double */
/* return if declined */
if (cturn != 1 && cturn != -1)
return;
}
roll();
}
race = 0;
for (i = 0; i < 26; i++) {
if (board[i] < 0)
l = i;
}
for (i = 0; i < l; i++) {
if (board[i] > 0)
break;
}
if (i == l)
race = 1;
/* print roll */
if (tflag)
curmove(cturn == -1 ? 18 : 19, 0);
writel(*Colorptr);
writel(" rolls ");
writec(D0 + '0');
writec(' ');
writec(D1 + '0');
/* make tty interruptable while thinking */
if (tflag)
cline();
fixtty(&noech);
/* find out how many moves */
mvlim = movallow();
if (mvlim == 0) {
writel(" but cannot use it.\n");
nexturn();
fixtty(&bg_raw);
return;
}
/* initialize */
for (i = 0; i < 4; i++)
cp[i] = cg[i] = 0;
/* strategize */
trymove(0, 0);
pickmove();
/* print move */
writel(" and moves ");
for (i = 0; i < mvlim; i++) {
if (i > 0)
writec(',');
wrint(p[i] = cp[i]);
writec('-');
wrint(g[i] = cg[i]);
makmove(i);
}
writec('.');
/* print blots hit */
if (tflag)
curmove(20, 0);
else
writec('\n');
for (i = 0; i < mvlim; i++)
if (h[i])
wrhit(g[i]);
/* get ready for next move */
nexturn();
if (!okay) {
buflush();
sleep(3);
}
fixtty(&bg_raw); /* no more tty interrupt */
}
void
trymove(mvnum, swapped)
int mvnum; /* number of move (rel zero) */
int swapped; /* see if swapped also tested */
{
int pos; /* position on board */
int rval; /* value of roll */
/* if recursed through all dice values, compare move */
if (mvnum == mvlim) {
binsert(bsave());
return;
}
/* make sure dice in always same order */
if (d0 == swapped)
swap;
/* choose value for this move */
rval = dice[mvnum != 0];
/* find all legitimate moves */
for (pos = bar; pos != home; pos += cturn) {
/* fix order of dice */
if (d0 == swapped)
swap;
/* break if stuck on bar */
if (board[bar] != 0 && pos != bar)
break;
/* on to next if not occupied */
if (board[pos] * cturn <= 0)
continue;
/* set up arrays for move */
p[mvnum] = pos;
g[mvnum] = pos + rval * cturn;
if (g[mvnum] * cturn >= home) {
if (*offptr < 0)
break;
g[mvnum] = home;
}
/* try to move */
if (makmove(mvnum))
continue;
else
trymove(mvnum + 1, 2);
/* undo move to try another */
backone(mvnum);
}
/* swap dice and try again */
if ((!swapped) && D0 != D1)
trymove(0, 1);
}
static struct BOARD *
bsave()
{
int i; /* index */
struct BOARD *now; /* current position */
now = nextfree(); /* get free BOARD */
/* store position */
for (i = 0; i < 26; i++)
now->b_board[i] = board[i];
now->b_in[0] = in[0];
now->b_in[1] = in[1];
now->b_off[0] = off[0];
now->b_off[1] = off[1];
for (i = 0; i < mvlim; i++) {
now->b_st[i] = p[i];
now->b_fn[i] = g[i];
}
return (now);
}
static void
binsert(new)
struct BOARD *new; /* item to insert */
{
struct BOARD *p = checkq; /* queue pointer */
int result; /* comparison result */
if (p == 0) { /* check if queue empty */
checkq = p = new;
p->b_next = 0;
return;
}
result = bcomp(new, p); /* compare to first element */
if (result < 0) { /* insert in front */
new->b_next = p;
checkq = new;
return;
}
if (result == 0) { /* duplicate entry */
mvcheck(p, new);
makefree(new);
return;
}
while (p->b_next != 0) {/* traverse queue */
result = bcomp(new, p->b_next);
if (result < 0) { /* found place */
new->b_next = p->b_next;
p->b_next = new;
return;
}
if (result == 0) { /* duplicate entry */
mvcheck(p->b_next, new);
makefree(new);
return;
}
p = p->b_next;
}
/* place at end of queue */
p->b_next = new;
new->b_next = 0;
}
static int
bcomp(a, b)
struct BOARD *a;
struct BOARD *b;
{
int *aloc = a->b_board; /* pointer to board a */
int *bloc = b->b_board; /* pointer to board b */
int i; /* index */
int result; /* comparison result */
for (i = 0; i < 26; i++) { /* compare boards */
result = cturn * (aloc[i] - bloc[i]);
if (result)
return (result); /* found inequality */
}
return (0); /* same position */
}
static void
mvcheck(incumbent, candidate)
struct BOARD *incumbent;
struct BOARD *candidate;
{
int i;
int result;
for (i = 0; i < mvlim; i++) {
result = cturn * (candidate->b_st[i] - incumbent->b_st[i]);
if (result > 0)
return;
if (result < 0)
break;
}
if (i == mvlim)
return;
for (i = 0; i < mvlim; i++) {
incumbent->b_st[i] = candidate->b_st[i];
incumbent->b_fn[i] = candidate->b_fn[i];
}
}
void
makefree(dead)
struct BOARD *dead; /* dead position */
{
dead->b_next = freeq; /* add to freeq */
freeq = dead;
}
static struct BOARD *
nextfree()
{
struct BOARD *new;
if (freeq == 0) {
new = (struct BOARD *) calloc(1, sizeof(struct BOARD));
if (new == 0) {
writel("\nOut of memory\n");
getout(0);
}
} else {
new = freeq;
freeq = freeq->b_next;
}
new->b_next = 0;
return (new);
}
void
pickmove()
{
/* current game position */
struct BOARD *now = bsave();
struct BOARD *next; /* next move */
#ifdef DEBUG
if (trace == NULL)
trace = fopen("bgtrace", "w");
fprintf(trace, "\nRoll: %d %d%s\n", D0, D1, race ? " (race)" : "");
fflush(trace);
#endif
do { /* compare moves */
boardcopy(checkq);
next = checkq->b_next;
makefree(checkq);
checkq = next;
movcmp();
} while (checkq != 0);
boardcopy(now);
}
static void
boardcopy(s)
struct BOARD *s; /* game situation */
{
int i; /* index */
for (i = 0; i < 26; i++)
board[i] = s->b_board[i];
for (i = 0; i < 2; i++) {
in[i] = s->b_in[i];
off[i] = s->b_off[i];
}
for (i = 0; i < mvlim; i++) {
p[i] = s->b_st[i];
g[i] = s->b_fn[i];
}
}
void
movcmp()
{
int i;
#ifdef DEBUG
if (trace == NULL)
trace = fopen("bgtrace", "w");
#endif
odds(0, 0, 0);
if (!race) {
ch = op = pt = 0;
for (i = 1; i < 25; i++) {
if (board[i] == cturn)
ch = canhit(i, 1);
op += abs(bar - i);
}
for (i = bar + cturn; i != home; i += cturn)
if (board[i] * cturn > 1)
pt += abs(bar - i);
frc = freemen(bar) + trapped(bar, cturn);
frp = freemen(home) + trapped(home, -cturn);
}
for (em = bar; em != home; em += cturn)
if (board[em] * cturn > 0)
break;
em = abs(home - em);
#ifdef DEBUG
fputs("Board: ", trace);
for (i = 0; i < 26; i++)
fprintf(trace, " %d", board[i]);
if (race)
fprintf(trace, "\n\tem = %d\n", em);
else
fprintf(trace,
"\n\tch = %d, pt = %d, em = %d, frc = %d, frp = %d\n",
ch, pt, em, frc, frp);
fputs("\tMove: ", trace);
for (i = 0; i < mvlim; i++)
fprintf(trace, " %d-%d", p[i], g[i]);
fputs("\n", trace);
fflush(trace);
strcpy(tests, "");
#endif
if ((cp[0] == 0 && cg[0] == 0) || movegood()) {
#ifdef DEBUG
fprintf(trace, "\t[%s] ... wins.\n", tests);
fflush(trace);
#endif
for (i = 0; i < mvlim; i++) {
cp[i] = p[i];
cg[i] = g[i];
}
if (!race) {
chance = ch;
openmen = op;
points = pt;
endman = em;
barmen = abs(board[home]);
oldfrc = frc;
oldfrp = frp;
}
menin = *inptr;
menoff = *offptr;
}
#ifdef DEBUG
else {
fprintf(trace, "\t[%s] ... loses.\n", tests);
fflush(trace);
}
#endif
}
int
movegood()
{
int n;
if (*offptr == 15)
return (1);
if (menoff == 15)
return (0);
if (race) {
#ifdef DEBUG
strcat(tests, "o");
#endif
if (*offptr - menoff)
return (*offptr > menoff);
#ifdef DEBUG
strcat(tests, "e");
#endif
if (endman - em)
return (endman > em);
#ifdef DEBUG
strcat(tests, "i");
#endif
if (menin == 15)
return (0);
if (*inptr == 15)
return (1);
#ifdef DEBUG
strcat(tests, "i");
#endif
if (*inptr - menin)
return (*inptr > menin);
return (rnum(2));
} else {
n = barmen - abs(board[home]);
#ifdef DEBUG
strcat(tests, "c");
#endif
if (abs(chance - ch) + 25 * n > rnum(150))
return (n ? (n < 0) : (ch < chance));
#ifdef DEBUG
strcat(tests, "o");
#endif
if (*offptr - menoff)
return (*offptr > menoff);
#ifdef DEBUG
strcat(tests, "o");
#endif
if (abs(openmen - op) > 7 + rnum(12))
return (openmen > op);
#ifdef DEBUG
strcat(tests, "b");
#endif
if (n)
return (n < 0);
#ifdef DEBUG
strcat(tests, "e");
#endif
if (abs(endman - em) > rnum(2))
return (endman > em);
#ifdef DEBUG
strcat(tests, "f");
#endif
if (abs(frc - oldfrc) > rnum(2))
return (frc < oldfrc);
#ifdef DEBUG
strcat(tests, "p");
#endif
if (abs(n = pt - points) > rnum(4))
return (n > 0);
#ifdef DEBUG
strcat(tests, "i");
#endif
if (*inptr - menin)
return (*inptr > menin);
#ifdef DEBUG
strcat(tests, "f");
#endif
if (abs(frp - oldfrp) > rnum(2))
return (frp > oldfrp);
return (rnum(2));
}
}

View File

@@ -0,0 +1,139 @@
/* $NetBSD: text.c,v 1.5 1997/10/10 08:59:38 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)text.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: text.c,v 1.5 1997/10/10 08:59:38 lukem Exp $");
#endif
#endif /* not lint */
#include "back.h"
const char *const instr[] = {
" If you did not notice by now, this program reacts to things as",
"soon as you type them, without waiting for a newline. This means that",
"the special characters RUBOUT, ESC, and CONTROL-D, will not perform",
"their special functions during most of this program. The program",
"should usually stop when a RUBOUT is typed, but occasionally it will",
"ignore RUBOUTs until it is waiting for input.\n",
" These instructions are presented in small chunks designed not to",
"roll off the top of your screen. When the characters '-->' are print-",
"ed, no more data will be printed until a space or newline is typed.",
"In this way, you can finish one section before continuing to another.",
"Like this:",
"",
" The two sides are colored 'red' and 'white.' The computer may play",
"one side, or if there are two players, the computer can merely act as",
"a gamekeeper, letting the players make the moves. Once you tell the",
"computer what color(s) you want to play, the decision remains in ef-",
"fect until you quit the program, even if you play more than one game,",
"since the program keeps a running score.\n",
" The program will prompt for a move in one of two ways. If the",
"player has the opportunity to double, then merely his color will be",
"typed out. The player can now do one of several things. He can dou-",
"ble by typing a 'd', he can roll by typing a space (' ') or newline,",
"or if he is not sure, he can reprint the board by typing a 'r'.\n",
" If the player cannot double, his roll will be thrust in front of",
"him, followed by the request 'Move:', asking for a move but not giving",
"him the chance to double. He can still ask for the board by typing",
"'r'. In either of these two states, the player can quit by typing 'q'",
"or save the game by typing 's'. In either case, the player will be",
"asked to verify, in case there was some error. The program then ends",
"immediately, after first saving the file if so requested.",
"",
" A player can move one of his men using two forms of input. The",
"first form is <s>-<f>, where <s> is the starting position, and <f> is",
"the finishing position of the player's man. For example, if white",
"wanted to move a piece from position 13 to position 8, his move could",
"be entered as 13-8. The second form is <s>/<r> where <s> is the",
"starting position, an <r> is the roll actually made. Hence, white",
"could have entered as 13/5 instead of 13-8.\n",
" A player must move each roll of the dice separately. For example,",
"if a player rolled 4 3, and wanted to move from 13 to 6, he could",
"enter it as 13/4,9/3 or 13/3,10/4 or 13-10,10-6 or 13-9,9-6, but not",
"13-6. The last two entries can be shortened to 13-10-6 and 13-9-6.",
"If you want to move more than one piece from the same position, such",
"as 13-10,13-9, you can abbreviate this using the <s>/<r> format as by",
"entering more than one <r>, or 13/34. A player can use both forms for",
"the same roll, e.g. 13/3,13-9, and separates individual moves by ei-",
"ther a comma or a space. The letter 'b' represents the bar, and the",
"letter 'h' represents a player's home. You could also enter the",
"number that would be in the position of the bar, 25 or 0 as appropri-",
"ate. Use a newline at the end of your moves for a turn.",
"",
" As you type in your move, if a character does not make sense under",
"the above constrictions, a bell will sound instead of the character,",
"and it will be ignored. You may kill lines and erase characters as",
"you would normally, but don't be surprised if they look different than",
"usual. Also, if you have entered one or more of your rolls, and you",
"wish to see what the move looks like so far, type a 'r' to see what it",
"looks like. This cannot be done in the middle of a move (e.g., after",
"a '-' or '/'). After the printing board, the program will go back to",
"inputting your move and you can backspace or kill just as if you had",
"just typed in your input.\n",
" Now you should be ready to begin the game. Good luck!",
"",
0};
int
text(t)
const char *const *t;
{
int i;
const char *s, *a;
fixtty(&noech);
while (*t != 0) {
s = a = *t;
for (i = 0; *a != '\0'; i--)
a++;
if (i) {
writel(s);
writec('\n');
} else {
writel("-->");
fixtty(&bg_raw);
while ((i = readc()) != ' ' && i != '\n');
fixtty(&noech);
clear();
}
t++;
}
fixtty(&bg_raw);
return (0);
}

View File

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

View File

@@ -0,0 +1,13 @@
# $NetBSD: Makefile,v 1.3 1997/10/11 20:24:06 mycroft Exp $
LIB= common
SRCS= allow.c board.c check.c fancy.c init.c odds.c one.c save.c subs.c \
table.c
NOPROFILE= noprofile
NOPIC= nopic
# only needed during build
libinstall::
.include <bsd.lib.mk>

View File

@@ -0,0 +1,10 @@
# Makefrag - makefile fragment for backgammon/common_source
backgammon_common_source_EXEC_PATH := $(GAMESDIR)/backgammon
backgammon_common_source_TEACH_PATH := $(GAMESDIR)/teachgammon
backgammon_common_source_DEFS := -DEXEC_PATH=\"$(backgammon_common_source_EXEC_PATH)\" -DTEACH_PATH=\"$(backgammon_common_source_TEACH_PATH)\"
backgammon_common_source_all:
backgammon_common_source_install:

View File

@@ -0,0 +1,117 @@
/* $NetBSD: allow.c,v 1.4 1997/10/10 08:59:41 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)allow.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: allow.c,v 1.4 1997/10/10 08:59:41 lukem Exp $");
#endif
#endif /* not lint */
#include "back.h"
int
movallow()
{
int i, m, iold;
int r;
if (d0)
swap;
m = (D0 == D1 ? 4 : 2);
for (i = 0; i < 4; i++)
p[i] = bar;
i = iold = 0;
while (i < m) {
if (*offptr == 15)
break;
h[i] = 0;
if (board[bar]) {
if (i == 1 || m == 4)
g[i] = bar + cturn * D1;
else
g[i] = bar + cturn * D0;
if ((r = makmove(i)) != 0) {
if (d0 || m == 4)
break;
swap;
movback(i);
if (i > iold)
iold = i;
for (i = 0; i < 4; i++)
p[i] = bar;
i = 0;
} else
i++;
continue;
}
if ((p[i] += cturn) == home) {
if (i > iold)
iold = i;
if (m == 2 && i) {
movback(i);
p[i--] = bar;
if (p[i] != bar)
continue;
else
break;
}
if (d0 || m == 4)
break;
swap;
movback(i);
for (i = 0; i < 4; i++)
p[i] = bar;
i = 0;
continue;
}
if (i == 1 || m == 4)
g[i] = p[i] + cturn * D1;
else
g[i] = p[i] + cturn * D0;
if (g[i] * cturn > home) {
if (*offptr >= 0)
g[i] = home;
else
continue;
}
if (board[p[i]] * cturn > 0 && (r = makmove(i)) == 0)
i++;
}
movback(i);
return (iold > i ? iold : i);
}

View File

@@ -0,0 +1,189 @@
/* $NetBSD: back.h,v 1.9 1998/09/13 15:31:07 hubertf 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)back.h 8.1 (Berkeley) 5/31/93
*/
#include <sys/types.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <termcap.h>
#include <unistd.h>
#define rnum(r) (random()%r)
#define D0 dice[0]
#define D1 dice[1]
#define swap {D0 ^= D1; D1 ^= D0; D0 ^= D1; d0 = 1-d0;}
/*
*
* Some numerical conventions:
*
* Arrays have white's value in [0], red in [1].
* Numeric values which are one color or the other use
* -1 for white, 1 for red.
* Hence, white will be negative values, red positive one.
* This makes a lot of sense since white is going in decending
* order around the board, and red is ascending.
*
*/
extern const char EXEC[]; /* object for main program */
extern const char TEACH[]; /* object for tutorial program */
extern int pnum; /* color of player:
-1 = white
1 = red
0 = both
2 = not yet init'ed */
extern char args[100]; /* args passed to teachgammon and back */
extern int acnt; /* length of args */
extern int aflag; /* flag to ask for rules or instructions */
extern int bflag; /* flag for automatic board printing */
extern int cflag; /* case conversion flag */
extern int hflag; /* flag for cleaning screen */
extern int mflag; /* backgammon flag */
extern int raflag; /* 'roll again' flag for recovered game */
extern int rflag; /* recovered game flag */
extern int tflag; /* cursor addressing flag */
extern int rfl; /* saved value of rflag */
extern int iroll; /* special flag for inputting rolls */
extern int board[26]; /* board: negative values are white,
positive are red */
extern int dice[2]; /* value of dice */
extern int mvlim; /* 'move limit': max. number of moves */
extern int mvl; /* working copy of mvlim */
extern int p[5]; /* starting position of moves */
extern int g[5]; /* ending position of moves (goals) */
extern int h[4]; /* flag for each move if a man was hit */
extern int cturn; /* whose turn it currently is:
-1 = white
1 = red
0 = just quitted
-2 = white just lost
2 = red just lost */
extern int d0; /* flag if dice have been reversed from
original position */
extern int table[6][6]; /* odds table for possible rolls */
extern int rscore; /* red's score */
extern int wscore; /* white's score */
extern int gvalue; /* value of game (64 max.) */
extern int dlast; /* who doubled last (0 = neither) */
extern int bar; /* position of bar for current player */
extern int home; /* position of home for current player */
extern int off[2]; /* number of men off board */
extern int *offptr; /* pointer to off for current player */
extern int *offopp; /* pointer to off for opponent */
extern int in[2]; /* number of men in inner table */
extern int *inptr; /* pointer to in for current player */
extern int *inopp; /* pointer to in for opponent */
extern int ncin; /* number of characters in cin */
extern char cin[100]; /* input line of current move
(used for reconstructing input after
a backspace) */
extern const char *const color[];
/* colors as strings */
extern const char *const *colorptr; /* color of current player */
extern const char *const *Colorptr; /* color of current player, capitalized */
extern int colen; /* length of color of current player */
extern struct termios old, noech, bg_raw;/* original tty status */
extern int curr; /* row position of cursor */
extern int curc; /* column position of cursor */
extern int begscr; /* 'beginning' of screen
(not including board) */
int addbuf __P((int));
void backone __P((int));
void bsect __P((int, int, int, int));
void buflush __P((void));
int canhit __P((int, int));
int checkd __P((int));
int checkmove __P((int));
void clear __P((void));
void clend __P((void));
void cline __P((void));
int count __P((void));
void curmove __P((int, int));
int dotable __P((char, int));
void errexit __P((const char *));
void fancyc __P((int));
void fboard __P((void));
void fixcol __P((int, int, int, int, int));
void fixpos __P((int, int, int, int, int));
void fixtty __P((struct termios *));
void getarg __P((char ***));
int getcaps __P((const char *));
void getmove __P((void));
void getout __P((int)) __attribute__((__noreturn__));
void gwrite __P((void));
void init __P((void));
int last __P((void));
int main __P((int, char *[]));
int makmove __P((int));
int movallow __P((void));
void movback __P((int));
void moverr __P((int));
int movokay __P((int));
void newline __P((void));
void newpos __P((void));
void nexturn __P((void));
void norec __P((const char *));
void odds __P((int, int, int));
void proll __P((void));
int quit __P((void));
int readc __P((void));
void recover __P((const char *));
void refresh __P((void));
void roll __P((void));
int rsetbrd __P((void));
void save __P((int));
int text __P((const char *const *));
void wrboard __P((void));
void wrbsub __P((void));
void wrhit __P((int));
void wrint __P((int));
void writec __P((char));
void writel __P((const char *));
void wrscore __P((void));
int yorn __P((char));

View File

@@ -0,0 +1,186 @@
/* $NetBSD: board.c,v 1.5 1997/10/10 08:59:43 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)board.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: board.c,v 1.5 1997/10/10 08:59:43 lukem Exp $");
#endif
#endif /* not lint */
#include "back.h"
static int i, j, k;
static char ln[60];
void
wrboard()
{
int l;
static const char bl[] =
"| | | |\n";
static const char sv[] =
"| | | | \n";
fixtty(&noech);
clear();
if (tflag) {
fboard();
goto lastline;
}
writel("_____________________________________________________\n");
writel(bl);
strcpy(ln, bl);
for (j = 1; j < 50; j += 4) {
k = j / 4 + (j > 24 ? 12 : 13);
ln[j + 1] = k % 10 + '0';
ln[j] = k / 10 + '0';
if (j == 21)
j += 4;
}
writel(ln);
for (i = 0; i < 5; i++) {
strcpy(ln, sv);
for (j = 1; j < 50; j += 4) {
k = j / 4 + (j > 24 ? 12 : 13);
wrbsub();
if (j == 21)
j += 4;
}
if (-board[25] > i)
ln[26] = 'w';
if (-board[25] > i + 5)
ln[25] = 'w';
if (-board[25] > i + 10)
ln[27] = 'w';
l = 53;
if (off[1] > i || (off[1] < 0 && off[1] + 15 > i)) {
ln[54] = 'r';
l = 55;
}
if (off[1] > i + 5 || (off[1] < 0 && off[1] + 15 > i + 5)) {
ln[55] = 'r';
l = 56;
}
if (off[1] > i + 10 || (off[1] < 0 && off[1] + 15 > i + 10)) {
ln[56] = 'r';
l = 57;
}
ln[l++] = '\n';
ln[l] = '\0';
writel(ln);
}
strcpy(ln, bl);
ln[25] = 'B';
ln[26] = 'A';
ln[27] = 'R';
writel(ln);
strcpy(ln, sv);
for (i = 4; i > -1; i--) {
for (j = 1; j < 50; j += 4) {
k = ((j > 24 ? 53 : 49) - j) / 4;
wrbsub();
if (j == 21)
j += 4;
}
if (board[0] > i)
ln[26] = 'r';
if (board[0] > i + 5)
ln[25] = 'r';
if (board[0] > i + 10)
ln[27] = 'r';
l = 53;
if (off[0] > i || (off[0] < 0 && off[0] + 15 > i)) {
ln[54] = 'w';
l = 55;
}
if (off[0] > i + 5 || (off[0] < 0 && off[0] + 15 > i + 5)) {
ln[55] = 'w';
l = 56;
}
if (off[0] > i + 10 || (off[0] < 0 && off[0] + 15 > i + 10)) {
ln[56] = 'w';
l = 57;
}
ln[l++] = '\n';
ln[l] = '\0';
writel(ln);
}
strcpy(ln, bl);
for (j = 1; j < 50; j += 4) {
k = ((j > 24 ? 53 : 49) - j) / 4;
ln[j + 1] = k % 10 + '0';
if (k > 9)
ln[j] = k / 10 + '0';
if (j == 21)
j += 4;
}
writel(ln);
writel("|_______________________|___|_______________________|\n");
lastline:
gwrite();
if (tflag)
curmove(18, 0);
else {
writec('\n');
writec('\n');
}
fixtty(&bg_raw);
}
void
wrbsub()
{
int m;
char d;
if (board[k] > 0) {
m = board[k];
d = 'r';
} else {
m = -board[k];
d = 'w';
}
if (m > i)
ln[j + 1] = d;
if (m > i + 5)
ln[j] = d;
if (m > i + 10)
ln[j + 2] = d;
}

View File

@@ -0,0 +1,162 @@
/* $NetBSD: check.c,v 1.4 1997/10/10 08:59:44 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)check.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: check.c,v 1.4 1997/10/10 08:59:44 lukem Exp $");
#endif
#endif /* not lint */
#include "back.h"
void
getmove()
{
int i, c;
c = 0;
for (;;) {
i = checkmove(c);
switch (i) {
case -1:
if (movokay(mvlim)) {
if (tflag)
curmove(20, 0);
else
writec('\n');
for (i = 0; i < mvlim; i++)
if (h[i])
wrhit(g[i]);
nexturn();
if (*offopp == 15)
cturn *= -2;
if (tflag && pnum)
bflag = pnum;
return;
}
case -4:
case 0:
if (tflag)
refresh();
if (i != 0 && i != -4)
break;
if (tflag)
curmove(20, 0);
else
writec('\n');
writel(*Colorptr);
if (i == -4)
writel(" must make ");
else
writel(" can only make ");
writec(mvlim + '0');
writel(" move");
if (mvlim > 1)
writec('s');
writec('.');
writec('\n');
break;
case -3:
if (quit())
return;
}
if (!tflag)
proll();
else {
curmove(cturn == -1 ? 18 : 19, 39);
cline();
c = -1;
}
}
}
int
movokay(mv)
int mv;
{
int i, m;
if (d0)
swap;
for (i = 0; i < mv; i++) {
if (p[i] == g[i]) {
moverr(i);
curmove(20, 0);
writel("Attempt to move to same location.\n");
return (0);
}
if (cturn * (g[i] - p[i]) < 0) {
moverr(i);
curmove(20, 0);
writel("Backwards move.\n");
return (0);
}
if (abs(board[bar]) && p[i] != bar) {
moverr(i);
curmove(20, 0);
writel("Men still on bar.\n");
return (0);
}
if ((m = makmove(i))) {
moverr(i);
switch (m) {
case 1:
writel("Move not rolled.\n");
break;
case 2:
writel("Bad starting position.\n");
break;
case 3:
writel("Destination occupied.\n");
break;
case 4:
writel("Can't remove men yet.\n");
}
return (0);
}
}
return (1);
}

View File

@@ -0,0 +1,741 @@
/* $NetBSD: fancy.c,v 1.7 1998/09/13 15:19:35 hubertf 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)fancy.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: fancy.c,v 1.7 1998/09/13 15:19:35 hubertf Exp $");
#endif
#endif /* not lint */
#include "back.h"
char PC; /* padding character */
char *BC; /* backspace sequence */
char *CD; /* clear to end of screen sequence */
char *CE; /* clear to end of line sequence */
char *CL; /* clear screen sequence */
char *CM; /* cursor movement instructions */
char *HO; /* home cursor sequence */
char *MC; /* column cursor movement map */
char *ML; /* row cursor movement map */
char *ND; /* forward cursor sequence */
char *UP; /* up cursor sequence */
int lHO; /* length of HO */
int lBC; /* length of BC */
int lND; /* length of ND */
int lUP; /* length of UP */
int CO; /* number of columns */
int LI; /* number of lines */
int *linect; /* array of lengths of lines on screen (the
* actual screen is not stored) */
/* two letter codes */
char tcap[] = "bccdceclcmhomcmlndup";
/* corresponding strings */
char **tstr[] = {&BC, &CD, &CE, &CL, &CM, &HO, &MC, &ML, &ND, &UP};
extern int buffnum; /* pointer to output buffer */
char tbuf[1024]; /* buffer for decoded termcap entries */
int oldb[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int oldr;
int oldw;
/* "real" cursor positions, so it knows when to reposition. These are -1 if
* curr and curc are accurate */
int realr;
int realc;
void
fboard()
{
int i, j, l;
curmove(0, 0); /* do top line */
for (i = 0; i < 53; i++)
fancyc('_');
curmove(15, 0); /* do botttom line */
for (i = 0; i < 53; i++)
fancyc('_');
l = 1; /* do vertical lines */
for (i = 52; i > -1; i -= 28) {
curmove((l == 1 ? 1 : 15), i);
fancyc('|');
for (j = 0; j < 14; j++) {
curmove(curr + l, curc - 1);
fancyc('|');
}
if (i == 24)
i += 32;
l = -l; /* alternate directions */
}
curmove(2, 1); /* label positions 13-18 */
for (i = 13; i < 18; i++) {
fancyc('1');
fancyc((i % 10) + '0');
curmove(curr, curc + 2);
}
fancyc('1');
fancyc('8');
curmove(2, 29); /* label positions 19-24 */
fancyc('1');
fancyc('9');
for (i = 20; i < 25; i++) {
curmove(curr, curc + 2);
fancyc('2');
fancyc((i % 10) + '0');
}
curmove(14, 1); /* label positions 12-7 */
fancyc('1');
fancyc('2');
for (i = 11; i > 6; i--) {
curmove(curr, curc + 2);
fancyc(i > 9 ? '1' : ' ');
fancyc((i % 10) + '0');
}
curmove(14, 30); /* label positions 6-1 */
fancyc('6');
for (i = 5; i > 0; i--) {
curmove(curr, curc + 3);
fancyc(i + '0');
}
for (i = 12; i > 6; i--)/* print positions 12-7 */
if (board[i])
bsect(board[i], 13, 1 + 4 * (12 - i), -1);
if (board[0]) /* print red men on bar */
bsect(board[0], 13, 25, -1);
for (i = 6; i > 0; i--) /* print positions 6-1 */
if (board[i])
bsect(board[i], 13, 29 + 4 * (6 - i), -1);
l = (off[1] < 0 ? off[1] + 15 : off[1]); /* print white's home */
bsect(l, 3, 54, 1);
curmove(8, 25); /* print the word BAR */
fancyc('B');
fancyc('A');
fancyc('R');
for (i = 13; i < 19; i++) /* print positions 13-18 */
if (board[i])
bsect(board[i], 3, 1 + 4 * (i - 13), 1);
if (board[25]) /* print white's men on bar */
bsect(board[25], 3, 25, 1);
for (i = 19; i < 25; i++) /* print positions 19-24 */
if (board[i])
bsect(board[i], 3, 29 + 4 * (i - 19), 1);
l = (off[0] < 0 ? off[0] + 15 : off[0]); /* print red's home */
bsect(-l, 13, 54, -1);
for (i = 0; i < 26; i++)/* save board position for refresh later */
oldb[i] = board[i];
oldr = (off[1] < 0 ? off[1] + 15 : off[1]);
oldw = -(off[0] < 0 ? off[0] + 15 : off[0]);
}
/*
* bsect (b,rpos,cpos,cnext)
* Print the contents of a board position. "b" has the value of the
* position, "rpos" is the row to start printing, "cpos" is the column to
* start printing, and "cnext" is positive if the position starts at the top
* and negative if it starts at the bottom. The value of "cpos" is checked
* to see if the position is a player's home, since those are printed
* differently.
*/
void
bsect(b, rpos, cpos, cnext)
int b; /* contents of position */
int rpos; /* row of position */
int cpos; /* column of position */
int cnext; /* direction of position */
{
int j; /* index */
int n; /* number of men on position */
int bct; /* counter */
int k; /* index */
char pc; /* color of men on position */
bct = 0;
n = abs(b); /* initialize n and pc */
pc = (b > 0 ? 'r' : 'w');
if (n < 6 && cpos < 54) /* position cursor at start */
curmove(rpos, cpos + 1);
else
curmove(rpos, cpos);
for (j = 0; j < 5; j++) { /* print position row by row */
for (k = 0; k < 15; k += 5) /* print men */
if (n > j + k)
fancyc(pc);
if (j < 4) { /* figure how far to back up for next row */
if (n < 6) { /* stop if none left */
if (j + 1 == n)
break;
bct = 1; /* single column */
} else {
if (n < 11) { /* two columns */
if (cpos == 54) { /* home pos */
if (j + 5 >= n)
bct = 1;
else
bct = 2;
}
if (cpos < 54) { /* not home */
if (j + 6 >= n)
bct = 1;
else
bct = 2;
}
} else { /* three columns */
if (j + 10 >= n)
bct = 2;
else
bct = 3;
}
}
curmove(curr + cnext, curc - bct); /* reposition cursor */
}
}
}
void
refresh()
{
int i, r, c;
r = curr; /* save current position */
c = curc;
for (i = 12; i > 6; i--)/* fix positions 12-7 */
if (board[i] != oldb[i]) {
fixpos(oldb[i], board[i], 13, 1 + (12 - i) * 4, -1);
oldb[i] = board[i];
}
if (board[0] != oldb[0]) { /* fix red men on bar */
fixpos(oldb[0], board[0], 13, 25, -1);
oldb[0] = board[0];
}
for (i = 6; i > 0; i--) /* fix positions 6-1 */
if (board[i] != oldb[i]) {
fixpos(oldb[i], board[i], 13, 29 + (6 - i) * 4, -1);
oldb[i] = board[i];
}
i = -(off[0] < 0 ? off[0] + 15 : off[0]); /* fix white's home */
if (oldw != i) {
fixpos(oldw, i, 13, 54, -1);
oldw = i;
}
for (i = 13; i < 19; i++) /* fix positions 13-18 */
if (board[i] != oldb[i]) {
fixpos(oldb[i], board[i], 3, 1 + (i - 13) * 4, 1);
oldb[i] = board[i];
}
if (board[25] != oldb[25]) { /* fix white men on bar */
fixpos(oldb[25], board[25], 3, 25, 1);
oldb[25] = board[25];
}
for (i = 19; i < 25; i++) /* fix positions 19-24 */
if (board[i] != oldb[i]) {
fixpos(oldb[i], board[i], 3, 29 + (i - 19) * 4, 1);
oldb[i] = board[i];
}
i = (off[1] < 0 ? off[1] + 15 : off[1]); /* fix red's home */
if (oldr != i) {
fixpos(oldr, i, 3, 54, 1);
oldr = i;
}
curmove(r, c); /* return to saved position */
newpos();
buflush();
}
void
fixpos(old, new, r, c, inc)
int old, new, r, c, inc;
{
int o, n, nv;
int ov, nc;
char col;
nc = 0;
if (old * new >= 0) {
ov = abs(old);
nv = abs(new);
col = (old + new > 0 ? 'r' : 'w');
o = (ov - 1) / 5;
n = (nv - 1) / 5;
if (o == n) {
if (o == 2)
nc = c + 2;
if (o == 1)
nc = c < 54 ? c : c + 1;
if (o == 0)
nc = c < 54 ? c + 1 : c;
if (ov > nv)
fixcol(r + inc * (nv - n * 5), nc, abs(ov - nv), ' ', inc);
else
fixcol(r + inc * (ov - o * 5), nc, abs(ov - nv), col, inc);
return;
} else {
if (c < 54) {
if (o + n == 1) {
if (n) {
fixcol(r, c, abs(nv - 5), col, inc);
if (ov != 5)
fixcol(r + inc * ov, c + 1,
abs(ov - 5), col, inc);
} else {
fixcol(r, c, abs(ov - 5), ' ', inc);
if (nv != 5)
fixcol(r + inc * nv, c + 1,
abs(nv - 5), ' ', inc);
}
return;
}
if (n == 2) {
if (ov != 10)
fixcol(r + inc * (ov - 5), c,
abs(ov - 10), col, inc);
fixcol(r, c + 2, abs(nv - 10), col, inc);
} else {
if (nv != 10)
fixcol(r + inc * (nv - 5), c,
abs(nv - 10), ' ', inc);
fixcol(r, c + 2, abs(ov - 10), ' ', inc);
}
return;
}
if (n > o) {
fixcol(r + inc * (ov % 5), c + o, abs(5 * n - ov), col, inc);
if (nv != 5 * n)
fixcol(r, c + n, abs(5 * n - nv), col, inc);
} else {
fixcol(r + inc * (nv % 5), c + n, abs(5 * n - nv), ' ', inc);
if (ov != 5 * o)
fixcol(r, c + o, abs(5 * o - ov), ' ', inc);
}
return;
}
}
nv = abs(new);
fixcol(r, c + 1, nv, new > 0 ? 'r' : 'w', inc);
if (abs(old) <= abs(new))
return;
fixcol(r + inc * new, c + 1, abs(old + new), ' ', inc);
}
void
fixcol(r, c, l, ch, inc)
int l, ch, r, c, inc;
{
int i;
curmove(r, c);
fancyc(ch);
for (i = 1; i < l; i++) {
curmove(curr + inc, curc - 1);
fancyc(ch);
}
}
void
curmove(r, c)
int r, c;
{
if (curr == r && curc == c)
return;
if (realr == -1) {
realr = curr;
realc = curc;
}
curr = r;
curc = c;
}
void
newpos()
{
int r; /* destination row */
int c; /* destination column */
int mode = -1; /* mode of movement */
int count = 1000; /* character count */
int i; /* index */
int n; /* temporary variable */
char *m; /* string containing CM movement */
m = NULL;
if (realr == -1) /* see if already there */
return;
r = curr; /* set current and dest. positions */
c = curc;
curr = realr;
curc = realc;
/* double check position */
if (curr == r && curc == c) {
realr = realc = -1;
return;
}
if (CM) { /* try CM to get there */
mode = 0;
m = (char *) tgoto(CM, c, r);
count = strlen(m);
}
/* try HO and local movement */
if (HO && (n = r + c * lND + lHO) < count) {
mode = 1;
count = n;
}
/* try various LF combinations */
if (r >= curr) {
/* CR, LF, and ND */
if ((n = (r - curr) + c * lND + 1) < count) {
mode = 2;
count = n;
}
/* LF, ND */
if (c >= curc && (n = (r - curr) + (c - curc) * lND) < count) {
mode = 3;
count = n;
}
/* LF, BS */
if (c < curc && (n = (r - curr) + (curc - c) * lBC) < count) {
mode = 4;
count = n;
}
}
/* try corresponding UP combinations */
if (r < curr) {
/* CR, UP, and ND */
if ((n = (curr - r) * lUP + c * lND + 1) < count) {
mode = 5;
count = n;
}
/* UP and ND */
if (c >= curc && (n = (curr - r) * lUP + (c - curc) * lND) < count) {
mode = 6;
count = n;
}
/* UP and BS */
if (c < curc && (n = (curr - r) * lUP + (curc - c) * lBC) < count) {
mode = 7;
count = n;
}
}
/* space over */
if (curr == r && c > curc && linect[r] < curc && c - curc < count)
mode = 8;
switch (mode) {
case -1: /* error! */
write(2, "\r\nInternal cursor error.\r\n", 26);
getout(0);
/* direct cursor motion */
case 0:
tputs(m, abs(curr - r), addbuf);
break;
/* relative to "home" */
case 1:
tputs(HO, r, addbuf);
for (i = 0; i < r; i++)
addbuf('\012');
for (i = 0; i < c; i++)
tputs(ND, 1, addbuf);
break;
/* CR and down and over */
case 2:
addbuf('\015');
for (i = 0; i < r - curr; i++)
addbuf('\012');
for (i = 0; i < c; i++)
tputs(ND, 1, addbuf);
break;
/* down and over */
case 3:
for (i = 0; i < r - curr; i++)
addbuf('\012');
for (i = 0; i < c - curc; i++)
tputs(ND, 1, addbuf);
break;
/* down and back */
case 4:
for (i = 0; i < r - curr; i++)
addbuf('\012');
for (i = 0; i < curc - c; i++)
addbuf('\010');
break;
/* CR and up and over */
case 5:
addbuf('\015');
for (i = 0; i < curr - r; i++)
tputs(UP, 1, addbuf);
for (i = 0; i < c; i++)
tputs(ND, 1, addbuf);
break;
/* up and over */
case 6:
for (i = 0; i < curr - r; i++)
tputs(UP, 1, addbuf);
for (i = 0; i < c - curc; i++)
tputs(ND, 1, addbuf);
break;
/* up and back */
case 7:
for (i = 0; i < curr - r; i++)
tputs(UP, 1, addbuf);
for (i = 0; i < curc - c; i++) {
if (BC)
tputs(BC, 1, addbuf);
else
addbuf('\010');
}
break;
/* safe space */
case 8:
for (i = 0; i < c - curc; i++)
addbuf(' ');
}
/* fix positions */
curr = r;
curc = c;
realr = -1;
realc = -1;
}
void
clear()
{
int i;
/* double space if can't clear */
if (CL == 0) {
writel("\n\n");
return;
}
curr = curc = 0; /* fix position markers */
realr = realc = -1;
for (i = 0; i < 24; i++)/* clear line counts */
linect[i] = -1;
buffnum = -1; /* ignore leftover buffer contents */
tputs(CL, CO, addbuf); /* put CL in buffer */
}
void
fancyc(c)
char c; /* character to output */
{
int sp; /* counts spaces in a tab */
if (c == '\007') { /* bells go in blindly */
addbuf(c);
return;
}
/* process tabs, use spaces if the the tab should be erasing things,
* otherwise use cursor movement routines. Note this does not use
* hardware tabs at all. */
if (c == '\t') {
sp = (curc + 8) & (~7); /* compute spaces */
/* check line length */
if (linect[curr] >= curc || sp < 4) {
for (; sp > curc; sp--)
addbuf(' ');
curc = sp; /* fix curc */
} else
curmove(curr, sp);
return;
}
/* do newline be calling newline */
if (c == '\n') {
newline();
return;
}
/* ignore any other control chars */
if (c < ' ')
return;
/* if an erasing space or non-space, just add it to buffer. Otherwise
* use cursor movement routine, so that multiple spaces will be
* grouped together */
if (c > ' ' || linect[curr] >= curc) {
newpos(); /* make sure position correct */
addbuf(c); /* add character to buffer */
/* fix line length */
if (c == ' ' && linect[curr] == curc)
linect[curr]--;
else
if (linect[curr] < curc)
linect[curr] = curc;
curc++; /* fix curc */
} else
/* use cursor movement routine */
curmove(curr, curc + 1);
}
void
clend()
{
int i;
if (CD) {
tputs(CD, CO - curr, addbuf);
for (i = curr; i < LI; i++)
linect[i] = -1;
return;
}
curmove(i = curr, 0);
cline();
while (curr < LI - 1) {
curmove(curr + 1, 0);
if (linect[curr] > -1)
cline();
}
curmove(i, 0);
}
void
cline()
{
int c;
if (curc > linect[curr])
return;
newpos();
if (CE) {
tputs(CE, 1, addbuf);
linect[curr] = curc - 1;
} else {
c = curc - 1;
while (linect[curr] > c) {
addbuf(' ');
curc++;
linect[curr]--;
}
curmove(curr, c + 1);
}
}
void
newline()
{
cline();
if (curr == LI - 1)
curmove(begscr, 0);
else
curmove(curr + 1, 0);
}
int
getcaps(s)
const char *s;
{
char *code; /* two letter code */
char ***cap; /* pointer to cap string */
char *bufp; /* pointer to cap buffer */
char tentry[1024]; /* temporary uncoded caps buffer */
tgetent(tentry, s); /* get uncoded termcap entry */
LI = tgetnum("li"); /* get number of lines */
if (LI == -1)
LI = 12;
CO = tgetnum("co"); /* get number of columns */
if (CO == -1)
CO = 65;
bufp = tbuf; /* get padding character */
tgetstr("pc", &bufp);
if (bufp != tbuf)
PC = *tbuf;
else
PC = 0;
bufp = tbuf; /* get string entries */
cap = tstr;
for (code = tcap; *code; code += 2)
**cap++ = (char *) tgetstr(code, &bufp);
/* get pertinent lengths */
if (HO)
lHO = strlen(HO);
if (BC)
lBC = strlen(BC);
else
lBC = 1;
if (UP)
lUP = strlen(UP);
if (ND)
lND = strlen(ND);
if (LI < 24 || CO < 72 || !(CL && UP && ND))
return (0);
linect = (int *) calloc(LI + 1, sizeof(int));
if (linect == NULL) {
write(2, "\r\nOut of memory!\r\n", 18);
getout(0);
}
return (1);
}

View File

@@ -0,0 +1,104 @@
/* $NetBSD: init.c,v 1.6 1997/10/14 00:53:31 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: init.c,v 1.6 1997/10/14 00:53:31 lukem Exp $");
#endif
#endif /* not lint */
#include <termios.h>
/*
* variable initialization.
*/
/* name of executable object programs */
const char EXEC[] = EXEC_PATH;
const char TEACH[] = TEACH_PATH;
int pnum = 2; /* color of player: -1 = white 1 = red 0 =
* both 2 = not yet init'ed */
int acnt = 1; /* length of args */
char args[100] = "-";
int aflag = 1; /* flag to ask for rules or instructions */
int bflag = 0; /* flag for automatic board printing */
int cflag = 0; /* case conversion flag */
int hflag = 1; /* flag for cleaning screen */
int mflag = 0; /* backgammon flag */
int raflag = 0; /* 'roll again' flag for recovered game */
int rflag = 0; /* recovered game flag */
int tflag = 0; /* cursor addressing flag */
int iroll = 0; /* special flag for inputting rolls */
int rfl = 0;
const char *const color[] = {"White", "Red", "white", "red"};
const char *const *Colorptr;
const char *const *colorptr;
int *inopp;
int *inptr;
int *offopp;
int *offptr;
char args[100];
int bar;
int begscr;
int board[26];
char cin[100];
int colen;
int cturn;
int curc;
int curr;
int d0;
int dice[2];
int dlast;
int g[5];
int gvalue;
int h[4];
int home;
int in[2];
int mvl;
int mvlim;
int ncin;
int off[2];
int p[5];
int rscore;
int table[6][6];
int wscore;
struct termios old, noech, bg_raw;

View File

@@ -0,0 +1,122 @@
/* $NetBSD: odds.c,v 1.4 1997/10/10 08:59:46 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)odds.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: odds.c,v 1.4 1997/10/10 08:59:46 lukem Exp $");
#endif
#endif /* not lint */
#include "back.h"
void
odds(r1, r2, val)
int r1, r2, val;
{
int i, j;
if (r1 == 0) {
for (i = 0; i < 6; i++)
for (j = 0; j < 6; j++)
table[i][j] = 0;
return;
} else {
r1--;
if (r2-- == 0) {
for (i = 0; i < 6; i++) {
table[i][r1] += val;
table[r1][i] += val;
}
} else {
table[r2][r1] += val;
table[r1][r2] += val;
}
}
}
int
count()
{
int i;
int j;
int total;
total = 0;
for (i = 0; i < 6; i++)
for (j = 0; j < 6; j++)
total += table[i][j];
return (total);
}
int
canhit(i, c)
int i, c;
{
int j, k, b;
int a, diff, place, addon, menstuck;
if (c == 0)
odds(0, 0, 0);
if (board[i] > 0) {
a = -1;
b = 25;
} else {
a = 1;
b = 0;
}
place = abs(25 - b - i);
menstuck = abs(board[b]);
for (j = b; j != i; j += a) {
if (board[j] * a > 0) {
diff = abs(j - i);
addon = place + ((board[j] * a > 2 || j == b) ? 5 : 0);
if ((j == b && menstuck == 1) &&
(j != b && menstuck == 0))
for (k = 1; k < diff; k++)
if (k < 7 && diff - k < 7 &&
(board[i + a * k] * a >= 0 ||
board[i + a * (diff - k)] >= 0))
odds(k, diff - k, addon);
if ((j == b || menstuck < 2) && diff < 7)
odds(diff, 0, addon);
}
if (j == b && menstuck > 1)
break;
}
return (count());
}

View File

@@ -0,0 +1,179 @@
/* $NetBSD: one.c,v 1.4 1997/10/10 08:59:47 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)one.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: one.c,v 1.4 1997/10/10 08:59:47 lukem Exp $");
#endif
#endif /* not lint */
#include "back.h"
int
makmove(i)
int i;
{
int n, d;
int max;
d = d0;
n = abs(g[i] - p[i]);
max = (*offptr < 0 ? 7 : last());
if (board[p[i]] * cturn <= 0)
return (checkd(d) + 2);
if (g[i] != home && board[g[i]] * cturn < -1)
return (checkd(d) + 3);
if (i || D0 == D1) {
if (n == max ? D1 < n : D1 != n)
return (checkd(d) + 1);
} else {
if (n == max ? D0 < n && D1 < n : D0 != n && D1 != n)
return (checkd(d) + 1);
if (n == max ? D0 < n : D0 != n) {
if (d0)
return (checkd(d) + 1);
swap;
}
}
if (g[i] == home && *offptr < 0)
return (checkd(d) + 4);
h[i] = 0;
board[p[i]] -= cturn;
if (g[i] != home) {
if (board[g[i]] == -cturn) {
board[home] -= cturn;
board[g[i]] = 0;
h[i] = 1;
if (abs(bar - g[i]) < 7) {
(*inopp)--;
if (*offopp >= 0)
*offopp -= 15;
}
}
board[g[i]] += cturn;
if (abs(home - g[i]) < 7 && abs(home - p[i]) > 6) {
(*inptr)++;
if (*inptr + *offptr == 0)
*offptr += 15;
}
} else {
(*offptr)++;
(*inptr)--;
}
return (0);
}
void
moverr(i)
int i;
{
int j;
if (tflag)
curmove(20, 0);
else
writec('\n');
writel("Error: ");
for (j = 0; j <= i; j++) {
wrint(p[j]);
writec('-');
wrint(g[j]);
if (j < i)
writec(',');
}
writel("... ");
movback(i);
}
int
checkd(d)
int d;
{
if (d0 != d)
swap;
return (0);
}
int
last()
{
int i;
for (i = home - 6 * cturn; i != home; i += cturn)
if (board[i] * cturn > 0)
return (abs(home - i));
return (-1);
}
void
movback(i)
int i;
{
int j;
for (j = i - 1; j >= 0; j--)
backone(j);
}
void
backone(i)
int i;
{
board[p[i]] += cturn;
if (g[i] != home) {
board[g[i]] -= cturn;
if (abs(g[i] - home) < 7 && abs(p[i] - home) > 6) {
(*inptr)--;
if (*inptr + *offptr < 15 && *offptr >= 0)
*offptr -= 15;
}
} else {
(*offptr)--;
(*inptr)++;
}
if (h[i]) {
board[home] += cturn;
board[g[i]] = -cturn;
if (abs(bar - g[i]) < 7) {
(*inopp)++;
if (*inopp + *offopp == 0)
*offopp += 15;
}
}
}

View File

@@ -0,0 +1,186 @@
/* $NetBSD: save.c,v 1.7 1998/09/13 15:41:34 hubertf 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)save.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: save.c,v 1.7 1998/09/13 15:41:34 hubertf Exp $");
#endif
#endif /* not lint */
#include <errno.h>
#include "back.h"
static const char confirm[] = "Are you sure you want to leave now?";
static const char prompt[] = "Enter a file name: ";
static const char exist1[] = "The file '";
static const char exist2[] =
"' already exists.\nAre you sure you want to use this file?";
static const char cantuse[] = "\nCan't use ";
static const char saved[] = "This game has been saved on the file '";
static const char type[] = "'.\nType \"backgammon ";
static const char rec[] = "\" to recover your game.\n\n";
static const char cantrec[] = "Can't recover file: ";
void
save(n)
int n;
{
int fdesc;
char *fs;
char fname[50];
if (n) {
if (tflag) {
curmove(20, 0);
clend();
} else
writec('\n');
writel(confirm);
if (!yorn(0))
return;
}
cflag = 1;
for (;;) {
writel(prompt);
fs = fname;
while ((*fs = readc()) != '\n') {
if (*fs == old.c_cc[VERASE]) {
if (fs > fname) {
fs--;
if (tflag)
curmove(curr, curc - 1);
else
writec(*fs);
} else
writec('\007');
continue;
}
writec(*fs++);
}
*fs = '\0';
if ((fdesc = open(fname, O_RDWR)) == -1 && errno == ENOENT) {
if ((fdesc = creat(fname, 0600)) != -1)
break;
}
if (fdesc != -1) {
if (tflag) {
curmove(18, 0);
clend();
} else
writec('\n');
writel(exist1);
writel(fname);
writel(exist2);
cflag = 0;
close(fdesc);
if (yorn(0)) {
unlink(fname);
fdesc = creat(fname, 0700);
break;
} else {
cflag = 1;
continue;
}
}
writel(cantuse);
writel(fname);
writel(".\n");
close(fdesc);
cflag = 1;
}
write(fdesc, board, sizeof board);
write(fdesc, off, sizeof off);
write(fdesc, in, sizeof in);
write(fdesc, dice, sizeof dice);
write(fdesc, &cturn, sizeof cturn);
write(fdesc, &dlast, sizeof dlast);
write(fdesc, &pnum, sizeof pnum);
write(fdesc, &rscore, sizeof rscore);
write(fdesc, &wscore, sizeof wscore);
write(fdesc, &gvalue, sizeof gvalue);
write(fdesc, &raflag, sizeof raflag);
close(fdesc);
if (tflag)
curmove(18, 0);
writel(saved);
writel(fname);
writel(type);
writel(fname);
writel(rec);
if (tflag)
clend();
getout(0);
}
void
recover(s)
const char *s;
{
int fdesc;
if ((fdesc = open(s, O_RDONLY)) == -1)
norec(s);
read(fdesc, board, sizeof board);
read(fdesc, off, sizeof off);
read(fdesc, in, sizeof in);
read(fdesc, dice, sizeof dice);
read(fdesc, &cturn, sizeof cturn);
read(fdesc, &dlast, sizeof dlast);
read(fdesc, &pnum, sizeof pnum);
read(fdesc, &rscore, sizeof rscore);
read(fdesc, &wscore, sizeof wscore);
read(fdesc, &gvalue, sizeof gvalue);
read(fdesc, &raflag, sizeof raflag);
close(fdesc);
rflag = 1;
}
void
norec(s)
const char *s;
{
const char *c;
tflag = 0;
writel(cantrec);
c = s;
while (*c != '\0')
writec(*c++);
getout(0);
}

View File

@@ -0,0 +1,511 @@
/* $NetBSD: subs.c,v 1.8 1998/09/13 15:19:35 hubertf 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)subs.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: subs.c,v 1.8 1998/09/13 15:19:35 hubertf Exp $");
#endif
#endif /* not lint */
#include "back.h"
int buffnum = -1;
char outbuff[BUFSIZ];
static const char plred[] = "Player is red, computer is white.";
static const char plwhite[] = "Player is white, computer is red.";
static const char nocomp[] = "(No computer play.)";
const char *const descr[] = {
"Usage: backgammon [-] [n r w b pr pw pb t3a]\n",
"\t-\tgets this list\n\tn\tdon't ask for rules or instructions",
"\tr\tplayer is red (implies n)\n\tw\tplayer is white (implies n)",
"\tb\ttwo players, red and white (implies n)",
"\tpr\tprint the board before red's turn",
"\tpw\tprint the board before white's turn",
"\tpb\tprint the board before both player's turn",
"\tterm\tterminal is a term",
"\tsfile\trecover saved game from file",
0
};
void
errexit(s)
const char *s;
{
write(2, "\n", 1);
perror(s);
getout(0);
}
int
addbuf(c)
int c;
{
buffnum++;
if (buffnum == BUFSIZ) {
if (write(1, outbuff, BUFSIZ) != BUFSIZ)
errexit("addbuf (write):");
buffnum = 0;
}
outbuff[buffnum] = c;
return 0;
}
void
buflush()
{
if (buffnum < 0)
return;
buffnum++;
if (write(1, outbuff, buffnum) != buffnum)
errexit("buflush (write):");
buffnum = -1;
}
int
readc()
{
char c;
if (tflag) {
cline();
newpos();
}
buflush();
if (read(0, &c, 1) != 1)
errexit("readc");
#ifdef WHY_IS_THIS_HARDWIRED_IN_HERE
if (c == '\177')
getout(0);
#endif
if (c == '\033' || c == '\015')
return ('\n');
if (cflag)
return (c);
if (c == '\014')
return ('R');
if (c >= 'a' && c <= 'z')
return (c & 0137);
return (c);
}
void
writec(c)
char c;
{
if (tflag)
fancyc(c);
else
addbuf(c);
}
void
writel(l)
const char *l;
{
#ifdef DEBUG
const char *s;
if (trace == NULL)
trace = fopen("bgtrace", "w");
fprintf(trace, "writel: \"");
for (s = l; *s; s++) {
if (*s < ' ' || *s == '\177')
fprintf(trace, "^%c", (*s) ^ 0100);
else
putc(*s, trace);
}
fprintf(trace, "\"\n");
fflush(trace);
#endif
while (*l)
writec(*l++);
}
void
proll()
{
if (d0)
swap;
if (cturn == 1)
writel("Red's roll: ");
else
writel("White's roll: ");
writec(D0 + '0');
writec('\040');
writec(D1 + '0');
if (tflag)
cline();
}
void
wrint(n)
int n;
{
int i, j, t;
for (i = 4; i > 0; i--) {
t = 1;
for (j = 0; j < i; j++)
t *= 10;
if (n > t - 1)
writec((n / t) % 10 + '0');
}
writec(n % 10 + '0');
}
void
gwrite()
{
int r, c;
r = c = 0;
if (tflag) {
r = curr;
c = curc;
curmove(16, 0);
}
if (gvalue > 1) {
writel("Game value: ");
wrint(gvalue);
writel(". ");
if (dlast == -1)
writel(color[0]);
else
writel(color[1]);
writel(" doubled last.");
} else {
switch (pnum) {
case -1: /* player is red */
writel(plred);
break;
case 0: /* player is both colors */
writel(nocomp);
break;
case 1: /* player is white */
writel(plwhite);
}
}
if (rscore || wscore) {
writel(" ");
wrscore();
}
if (tflag) {
cline();
curmove(r, c);
}
}
int
quit()
{
if (tflag) {
curmove(20, 0);
clend();
} else
writec('\n');
writel("Are you sure you want to quit?");
if (yorn(0)) {
if (rfl) {
writel("Would you like to save this game?");
if (yorn(0))
save(0);
}
cturn = 0;
return (1);
}
return (0);
}
int
yorn(special)
char special; /* special response */
{
char c;
int i;
i = 1;
while ((c = readc()) != 'Y' && c != 'N') {
if (special && c == special)
return (2);
if (i) {
if (special) {
writel(" (Y, N, or ");
writec(special);
writec(')');
} else
writel(" (Y or N)");
i = 0;
} else
writec('\007');
}
if (c == 'Y')
writel(" Yes.\n");
else
writel(" No.\n");
if (tflag)
buflush();
return (c == 'Y');
}
void
wrhit(i)
int i;
{
writel("Blot hit on ");
wrint(i);
writec('.');
writec('\n');
}
void
nexturn()
{
int c;
cturn = -cturn;
c = cturn / abs(cturn);
home = bar;
bar = 25 - bar;
offptr += c;
offopp -= c;
inptr += c;
inopp -= c;
Colorptr += c;
colorptr += c;
}
void
getarg(arg)
char ***arg;
{
char **s;
/* process arguments here. dashes are ignored, nbrw are ignored if
* the game is being recovered */
s = *arg;
while (s[0] != NULL && s[0][0] == '-') {
switch (s[0][1]) {
/* don't ask if rules or instructions needed */
case 'n':
if (rflag)
break;
aflag = 0;
args[acnt++] = 'n';
break;
/* player is both red and white */
case 'b':
if (rflag)
break;
pnum = 0;
aflag = 0;
args[acnt++] = 'b';
break;
/* player is red */
case 'r':
if (rflag)
break;
pnum = -1;
aflag = 0;
args[acnt++] = 'r';
break;
/* player is white */
case 'w':
if (rflag)
break;
pnum = 1;
aflag = 0;
args[acnt++] = 'w';
break;
/* print board after move according to following
* character */
case 'p':
if (s[0][2] != 'r' && s[0][2] != 'w' && s[0][2] != 'b')
break;
args[acnt++] = 'p';
args[acnt++] = s[0][2];
if (s[0][2] == 'r')
bflag = 1;
if (s[0][2] == 'w')
bflag = -1;
if (s[0][2] == 'b')
bflag = 0;
break;
case 't':
if (s[0][2] == '\0') { /* get terminal caps */
s++;
tflag = getcaps(*s);
} else
tflag = getcaps(&s[0][2]);
break;
case 's':
s++;
/* recover file */
if (s[0] == NULL) {
writel("No save file named\n");
getout(0);
} else
recover(s[0]);
break;
}
s++;
}
if (s[0] != 0)
recover(s[0]);
}
void
init()
{
int i;
for (i = 0; i < 26;)
board[i++] = 0;
board[1] = 2;
board[6] = board[13] = -5;
board[8] = -3;
board[12] = board[19] = 5;
board[17] = 3;
board[24] = -2;
off[0] = off[1] = -15;
in[0] = in[1] = 5;
gvalue = 1;
dlast = 0;
}
void
wrscore()
{
writel("Score: ");
writel(color[1]);
writec(' ');
wrint(rscore);
writel(", ");
writel(color[0]);
writec(' ');
wrint(wscore);
}
void
fixtty(t)
struct termios *t;
{
if (tflag)
newpos();
buflush();
if (tcsetattr(0, TCSADRAIN, t) < 0)
errexit("fixtty");
}
void
getout(dummy)
int dummy __attribute__((unused));
{
/* go to bottom of screen */
if (tflag) {
curmove(23, 0);
cline();
} else
writec('\n');
/* fix terminal status */
fixtty(&old);
exit(0);
}
void
roll()
{
char c;
int row;
int col;
row = col = 0;
if (iroll) {
if (tflag) {
row = curr;
col = curc;
curmove(17, 0);
} else
writec('\n');
writel("ROLL: ");
c = readc();
if (c != '\n') {
while (c < '1' || c > '6')
c = readc();
D0 = c - '0';
writec(' ');
writec(c);
c = readc();
while (c < '1' || c > '6')
c = readc();
D1 = c - '0';
writec(' ');
writec(c);
if (tflag) {
curmove(17, 0);
cline();
curmove(row, col);
} else
writec('\n');
return;
}
if (tflag) {
curmove(17, 0);
cline();
curmove(row, col);
} else
writec('\n');
}
D0 = rnum(6) + 1;
D1 = rnum(6) + 1;
d0 = 0;
}

View File

@@ -0,0 +1,310 @@
/* $NetBSD: table.c,v 1.5 1997/10/10 08:59:49 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)table.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: table.c,v 1.5 1997/10/10 08:59:49 lukem Exp $");
#endif
#endif /* not lint */
#include "back.h"
const char *const help2[] = {
" Enter moves as <s>-<f> or <s>/<r> where <s> is the starting",
"position, <f> is the finishing position, and <r> is the roll.",
"Remember, each die roll must be moved separately.",
0
};
struct state {
char ch;
int fcode;
int newst;
};
static const struct state atmata[] = {
{'R', 1, 0}, {'?', 7, 0}, {'Q', 0, -3}, {'B', 8, 25},
{'9', 2, 25}, {'8', 2, 25}, {'7', 2, 25}, {'6', 2, 25},
{'5', 2, 25}, {'4', 2, 25}, {'3', 2, 25}, {'2', 2, 19},
{'1', 2, 15}, {'0', 2, 25}, {'.', 0, 0}, {'9', 2, 25},
{'8', 2, 25}, {'7', 2, 25}, {'6', 2, 25}, {'5', 2, 25},
{'4', 2, 25}, {'3', 2, 25}, {'2', 2, 25}, {'1', 2, 25},
{'0', 2, 25}, {'/', 0, 32}, {'-', 0, 39}, {'.', 0, 0},
{'/', 5, 32}, {' ', 6, 3}, {',', 6, 3}, {'\n', 0, -1},
{'6', 3, 28}, {'5', 3, 28}, {'4', 3, 28}, {'3', 3, 28},
{'2', 3, 28}, {'1', 3, 28}, {'.', 0, 0}, {'H', 9, 61},
{'9', 4, 61}, {'8', 4, 61}, {'7', 4, 61}, {'6', 4, 61},
{'5', 4, 61}, {'4', 4, 61}, {'3', 4, 61}, {'2', 4, 53},
{'1', 4, 51}, {'0', 4, 61}, {'.', 0, 0}, {'9', 4, 61},
{'8', 4, 61}, {'7', 4, 61}, {'6', 4, 61}, {'5', 4, 61},
{'4', 4, 61}, {'3', 4, 61}, {'2', 4, 61}, {'1', 4, 61},
{'0', 4, 61}, {' ', 6, 3}, {',', 6, 3}, {'-', 5, 39},
{'\n', 0, -1}, {'.', 0, 0}
};
int
checkmove(ist)
int ist;
{
int j, n;
char c;
domove:
if (ist == 0) {
if (tflag)
curmove(curr, 32);
else
writel("\t\t");
writel("Move: ");
}
ist = mvl = ncin = 0;
for (j = 0; j < 5; j++)
p[j] = g[j] = -1;
dochar:
c = readc();
if (c == 'S') {
raflag = 0;
save(1);
if (tflag) {
curmove(cturn == -1 ? 18 : 19, 39);
ist = -1;
goto domove;
} else {
proll();
ist = 0;
goto domove;
}
}
if (c == old.c_cc[VERASE] && ncin > 0) {
if (tflag)
curmove(curr, curc - 1);
else {
if (old.c_cc[VERASE] == '\010')
writel("\010 \010");
else
writec(cin[ncin - 1]);
}
ncin--;
n = rsetbrd();
if (n == 0) {
n = -1;
if (tflag)
refresh();
}
if ((ist = n) > 0)
goto dochar;
goto domove;
}
if (c == old.c_cc[VKILL] && ncin > 0) {
if (tflag) {
refresh();
curmove(curr, 39);
ist = -1;
goto domove;
} else
if (old.c_cc[VERASE] == '\010') {
for (j = 0; j < ncin; j++)
writel("\010 \010");
ist = -1;
goto domove;
} else {
writec('\\');
writec('\n');
proll();
ist = 0;
goto domove;
}
}
n = dotable(c, ist);
if (n >= 0) {
cin[ncin++] = c;
if (n > 2)
if ((!tflag) || c != '\n')
writec(c);
ist = n;
if (n)
goto dochar;
else
goto domove;
}
if (n == -1 && mvl >= mvlim)
return (0);
if (n == -1 && mvl < mvlim - 1)
return (-4);
if (n == -6) {
if (!tflag) {
if (movokay(mvl + 1)) {
wrboard();
movback(mvl + 1);
}
proll();
writel("\t\tMove: ");
for (j = 0; j < ncin;)
writec(cin[j++]);
} else {
if (movokay(mvl + 1)) {
refresh();
movback(mvl + 1);
} else
curmove(cturn == -1 ? 18 : 19, ncin + 39);
}
ist = n = rsetbrd();
goto dochar;
}
if (n != -5)
return (n);
writec('\007');
goto dochar;
}
int
dotable(c, i)
char c;
int i;
{
int a;
int test;
test = (c == 'R');
while ((a = atmata[i].ch) != '.') {
if (a == c || (test && a == '\n')) {
switch (atmata[i].fcode) {
case 1:
wrboard();
if (tflag) {
curmove(cturn == -1 ? 18 : 19, 0);
proll();
writel("\t\t");
} else
proll();
break;
case 2:
if (p[mvl] == -1)
p[mvl] = c - '0';
else
p[mvl] = p[mvl] * 10 + c - '0';
break;
case 3:
if (g[mvl] != -1) {
if (mvl < mvlim)
mvl++;
p[mvl] = p[mvl - 1];
}
g[mvl] = p[mvl] + cturn * (c - '0');
if (g[mvl] < 0)
g[mvl] = 0;
if (g[mvl] > 25)
g[mvl] = 25;
break;
case 4:
if (g[mvl] == -1)
g[mvl] = c - '0';
else
g[mvl] = g[mvl] * 10 + c - '0';
break;
case 5:
if (mvl < mvlim)
mvl++;
p[mvl] = g[mvl - 1];
break;
case 6:
if (mvl < mvlim)
mvl++;
break;
case 7:
if (tflag)
curmove(20, 0);
else
writec('\n');
(void) text(help2);
if (tflag) {
curmove(cturn == -1 ? 18 : 19, 39);
} else {
writec('\n');
proll();
writel("\t\tMove: ");
}
break;
case 8:
p[mvl] = bar;
break;
case 9:
g[mvl] = home;
}
if (!test || a != '\n')
return (atmata[i].newst);
else
return (-6);
}
i++;
}
return (-5);
}
int
rsetbrd()
{
int i, j, n;
n = 0;
mvl = 0;
for (i = 0; i < 4; i++)
p[i] = g[i] = -1;
for (j = 0; j < ncin; j++)
n = dotable(cin[j], n);
return (n);
}

View File

@@ -0,0 +1,8 @@
# $NetBSD: Makefile,v 1.8 1997/10/10 08:59:50 lukem Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= teachgammon
SRCS= data.c teach.c ttext1.c ttext2.c tutor.c
NOMAN= noman
.include <bsd.prog.mk>

View File

@@ -0,0 +1,12 @@
# Makefrag - makefile fragment for backgammon/teachgammon
backgammon_teachgammon_DEFS := -DV7
backgammon_teachgammon_DIRS := $(GAMESDIR) $(MAN6DIR)
backgammon_teachgammon_INCS := -Ibackgammon/common_source
backgammon_teachgammon_all: backgammon/teachgammon/teachgammon
backgammon_teachgammon_install: backgammon_teachgammon_all
$(INSTALL_BINARY) backgammon/teachgammon/teachgammon $(INSTALL_PREFIX)$(GAMESDIR)/teachgammon
$(HIDE_GAME) teachgammon
$(INSTALL_MANUAL) backgammon.6 teachgammon.6

View File

@@ -0,0 +1,346 @@
/* $NetBSD: data.c,v 1.4 1997/10/10 08:59:51 lukem 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)data.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: data.c,v 1.4 1997/10/10 08:59:51 lukem Exp $");
#endif
#endif /* not lint */
#include "tutor.h"
int maxmoves = 23;
const char *const text0[] = {
"To start the game, I roll a 3, and you roll a 1. This means",
"that I get to start first. I move 8-5,6-5 since this makes a",
"new point and helps to trap your back men on 1. You should be",
"able to do a similar move with your roll.",
0
};
const char *const text1[] = {
"Now you shall see a move using doubles. I just rolled double",
"5's. I will move two men from position 13 to position 3. The",
"notation for this is 13-8,13-8,8-3,8-3. You will also roll dou-",
"bles, but you will be able to make a much stronger move.",
0
};
const char *const text2[] = {
"Excellent! As you can see, you are beginning to develop a wall",
"which is trapping my men on position 24. Also, moving your back",
"men forward not only improves your board position safely, but it",
"thwarts my effort to make a wall.",
"",
"My roll now is 5 6. Normally, I would use that roll to move from",
"position 24 to position 13 (24-18-13), but your new point prevents",
"that. Instead, I am forced to move from 13 to 2, where my man is",
"open but cannot be hit.",
0
};
const char *const text3[] = {
"As you can see, although you left a man open, it is a rela-",
"tively safe move to an advantageous position, which might help",
"you make a point later. Only two rolls (4 5 or 5 4) will allow",
"me to hit you. With an unprecedented amount of luck, I happen",
"to roll a 4 5 and hit you as just mentioned.",
0
};
const char *const text4[] = {
"You're pretty lucky yourself, you know. I follow by rolling 2 3",
"and moving 25-22,24-22, forming a new point.",
0
};
const char *const text5[] = {
"Not a spectacular move, but a safe one. I follow by rolling 6 1.",
"I decide to use this roll to move 22-16,16-17. It leaves me with",
"one man still open, but the blot is farther back on the board, and",
"would suffer less of a loss by being hit.",
0
};
const char *const text6[] = {
"By moving your two men from 17 to 20, you lessen my chance of",
"getting my man off the board. In fact, the odds are 5 to 4",
"against me getting off. I roll with the odds and helplessly",
"receive a 3 5.",
0
};
const char *const text7[] = {
"Note that the blot on 7 cannot be hit unless I get off the bar",
"and have a 1 or a 6 left over, and doing so will leave two of",
"my men open. Also, the blot on 16 cannot be hit at all! With",
"a sigh of frustration, I roll double 6's and remain immobile.",
0
};
const char *const text8[] = {
"See, you did not get hit and, you got to 'cover up' your open men.",
"Quite an accomplishment. Finally, I get off the bar by rolling",
"6 2 and moving 25-23,23-17.",
0
};
const char *const text9[] = {
"My venture off the bar did not last long. However, I got lucky",
"and rolled double 1's, allowing me to move 0-1,1-2,15-14,15-14.",
0
};
const char *const text10[] = {
"You are improving your position greatly and safely, and are well",
"on the way to winning the game. I roll a 6 2 and squeak past",
"your back man. Now the game becomes a race to the finish.",
0
};
const char *const text11[] = {
"Now that it is merely a race, you are trying to get as many men",
"as possible into the inner table, so you can start removing them.",
"I roll a 3 4 and move my two men farthest back to position 11",
"(15-11,14-11).",
0
};
const char *const text12[] = {
"The race is still on, and you have seem to be doing all right.",
"I roll 6 1 and move 14-8,13-12.",
0
};
const char *const text13[] = {
"Notice that you get to remove men the instant you have all of",
"them at your inner table, even if it is the middle of a turn.",
"I roll 1 2 and move 13-11,12-11.",
0
};
const char *const text14[] = {
"Although you could have removed a man, this move illustrates two",
"points: 1) You never have to remove men, and 2) You should try",
"to spread out your men on your inner table. Since you have one",
"man on each position, you should be able to remove at least two",
"men next turn. I roll 2 5 and move 8-6,11-6.",
0
};
const char *const text15[] = {
"This time you were able to remove men. I roll 3 4 and move",
"11-7,11-8. The race continues.",
0
};
const char *const text16[] = {
"More holes are opening up in your inner table, but you are",
"still very much ahead. If we were doubling, you would have",
"doubled long ago. I roll 2 6 and move 8-6,11-5.",
0
};
const char *const text17[] = {
"It pays to spread out your men. I roll 3 5 and move 7-4,8-3.",
0
};
const char *const text18[] = {
"You can only remove some men, but you spread out more and",
"more, in order to be able to remove men more efficiently.",
"I roll double 3's, which help, but not that much. I move",
"8-5,3-0,3-0,3-0.",
0
};
const char *const text19[] = {
"I roll 1 4 and move 5-4,4-0.",
0
};
const char *const text20[] = {
"You are now nicely spread out to win a game. I roll 5 6 and",
"move 5-0,6-0.",
0
};
const char *const text21[] = {
"Any minute now. Just a few short steps from victory. I roll",
"2 4 and move 6-4,4-0.",
0
};
const char *const text22[] = {
"It looks pretty hopeless for me, but I play on, rolling 1 3 and",
"moving 4-3,3-0.",
0
};
const char *const text23[] = {
"Congratulations! You just won a game of backgammon against the",
"computer! You will now be able to play a game, but remember,",
"when you start playing, that doubling will be enabled, which",
"will add another factor to the game... Good luck!!",
"",
0
};
const struct situatn test[] = {
{
{0, 2, 0, 0, 0, 0, -5, 0, -3, 0, 0, 0, 5, -5, 0, 0, 0, 3, 0,
5, 0, 0, 0, 0, -2, 0},
3, 1, {8, 6, 0, 0}, {5, 5, 0, 0}, 4, 2, {text0}
},
{
{0, 2, 0, 0, 0, -2, -4, 0, -2, 0, 0, 0, 5, -5, 0, 0, 0, 2, 0,
4, 0, 2, 0, 0, -2, 0},
5, 5, {13, 13, 8, 8}, {8, 8, 3, 3}, 6, 6, {text1}
},
{
{0, 0, 0, -2, 0, -2, -4, 2, -2, 0, 0, 0, 3, -3, 0, 0, 0, 2, 2,
4, 0, 2, 0, 0, -2, 0},
6, 5, {13, 8, 0, 0}, {8, 2, 0, 0}, 1, 2, {text2}
},
{
{0, 0, -1, -2, 0, -2, -4, 2, -2, 0, 0, 0, 2, -2, 0, 1, 0, 2,
2, 4, 0, 2, 0, 0, -2, 0},
4, 5, {24, 20, 0, 0}, {20, 15, 0, 0}, 2, 5, {text3}
},
{
{0, 0, 0, -2, 0, -2, -4, 3, -2, 0, 0, 0, 2, -2, 0, -1, 0, 2,
2, 4, 0, 2, 0, 0, -1, -1},
2, 3, {25, 24, 0, 0}, {22, 22, 0, 0}, 4, 1, {text4}
},
{
{0, 0, 0, -2, 0, -2, -4, 2, -2, 0, 0, 0, 3, -2, 0, -1, 0, 2,
2, 4, 0, 2, -2, 0, 0, 0},
6, 1, {22, 16, 0, 0}, {16, 15, 0, 0}, 3, 3, {text5}
},
{
{0, 0, 0, -2, 0, -2, -4, 2, -2, 0, 0, 0, 3, -2, 0, -2, 0, 0,
2, 2, 2, 2, 2, 0, 0, -1},
3, 5, {0, 0, 0, 0}, {0, 0, 0, 0}, 5, 4, {text6}
},
{
{0, 0, 0, -2, 0, -2, -4, 1, -2, 0, 0, 0, 3, -2, 0, -2, 1, 0,
2, 2, 2, 2, 2, 0, 0, -1},
6, 6, {0, 0, 0, 0}, {0, 0, 0, 0}, 3, 6, {text7}
},
{
{0, 0, 0, -2, 0, -2, -4, 0, -2, 0, 0, 0, 3, -2, 0, -2, 2, 0,
2, 2, 2, 2, 2, 0, 0, -1},
2, 6, {25, 23, 0, 0}, {23, 17, 0, 0}, 5, 1, {text8}
},
{
{0, 0, 0, -2, 0, -2, -4, 0, -2, 0, 0, 0, 2, -2, 0, -2, 2, 0,
3, 2, 2, 2, 2, 0, 0, -1},
1, 1, {25, 24, 15, 15}, {24, 23, 14, 14}, 4, 6, {text9}
},
{
{0, 0, 0, -2, 0, -2, -4, 0, -2, 0, 0, 0, 0, -2, -2, 0, 3, 0,
4, 2, 2, 2, 2, -1, 0, 0},
6, 2, {23, 17, 0, 0}, {17, 15, 0, 0}, 1, 3, {text10}
},
{
{0, 0, 0, -2, 0, -2, -4, 0, -2, 0, 0, 0, 0, -2, -2, -1, 2, 0,
3, 4, 2, 2, 2, 0, 0, 0},
4, 3, {15, 14, 0, 0}, {11, 11, 0, 0}, 5, 3, {text11}
},
{
{0, 0, 0, -2, 0, -2, -4, 0, -2, 0, 0, -2, 0, -2, -1, 0, 0, 0,
3, 5, 2, 3, 2, 0, 0, 0},
6, 1, {14, 13, 0, 0}, {8, 12, 0, 0}, 4, 4, {text12}
},
{
{0, 0, 0, -2, 0, -2, -4, 0, -3, 0, 0, -2, -1, -1, 0, 0, 0, 0,
0, 5, 2, 2, 5, 0, 0, 0},
2, 1, {13, 12, 0, 0}, {11, 11, 0, 0}, 2, 1, {text13}
},
{
{0, 0, 0, -2, 0, -2, -4, 0, -3, 0, 0, -4, 0, 0, 0, 0, 0, 0,
0, 5, 2, 2, 3, 1, 1, 0},
2, 5, {8, 11, 0, 0}, {6, 6, 0, 0}, 6, 3, {text14}
},
{
{0, 0, 0, -2, 0, -2, -6, 0, -2, 0, 0, -3, 0, 0, 0, 0, 0, 0,
0, 4, 2, 2, 2, 1, 1, 0},
4, 3, {11, 11, 0, 0}, {7, 8, 0, 0}, 2, 5, {text15}
},
{
{0, 0, 0, -2, 0, -2, -6, -1, -3, 0, 0, -1, 0, 0, 0, 0, 0, 0,
0, 4, 1, 2, 2, 0, 1, 0},
2, 6, {8, 11, 0, 0}, {6, 5, 0, 0}, 6, 1, {text16}
},
{
{0, 0, 0, -2, 0, -3, -7, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 1, 2, 2, 0, 0, 0},
5, 3, {8, 7, 0, 0}, {3, 4, 0, 0}, 5, 2, {text17}
},
{
{0, 0, 0, -3, -1, -3, -7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 0, 1, 2, 1, 0, 0},
3, 3, {8, 3, 3, 3}, {5, 0, 0, 0}, 1, 6, {text18}
},
{
{0, 0, 0, 0, -1, -4, -7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 2, 1, 0, 0},
1, 4, {4, 5, 0, 0}, {0, 4, 0, 0}, 2, 3, {text19}
},
{
{0, 0, 0, 0, -1, -3, -7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 0, 0, 0},
5, 6, {6, 5, 0, 0}, {0, 0, 0, 0}, 1, 4, {text20}
},
{
{0, 0, 0, 0, -1, -2, -6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 1, 1, 0, 0, 0},
2, 4, {4, 6, 0, 0}, {0, 4, 0, 0}, 6, 2, {text21}
},
{
{0, 0, 0, 0, -1, -2, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 0, 0},
3, 1, {4, 3, 0, 0}, {3, 0, 0, 0}, 4, 3, {text22}
},
{
{0, 0, 0, 0, 0, -2, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0},
0, 0, {0, 0, 0, 0}, {0, 0, 0, 0}, 0, 0, {text23}
}
};

Some files were not shown because too many files have changed in this diff Show More