diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /games/wump |
initial import of NetBSD tree
Diffstat (limited to 'games/wump')
-rw-r--r-- | games/wump/Makefile | 12 | ||||
-rw-r--r-- | games/wump/pathnames.h | 39 | ||||
-rw-r--r-- | games/wump/wump.6 | 114 | ||||
-rw-r--r-- | games/wump/wump.c | 785 | ||||
-rw-r--r-- | games/wump/wump.info | 41 |
5 files changed, 991 insertions, 0 deletions
diff --git a/games/wump/Makefile b/games/wump/Makefile new file mode 100644 index 00000000000..58c65e7c0ba --- /dev/null +++ b/games/wump/Makefile @@ -0,0 +1,12 @@ +# $NetBSD: Makefile,v 1.4 1995/04/22 08:19:45 cgd Exp $ +# @(#)Makefile 8.1 (Berkeley) 5/31/93 + +PROG= wump +MAN= wump.6 +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/games/wump/pathnames.h b/games/wump/pathnames.h new file mode 100644 index 00000000000..8f534830e9d --- /dev/null +++ b/games/wump/pathnames.h @@ -0,0 +1,39 @@ +/* $NetBSD: pathnames.h,v 1.3 1995/04/22 08:19:48 cgd Exp $ */ + +/*- + * Copyright (c) 1989, 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 + */ + +#define _PATH_PAGER "/usr/bin/more" +#define _PATH_WUMPINFO "/usr/share/games/wump.info" diff --git a/games/wump/wump.6 b/games/wump/wump.6 new file mode 100644 index 00000000000..4a5c26e7fa1 --- /dev/null +++ b/games/wump/wump.6 @@ -0,0 +1,114 @@ +.\" $NetBSD: wump.6,v 1.4 1995/04/22 08:19:49 cgd 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 +.\" 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 8.1 (Berkeley) 5/31/93 +.\" +.Dd May 31, 1993 +.Dt WUMP 6 +.Os +.Sh NAME +.Nm wump +.Nd hunt the wumpus in an underground cave +.Sh SYNOPSIS +.Nm wump +.Op Fl h +.Op Fl a Ar arrows +.Op Fl b Ar bats +.Op Fl p Ar pits +.Op Fl r Ar rooms +.Op Fl t Ar tunnels +.Sh DESCRIPTION +The game +.Nm wump +is based on a fantasy game first presented in the pages of +.Em 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: +.Bl -tag -width indent +.It Fl a +Specifies the number of magic arrows the adventurer gets. +The default is five. +.It Fl b +Specifies the number of rooms in the cave which contain bats. +The default is three. +.It Fl h +Play the hard version -- more pits, more bats, and a generally more +dangerous cave. +.It Fl p +Specifies the number of rooms in the cave which contain bottomless pits. +The default is three. +.It Fl r +Specifies the number of rooms in the cave. +The default cave size is twenty-five rooms. +.It Fl 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. +.El +.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 +.Em 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/games/wump/wump.c b/games/wump/wump.c new file mode 100644 index 00000000000..536324ef711 --- /dev/null +++ b/games/wump/wump.c @@ -0,0 +1,785 @@ +/* $NetBSD: wump.c,v 1.4 1995/04/24 12:26:22 cgd Exp $ */ + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * 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 +static char 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[] = "@(#)wump.c 8.1 (Berkeley) 5/31/93"; +#else +static char rcsid[] = "$NetBSD: wump.c,v 1.4 1995/04/24 12:26:22 cgd Exp $"; +#endif +#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 <string.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/games/wump/wump.info b/games/wump/wump.info new file mode 100644 index 00000000000..329e8219c0c --- /dev/null +++ b/games/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. + |