summaryrefslogtreecommitdiffstats
path: root/wump
diff options
context:
space:
mode:
authorcgd <cgd@NetBSD.org>1993-03-21 09:45:37 +0000
committercgd <cgd@NetBSD.org>1993-03-21 09:45:37 +0000
commit77e3814f0c0e3dea4d0032e25666f77e6f83bfff (patch)
tree7eddfcbf3dd12089e71dc3fafb0a106c5c5766c7 /wump
parente81d63576b2e46ab90da7d75fa155ea57ee4d32e (diff)
downloadbsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.tar.gz
bsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.tar.zst
bsdgames-darwin-77e3814f0c0e3dea4d0032e25666f77e6f83bfff.zip
initial import of 386bsd-0.1 sources
Diffstat (limited to 'wump')
-rw-r--r--wump/Makefile11
-rw-r--r--wump/pathnames.h37
-rw-r--r--wump/wump.6110
-rw-r--r--wump/wump.c778
-rw-r--r--wump/wump.info41
5 files changed, 977 insertions, 0 deletions
diff --git a/wump/Makefile b/wump/Makefile
new file mode 100644
index 00000000..ecb49134
--- /dev/null
+++ b/wump/Makefile
@@ -0,0 +1,11 @@
+# @(#)Makefile 5.4 (Berkeley) 5/11/90
+
+PROG= wump
+MAN6= wump.0
+HIDEGAME=hidegame
+
+beforeinstall:
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/wump.info \
+ ${DESTDIR}/usr/share/games
+
+.include <bsd.prog.mk>
diff --git a/wump/pathnames.h b/wump/pathnames.h
new file mode 100644
index 00000000..62e4203e
--- /dev/null
+++ b/wump/pathnames.h
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 1989 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 5.1 (Berkeley) 6/1/90
+ */
+
+#define _PATH_PAGER "/usr/bin/more"
+#define _PATH_WUMPINFO "/usr/share/games/wump.info"
diff --git a/wump/wump.6 b/wump/wump.6
new file mode 100644
index 00000000..b230aab2
--- /dev/null
+++ b/wump/wump.6
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1989 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Dave Taylor, of Intuitive Systems.
+.\"
+.\" 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.
+.\"
+.\" @(#)wump.6 6.3 (Berkeley) 6/23/90
+.\"
+.TH WUMP 6 "June 23, 1990"
+.UC 7
+.SH NAME
+wump \- hunt the wumpus in an underground cave
+.SH SYNOPSIS
+.ft B
+wump [-h] [-a arrows] [-b bats] [-p pits] [-r rooms] [-t tunnels]
+.ft R
+.SH DESCRIPTION
+The game
+.I wump
+is based on a fantasy game first presented in the pages of
+.I "People's Computer Company"
+in 1973.
+In Hunt the Wumpus you are placed in a cave built of many different rooms,
+all interconnected by tunnels.
+Your quest is to find and shoot the evil Wumpus that resides elsewhere in
+the cave without running into any pits or using up your limited supply of
+arrows.
+.PP
+The options are as follows:
+.TP
+.I -a
+Specifies the number of magic arrows the adventurer gets.
+The default is five.
+.TP
+.I -b
+Specifies the number of rooms in the cave which contain bats.
+The default is three.
+.TP
+.I -h
+Play the hard version -- more pits, more bats, and a generally more
+dangerous cave.
+.TP
+.I -n
+Specifies the number of rooms in the cave which contain bottomless pits.
+The default is three.
+.TP
+.I -r
+Specifies the number of rooms in the cave.
+The default cave size is twenty-five rooms.
+.TP
+.I -t
+Specifies the number of tunnels connecting each room in the cave to
+another room.
+Beware, too many tunnels in a small cave can easily cause it to collapse!
+The default cave room has three tunnels to other rooms.
+.PP
+While wandering through the cave you'll notice that, while there are tunnels
+everywhere, there are some mysterious quirks to the cave topology, including
+some tunnels that go from one room to another, but not necessarily back!
+Also, most pesky of all are the rooms that are home to large numbers of bats,
+which, upon being disturbed, will en masse grab you and move you to another
+portion of the cave (including those housing bottomless pits, sure
+death for unwary explorers).
+.PP
+Fortunately, you're not going into the cave without any weapons or tools,
+and in fact your biggest aids are your senses; you can often smell the
+rather odiferous Wumpus up to
+.I two
+rooms away, and you can always feel the drafts created by the occasional
+bottomless pit and hear the rustle of the bats in caves they might be
+sleeping within.
+.PP
+To kill the wumpus, you'll need to shoot it with one of your magic arrows.
+Fortunately, you don't have to be in the same room as the creature, and can
+instead shoot the arrow from as far as three or four rooms away!
+.PP
+When you shoot an arrow, you do so by typing in a list of rooms that you'd
+like it to travel to.
+If at any point in its travels it cannot find a tunnel to the room you
+specify from the room it's in, it will instead randomly fly down one of the
+tunnels, possibly, if you're real unlucky, even flying back into the room
+you're in and hitting you!
diff --git a/wump/wump.c b/wump/wump.c
new file mode 100644
index 00000000..7d40b69b
--- /dev/null
+++ b/wump/wump.c
@@ -0,0 +1,778 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * Copyright (c) 1989 Dave Taylor, Intuitive Systems.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Dave Taylor, of Intuitive Systems.
+ *
+ * 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.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)wump.c 4.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/*
+ * A very new version of the age old favorite Hunt-The-Wumpus game that has
+ * been a part of the BSD distribution of Unix for longer than us old folk
+ * would care to remember.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include "pathnames.h"
+
+/* some defines to spec out what our wumpus cave should look like */
+
+#define MAX_ARROW_SHOT_DISTANCE 6 /* +1 for '0' stopper */
+#define MAX_LINKS_IN_ROOM 25 /* a complex cave */
+
+#define MAX_ROOMS_IN_CAVE 250
+#define ROOMS_IN_CAVE 20
+#define MIN_ROOMS_IN_CAVE 10
+
+#define LINKS_IN_ROOM 3
+#define NUMBER_OF_ARROWS 5
+#define PIT_COUNT 3
+#define BAT_COUNT 3
+
+#define EASY 1 /* levels of play */
+#define HARD 2
+
+/* some macro definitions for cleaner output */
+
+#define plural(n) (n == 1 ? "" : "s")
+
+/* simple cave data structure; +1 so we can index from '1' not '0' */
+struct room_record {
+ int tunnel[MAX_LINKS_IN_ROOM];
+ int has_a_pit, has_a_bat;
+} cave[MAX_ROOMS_IN_CAVE+1];
+
+/*
+ * global variables so we can keep track of where the player is, how
+ * many arrows they still have, where el wumpo is, and so on...
+ */
+int player_loc = -1; /* player location */
+int wumpus_loc = -1; /* The Bad Guy location */
+int level = EASY; /* level of play */
+int arrows_left; /* arrows unshot */
+
+#ifdef DEBUG
+int debug = 0;
+#endif
+
+int pit_num = PIT_COUNT; /* # pits in cave */
+int bat_num = BAT_COUNT; /* # bats */
+int room_num = ROOMS_IN_CAVE; /* # rooms in cave */
+int link_num = LINKS_IN_ROOM; /* links per room */
+int arrow_num = NUMBER_OF_ARROWS; /* arrow inventory */
+
+char answer[20]; /* user input */
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ extern char *optarg;
+ int c;
+
+#ifdef DEBUG
+ while ((c = getopt(argc, argv, "a:b:hp:r:t:d")) != EOF)
+#else
+ while ((c = getopt(argc, argv, "a:b:hp:r:t:")) != EOF)
+#endif
+ switch (c) {
+ case 'a':
+ arrow_num = atoi(optarg);
+ break;
+ case 'b':
+ bat_num = atoi(optarg);
+ break;
+#ifdef DEBUG
+ case 'd':
+ debug = 1;
+ break;
+#endif
+ case 'h':
+ level = HARD;
+ break;
+ case 'p':
+ pit_num = atoi(optarg);
+ break;
+ case 'r':
+ room_num = atoi(optarg);
+ if (room_num < MIN_ROOMS_IN_CAVE) {
+ (void)fprintf(stderr,
+ "No self-respecting wumpus would live in such a small cave!\n");
+ exit(1);
+ }
+ if (room_num > MAX_ROOMS_IN_CAVE) {
+ (void)fprintf(stderr,
+ "Even wumpii can't furnish caves that large!\n");
+ exit(1);
+ }
+ break;
+ case 't':
+ link_num = atoi(optarg);
+ if (link_num < 2) {
+ (void)fprintf(stderr,
+ "Wumpii like extra doors in their caves!\n");
+ exit(1);
+ }
+ break;
+ case '?':
+ default:
+ usage();
+ }
+
+ if (link_num > MAX_LINKS_IN_ROOM ||
+ link_num > room_num - (room_num / 4)) {
+ (void)fprintf(stderr,
+"Too many tunnels! The cave collapsed!\n(Fortunately, the wumpus escaped!)\n");
+ exit(1);
+ }
+
+ if (level == HARD) {
+ bat_num += ((random() % (room_num / 2)) + 1);
+ pit_num += ((random() % (room_num / 2)) + 1);
+ }
+
+ if (bat_num > room_num / 2) {
+ (void)fprintf(stderr,
+"The wumpus refused to enter the cave, claiming it was too crowded!\n");
+ exit(1);
+ }
+
+ if (pit_num > room_num / 2) {
+ (void)fprintf(stderr,
+"The wumpus refused to enter the cave, claiming it was too dangerous!\n");
+ exit(1);
+ }
+
+ instructions();
+ cave_init();
+
+ /* and we're OFF! da dum, da dum, da dum, da dum... */
+ (void)printf(
+"\nYou're in a cave with %d rooms and %d tunnels leading from each room.\n\
+There are %d bat%s and %d pit%s scattered throughout the cave, and your\n\
+quiver holds %d custom super anti-evil Wumpus arrows. Good luck.\n",
+ room_num, link_num, bat_num, plural(bat_num), pit_num,
+ plural(pit_num), arrow_num);
+
+ for (;;) {
+ initialize_things_in_cave();
+ arrows_left = arrow_num;
+ do {
+ display_room_stats();
+ (void)printf("Move or shoot? (m-s) ");
+ (void)fflush(stdout);
+ if (!fgets(answer, sizeof(answer), stdin))
+ break;
+ } while (!take_action());
+
+ if (!getans("\nCare to play another game? (y-n) "))
+ exit(0);
+ if (getans("In the same cave? (y-n) "))
+ clear_things_in_cave();
+ else
+ cave_init();
+ }
+ /* NOTREACHED */
+}
+
+display_room_stats()
+{
+ register int i;
+
+ /*
+ * Routine will explain what's going on with the current room, as well
+ * as describe whether there are pits, bats, & wumpii nearby. It's
+ * all pretty mindless, really.
+ */
+ (void)printf(
+"\nYou are in room %d of the cave, and have %d arrow%s left.\n",
+ player_loc, arrows_left, plural(arrows_left));
+
+ if (bats_nearby())
+ (void)printf("*rustle* *rustle* (must be bats nearby)\n");
+ if (pit_nearby())
+ (void)printf("*whoosh* (I feel a draft from some pits).\n");
+ if (wump_nearby())
+ (void)printf("*sniff* (I can smell the evil Wumpus nearby!)\n");
+
+ (void)printf("There are tunnels to rooms %d, ",
+ cave[player_loc].tunnel[0]);
+
+ for (i = 1; i < link_num - 1; i++)
+ if (cave[player_loc].tunnel[i] <= room_num)
+ (void)printf("%d, ", cave[player_loc].tunnel[i]);
+ (void)printf("and %d.\n", cave[player_loc].tunnel[link_num - 1]);
+}
+
+take_action()
+{
+ /*
+ * Do the action specified by the player, either 'm'ove, 's'hoot
+ * or something exceptionally bizarre and strange! Returns 1
+ * iff the player died during this turn, otherwise returns 0.
+ */
+ switch (*answer) {
+ case 'M':
+ case 'm': /* move */
+ return(move_to(answer + 1));
+ case 'S':
+ case 's': /* shoot */
+ return(shoot(answer + 1));
+ case 'Q':
+ case 'q':
+ case 'x':
+ exit(0);
+ case '\n':
+ return(0);
+ }
+ if (random() % 15 == 1)
+ (void)printf("Que pasa?\n");
+ else
+ (void)printf("I don't understand!\n");
+ return(0);
+}
+
+move_to(room_number)
+ char *room_number;
+{
+ int i, just_moved_by_bats, next_room, tunnel_available;
+
+ /*
+ * This is responsible for moving the player into another room in the
+ * cave as per their directions. If room_number is a null string,
+ * then we'll prompt the user for the next room to go into. Once
+ * we've moved into the room, we'll check for things like bats, pits,
+ * and so on. This routine returns 1 if something occurs that kills
+ * the player and 0 otherwise...
+ */
+ tunnel_available = just_moved_by_bats = 0;
+ next_room = atoi(room_number);
+
+ /* crap for magic tunnels */
+ if (next_room == room_num + 1 &&
+ cave[player_loc].tunnel[link_num-1] != next_room)
+ ++next_room;
+
+ while (next_room < 1 || next_room > room_num + 1) {
+ if (next_room < 0 && next_room != -1)
+(void)printf("Sorry, but we're constrained to a semi-Euclidean cave!\n");
+ if (next_room > room_num + 1)
+(void)printf("What? The cave surely isn't quite that big!\n");
+ if (next_room == room_num + 1 &&
+ cave[player_loc].tunnel[link_num-1] != next_room) {
+ (void)printf("What? The cave isn't that big!\n");
+ ++next_room;
+ }
+ (void)printf("To which room do you wish to move? ");
+ (void)fflush(stdout);
+ if (!fgets(answer, sizeof(answer), stdin))
+ return(1);
+ next_room = atoi(answer);
+ }
+
+ /* now let's see if we can move to that room or not */
+ tunnel_available = 0;
+ for (i = 0; i < link_num; i++)
+ if (cave[player_loc].tunnel[i] == next_room)
+ tunnel_available = 1;
+
+ if (!tunnel_available) {
+ (void)printf("*Oof!* (You hit the wall)\n");
+ if (random() % 6 == 1) {
+(void)printf("Your colorful comments awaken the wumpus!\n");
+ move_wump();
+ if (wumpus_loc == player_loc) {
+ wump_kill();
+ return(1);
+ }
+ }
+ return(0);
+ }
+
+ /* now let's move into that room and check it out for dangers */
+ if (next_room == room_num + 1)
+ jump(next_room = (random() % room_num) + 1);
+
+ player_loc = next_room;
+ for (;;) {
+ if (next_room == wumpus_loc) { /* uh oh... */
+ wump_kill();
+ return(1);
+ }
+ if (cave[next_room].has_a_pit)
+ if (random() % 12 < 2) {
+ pit_survive();
+ return(0);
+ } else {
+ pit_kill();
+ return(1);
+ }
+
+ if (cave[next_room].has_a_bat) {
+ (void)printf(
+"*flap* *flap* *flap* (humongous bats pick you up and move you%s!)\n",
+ just_moved_by_bats ? " again": "");
+ next_room = player_loc = (random() % room_num) + 1;
+ just_moved_by_bats = 1;
+ }
+
+ else
+ break;
+ }
+ return(0);
+}
+
+shoot(room_list)
+ char *room_list;
+{
+ int chance, next, roomcnt;
+ int j, arrow_location, link, ok;
+ char *p, *strtok();
+
+ /*
+ * Implement shooting arrows. Arrows are shot by the player indicating
+ * a space-separated list of rooms that the arrow should pass through;
+ * if any of the rooms they specify are not accessible via tunnel from
+ * the room the arrow is in, it will instead fly randomly into another
+ * room. If the player hits the wumpus, this routine will indicate
+ * such. If it misses, this routine will *move* the wumpus one room.
+ * If it's the last arrow, the player then dies... Returns 1 if the
+ * player has won or died, 0 if nothing has happened.
+ */
+ arrow_location = player_loc;
+ for (roomcnt = 1;; ++roomcnt, room_list = NULL) {
+ if (!(p = strtok(room_list, " \t\n")))
+ if (roomcnt == 1) {
+ (void)printf(
+ "The arrow falls to the ground at your feet!\n");
+ return(0);
+ } else
+ break;
+ if (roomcnt > 5) {
+ (void)printf(
+"The arrow wavers in its flight and and can go no further!\n");
+ break;
+ }
+ next = atoi(p);
+ for (j = 0, ok = 0; j < link_num; j++)
+ if (cave[arrow_location].tunnel[j] == next)
+ ok = 1;
+
+ if (ok) {
+ if (next > room_num) {
+ (void)printf(
+"A faint gleam tells you the arrow has gone through a magic tunnel!\n");
+ arrow_location = (random() % room_num) + 1;
+ } else
+ arrow_location = next;
+ } else {
+ link = (random() % link_num);
+ if (link == player_loc)
+ (void)printf(
+"*thunk* The arrow can't find a way from %d to %d and flys back into\n\
+your room!\n",
+ arrow_location, next);
+ else if (cave[arrow_location].tunnel[link] > room_num)
+ (void)printf(
+"*thunk* The arrow flys randomly into a magic tunnel, thence into\n\
+room %d!\n",
+ cave[arrow_location].tunnel[link]);
+ else
+ (void)printf(
+"*thunk* The arrow can't find a way from %d to %d and flys randomly\n\
+into room %d!\n",
+ arrow_location, next,
+ cave[arrow_location].tunnel[link]);
+ arrow_location = cave[arrow_location].tunnel[link];
+ break;
+ }
+ chance = random() % 10;
+ if (roomcnt == 3 && chance < 2) {
+ (void)printf(
+"Your bowstring breaks! *twaaaaaang*\n\
+The arrow is weakly shot and can go no further!\n");
+ break;
+ } else if (roomcnt == 4 && chance < 6) {
+ (void)printf(
+"The arrow wavers in its flight and and can go no further!\n");
+ break;
+ }
+ }
+
+ /*
+ * now we've gotten into the new room let us see if El Wumpo is
+ * in the same room ... if so we've a HIT and the player WON!
+ */
+ if (arrow_location == wumpus_loc) {
+ kill_wump();
+ return(1);
+ }
+
+ if (arrow_location == player_loc) {
+ shoot_self();
+ return(1);
+ }
+
+ if (!--arrows_left) {
+ no_arrows();
+ return(1);
+ }
+
+ {
+ /* each time you shoot, it's more likely the wumpus moves */
+ static int lastchance = 2;
+
+ if (random() % level == EASY ? 12 : 9 < (lastchance += 2)) {
+ move_wump();
+ if (wumpus_loc == player_loc)
+ wump_kill();
+ lastchance = random() % 3;
+
+ }
+ }
+ return(0);
+}
+
+cave_init()
+{
+ register int i, j, k, link;
+ int delta, int_compare();
+ time_t time();
+
+ /*
+ * This does most of the interesting work in this program actually!
+ * In this routine we'll initialize the Wumpus cave to have all rooms
+ * linking to all others by stepping through our data structure once,
+ * recording all forward links and backwards links too. The parallel
+ * "linkcount" data structure ensures that no room ends up with more
+ * than three links, regardless of the quality of the random number
+ * generator that we're using.
+ */
+ srandom((int)time((time_t *)0));
+
+ /* initialize the cave first off. */
+ for (i = 1; i <= room_num; ++i)
+ for (j = 0; j < link_num ; ++j)
+ cave[i].tunnel[j] = -1;
+
+ /* choose a random 'hop' delta for our guaranteed link */
+ while (!(delta = random() % room_num));
+
+ for (i = 1; i <= room_num; ++i) {
+ link = ((i + delta) % room_num) + 1; /* connection */
+ cave[i].tunnel[0] = link; /* forw link */
+ cave[link].tunnel[1] = i; /* back link */
+ }
+ /* now fill in the rest of the cave with random connections */
+ for (i = 1; i <= room_num; i++)
+ for (j = 2; j < link_num ; j++) {
+ if (cave[i].tunnel[j] != -1)
+ continue;
+try_again: link = (random() % room_num) + 1;
+ /* skip duplicates */
+ for (k = 0; k < j; k++)
+ if (cave[i].tunnel[k] == link)
+ goto try_again;
+ cave[i].tunnel[j] = link;
+ if (random() % 2 == 1)
+ continue;
+ for (k = 0; k < link_num; ++k) {
+ /* if duplicate, skip it */
+ if (cave[link].tunnel[k] == i)
+ k = link_num;
+
+ /* if open link, use it, force exit */
+ if (cave[link].tunnel[k] == -1) {
+ cave[link].tunnel[k] = i;
+ k = link_num;
+ }
+ }
+ }
+ /*
+ * now that we're done, sort the tunnels in each of the rooms to
+ * make it easier on the intrepid adventurer.
+ */
+ for (i = 1; i <= room_num; ++i)
+ qsort(cave[i].tunnel, (u_int)link_num,
+ sizeof(cave[i].tunnel[0]), int_compare);
+
+#ifdef DEBUG
+ if (debug)
+ for (i = 1; i <= room_num; ++i) {
+ (void)printf("<room %d has tunnels to ", i);
+ for (j = 0; j < link_num; ++j)
+ (void)printf("%d ", cave[i].tunnel[j]);
+ (void)printf(">\n");
+ }
+#endif
+}
+
+clear_things_in_cave()
+{
+ register int i;
+
+ /*
+ * remove bats and pits from the current cave in preparation for us
+ * adding new ones via the initialize_things_in_cave() routines.
+ */
+ for (i = 1; i <= room_num; ++i)
+ cave[i].has_a_bat = cave[i].has_a_pit = 0;
+}
+
+initialize_things_in_cave()
+{
+ register int i, loc;
+
+ /* place some bats, pits, the wumpus, and the player. */
+ for (i = 0; i < bat_num; ++i) {
+ do {
+ loc = (random() % room_num) + 1;
+ } while (cave[loc].has_a_bat);
+ cave[loc].has_a_bat = 1;
+#ifdef DEBUG
+ if (debug)
+ (void)printf("<bat in room %d>\n", loc);
+#endif
+ }
+
+ for (i = 0; i < pit_num; ++i) {
+ do {
+ loc = (random() % room_num) + 1;
+ } while (cave[loc].has_a_pit && cave[loc].has_a_bat);
+ cave[loc].has_a_pit = 1;
+#ifdef DEBUG
+ if (debug)
+ (void)printf("<pit in room %d>\n", loc);
+#endif
+ }
+
+ wumpus_loc = (random() % room_num) + 1;
+#ifdef DEBUG
+ if (debug)
+ (void)printf("<wumpus in room %d>\n", loc);
+#endif
+
+ do {
+ player_loc = (random() % room_num) + 1;
+ } while (player_loc == wumpus_loc || (level == HARD ?
+ (link_num / room_num < 0.4 ? wump_nearby() : 0) : 0));
+}
+
+getans(prompt)
+ char *prompt;
+{
+ char buf[20];
+
+ /*
+ * simple routine to ask the yes/no question specified until the user
+ * answers yes or no, then return 1 if they said 'yes' and 0 if they
+ * answered 'no'.
+ */
+ for (;;) {
+ (void)printf("%s", prompt);
+ (void)fflush(stdout);
+ if (!fgets(buf, sizeof(buf), stdin))
+ return(0);
+ if (*buf == 'N' || *buf == 'n')
+ return(0);
+ if (*buf == 'Y' || *buf == 'y')
+ return(1);
+ (void)printf(
+"I don't understand your answer; please enter 'y' or 'n'!\n");
+ }
+ /* NOTREACHED */
+}
+
+bats_nearby()
+{
+ register int i;
+
+ /* check for bats in the immediate vicinity */
+ for (i = 0; i < link_num; ++i)
+ if (cave[cave[player_loc].tunnel[i]].has_a_bat)
+ return(1);
+ return(0);
+}
+
+pit_nearby()
+{
+ register int i;
+
+ /* check for pits in the immediate vicinity */
+ for (i = 0; i < link_num; ++i)
+ if (cave[cave[player_loc].tunnel[i]].has_a_pit)
+ return(1);
+ return(0);
+}
+
+wump_nearby()
+{
+ register int i, j;
+
+ /* check for a wumpus within TWO caves of where we are */
+ for (i = 0; i < link_num; ++i) {
+ if (cave[player_loc].tunnel[i] == wumpus_loc)
+ return(1);
+ for (j = 0; j < link_num; ++j)
+ if (cave[cave[player_loc].tunnel[i]].tunnel[j] ==
+ wumpus_loc)
+ return(1);
+ }
+ return(0);
+}
+
+move_wump()
+{
+ wumpus_loc = cave[wumpus_loc].tunnel[random() % link_num];
+}
+
+int_compare(a, b)
+ int *a, *b;
+{
+ return(*a < *b ? -1 : 1);
+}
+
+instructions()
+{
+ char buf[120], *p, *getenv();
+
+ /*
+ * read the instructions file, if needed, and show the user how to
+ * play this game!
+ */
+ if (!getans("Instructions? (y-n) "))
+ return;
+
+ if (access(_PATH_WUMPINFO, R_OK)) {
+ (void)printf(
+"Sorry, but the instruction file seems to have disappeared in a\n\
+puff of greasy black smoke! (poof)\n");
+ return;
+ }
+
+ if (!(p = getenv("PAGER")) ||
+ strlen(p) > sizeof(buf) + strlen(_PATH_WUMPINFO) + 5)
+ p = _PATH_PAGER;
+
+ (void)sprintf(buf, "%s %s", p, _PATH_WUMPINFO);
+ (void)system(buf);
+}
+
+usage()
+{
+ (void)fprintf(stderr,
+"usage: wump [-h] [-a arrows] [-b bats] [-p pits] [-r rooms] [-t tunnels]\n");
+ exit(1);
+}
+
+/* messages */
+
+wump_kill()
+{
+ (void)printf(
+"*ROAR* *chomp* *snurfle* *chomp*!\n\
+Much to the delight of the Wumpus, you walked right into his mouth,\n\
+making you one of the easiest dinners he's ever had! For you, however,\n\
+it's a rather unpleasant death. The only good thing is that it's been\n\
+so long since the evil Wumpus cleaned his teeth that you immediately\n\
+passed out from the stench!\n");
+}
+
+kill_wump()
+{
+ (void)printf(
+"*thwock!* *groan* *crash*\n\n\
+A horrible roar fills the cave, and you realize, with a smile, that you\n\
+have slain the evil Wumpus and won the game! You don't want to tarry for\n\
+long, however, because not only is the Wumpus famous, but the stench of\n\
+dead Wumpus is also quite well known, a stench plenty enough to slay the\n\
+mightiest adventurer at a single whiff!!\n");
+}
+
+no_arrows()
+{
+ (void)printf(
+"\nYou turn and look at your quiver, and realize with a sinking feeling\n\
+that you've just shot your last arrow (figuratively, too). Sensing this\n\
+with its psychic powers, the evil Wumpus rampagees through the cave, finds\n\
+you, and with a mighty *ROAR* eats you alive!\n");
+}
+
+shoot_self()
+{
+ (void)printf(
+"\n*Thwack!* A sudden piercing feeling informs you that the ricochet\n\
+of your wild arrow has resulted in it wedging in your side, causing\n\
+extreme agony. The evil Wumpus, with its psychic powers, realizes this\n\
+and immediately rushes to your side, not to help, alas, but to EAT YOU!\n\
+(*CHOMP*)\n");
+}
+
+jump(where)
+ int where;
+{
+ (void)printf(
+"\nWith a jaunty step you enter the magic tunnel. As you do, you\n\
+notice that the walls are shimmering and glowing. Suddenly you feel\n\
+a very curious, warm sensation and find yourself in room %d!!\n", where);
+}
+
+pit_kill()
+{
+ (void)printf(
+"*AAAUUUUGGGGGHHHHHhhhhhhhhhh...*\n\
+The whistling sound and updraft as you walked into this room of the\n\
+cave apparently wasn't enough to clue you in to the presence of the\n\
+bottomless pit. You have a lot of time to reflect on this error as\n\
+you fall many miles to the core of the earth. Look on the bright side;\n\
+you can at least find out if Jules Verne was right...\n");
+}
+
+pit_survive()
+{
+ (void)printf(
+"Without conscious thought you grab for the side of the cave and manage\n\
+to grasp onto a rocky outcrop. Beneath your feet stretches the limitless\n\
+depths of a bottomless pit! Rock crumbles beneath your feet!\n");
+}
diff --git a/wump/wump.info b/wump/wump.info
new file mode 100644
index 00000000..329e8219
--- /dev/null
+++ b/wump/wump.info
@@ -0,0 +1,41 @@
+Welcome to the game of Hunt the Wumpus.
+
+The Wumpus typically lives in a cave of twenty rooms, with each room having
+three tunnels connecting it to other rooms in the cavern. Caves may vary,
+however, depending on options specified when starting the game.
+
+The game has the following hazards for intrepid adventurers to wind their
+way through:
+
+ Pits -- If you fall into one of the bottomless pits, you find yourself
+ slung back out on the far side of the Earth and in very poor
+ shape to continue your quest since you're dead.
+
+ Bats -- As with any other cave, the Wumpus cave has bats in residence.
+ These are a bit more potent, however, and if you stumble into
+ one of their rooms they will rush up and carry you elsewhere in
+ the cave.
+
+ Wumpus -- If you happen to walk into the room the Wumpus is in you'll find
+ that he has quite an appetite for young adventurous humans! Not
+ recommended.
+
+The Wumpus, by the way, is not bothered by the hazards since he has sucker
+feet and is too big for a bat to lift. If you try to shoot him and miss,
+there's also a chance that he'll up and move himself into another cave,
+though by nature the Wumpus is a sedentary creature.
+
+Each turn you may either move or shoot a crooked arrow. Moving is done
+simply by specifying "m" for move and the number of the room that you'd
+like to move down a tunnel towards. Shooting is done similarly; indicate
+that you'd like to shoot one of your magic arrows with an "s" for shoot,
+then list a set of connected room numbers through which the deadly shaft
+should fly!
+
+If your path for the arrow is incorrect, however, it will flail about in
+the room it can't understand and randomly pick a tunnel to continue
+through. You might just end up shooting yourself in the foot if you're
+not careful! On the other hand, if you shoot the Wumpus you've WON!
+
+Good luck.
+