From: Eric S. Raymond Date: Wed, 7 Feb 2024 10:56:40 +0000 (-0500) Subject: Ready to ship 1.10 X-Git-Tag: 1.10^0 X-Git-Url: https://jxself.org/git/?p=wumpus.git;a=commitdiff_plain;h=HEAD;hp=696447095f4d7fd1752336c4b7dc59be694d74bb Ready to ship 1.10 --- diff --git a/Makefile b/Makefile index 6b19476..c1ceb6f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ # # Makefile for `Hunt the Wumpus' and `Superhack' games # -VERS=1.6 +# SPDX-FileCopyrightText: (C) Eric S. Raymond +# SPDX-License-Identifier: BSD-2-Clause + +VERS=$(shell sed -n +# SPDX-License-Identifier: BSD-2-Clause Package: wumpus diff --git a/superhack.c b/superhack.c index 2a245bd..22333f9 100644 --- a/superhack.c +++ b/superhack.c @@ -10,425 +10,413 @@ * if you believe *that*... * * SPDX-License-Identifier: BSD-2-Clause + * SPDX-FileCopyrightText: (C) Eric S. Raymond */ -#include #include +#include #include #include -#include -#include #include +#include +#include static int path[5]; static int j, k, scratchloc, pies; -static char inp[BUFSIZ]; /* common input buffer */ +static char inp[BUFSIZ]; /* common input buffer */ #define NUMBERS "0123456789" -#define YOU 0 -#define RMS 1 -#define STARLET1 2 -#define STARLET2 3 -#define DROID1 4 -#define DROID2 5 -#define LUSER1 6 -#define LUSER2 7 -#define LOCS 8 +#define YOU 0 +#define RMS 1 +#define STARLET1 2 +#define STARLET2 3 +#define DROID1 4 +#define DROID2 5 +#define LUSER1 6 +#define LUSER2 7 +#define LOCS 8 static int loc[LOCS]; -#define NOT 0 -#define WIN 1 -#define LOSE -1 +#define NOT 0 +#define WIN 1 +#define LOSE -1 static int finished; -#define IGNORE(r) do{if(r);}while(0) - -static int cave[20][3] = -{ - {1,4,7}, - {0,2,9}, - {1,3,11}, - {2,4,13}, - {0,3,5}, - {4,6,14}, - {5,7,16}, - {0,6,8}, - {7,9,17}, - {1,8,10}, - {9,11,18}, - {2,10,12}, - {11,13,19}, - {3,12,14}, - {5,13,15}, - {14,16,19}, - {6,15,17}, - {8,16,18}, - {10,17,19}, - {12,15,18}, +#define IGNORE(r) \ + do { \ + if (r) \ + ; \ + } while (0) + +static int cave[20][3] = { + {1, 4, 7}, {0, 2, 9}, {1, 3, 11}, {2, 4, 13}, {0, 3, 5}, + {4, 6, 14}, {5, 7, 16}, {0, 6, 8}, {7, 9, 17}, {1, 8, 10}, + {9, 11, 18}, {2, 10, 12}, {11, 13, 19}, {3, 12, 14}, {5, 13, 15}, + {14, 16, 19}, {6, 15, 17}, {8, 16, 18}, {10, 17, 19}, {12, 15, 18}, }; -#define FNA() (rand() % 20) +#define FNA() (rand() % 20) -#define FNB() (rand() % 3) +#define FNB() (rand() % 3) -#define FNC() (rand() % 4) +#define FNC() (rand() % 4) int getlet(prompt) char *prompt; { - (void) printf("%s? ", prompt); - if (fgets(inp, sizeof(inp), stdin)) - return(tolower(inp[0])); - else { - fputs("\n",stdout); - exit(1); - } + (void)printf("%s? ", prompt); + if (fgets(inp, sizeof(inp), stdin)) { + return (tolower(inp[0])); + } else { + fputs("\n", stdout); + exit(1); + } } -#define PM(x) puts(x); - -void print_instructions() -{ - PM("Welcome to `Hunt the Superhack'\n") - -PM(" The superhack lives on the 9th floor of 45 Technology Square in"); -PM("Cambridge, Massachusetts. Your mission is to throw a pie in his face.\n"); - - PM(" First, you'll have to find him. A botched experiment by an MIT"); - PM("physics group has regularized the floor's topology, so that each"); - PM("room has exits to three other rooms. (Look at a dodecahedron to"); - PM("see how this works --- if you don't know what a dodecahedron is,"); - PM("ask someone.)\n"); - - PM("You:"); - PM(" Each turn you may move to an adjacent room or throw a pie. If"); - PM("you run out of pies, you lose. Each pie can pass through up to"); - PM("five rooms (connected by a continuous path from where you are). You"); - PM("aim by telling the computer which rooms you want to throw through."); - PM("If the path is incorrect (presumes a nonexistent connection) the "); - PM("pie moves at random."); - - PM(" If a pie hits the superhack, you win. If it hits you, you lose!\n"); - - (void) fputs("", stdout); - IGNORE(fgets(inp, sizeof(inp), stdin)); - (void) putchar('\n'); - - PM("Hazards:"); - PM(" Starlets --- two rooms contain lonely, beautiful women. If you"); - PM("enter these, you will become fascinated and forget your mission as"); - PM("you engage in futile efforts to pick one up. You weenie."); - PM(" Droids --- two rooms are guarded by experimental AI security "); - PM("droids. If you enter either, the droid will grab you and hustle"); - PM("you off to somewhere else, at random."); - PM(" Lusers --- two rooms contain hungry lusers. If you blunder into"); - PM("either, they will eat one of your pies."); - PM(" Superhack --- the superhack is not bothered by hazards (the"); - PM("lusers are in awe of him, he's programmed the droids to ignore him,"); - PM("and he has no sex life). Usually he is hacking. Two things can"); - PM("interrupt him; you throwing a pie or you entering his room.\n"); - PM(" On an interrupt, the superhack moves (3/4 chance) or stays where"); - PM("he is (1/4 chance). After that, if he is where you are, he flames"); - PM("you and you lose!\n"); - - (void) fputs("", stdout); - (void) fgets(inp, sizeof(inp), stdin); - (void) putchar('\n'); - - PM("Warnings:"); - PM(" When you are one room away from the superhack or a hazard,"); - PM("the computer says:"); - PM(" superhack: \"I smell a superhack!\""); - PM(" security droid: \"Droids nearby!\""); - PM(" starlet: \"I smell perfume!\""); - PM(" luser: \"Lusers nearby!\""); - - PM("If you take too long finding the superhack, hazards may move. You"); - PM("will get a warning when this happens.\n"); - - PM("Commands:"); - PM(" Available commands are:\n"); - PM(" ? --- print long instructions."); - PM(" m --- move to room with given number."); - PM(" t --- throw through given rooms."); +#define PM(x) puts(x); + +void print_instructions() { + PM("Welcome to `Hunt the Superhack'\n") + + PM(" The superhack lives on the 9th floor of 45 Technology Square " + "in"); + PM("Cambridge, Massachusetts. Your mission is to throw a pie in his " + "face.\n"); + + PM(" First, you'll have to find him. A botched experiment by an " + "MIT"); + PM("physics group has regularized the floor's topology, so that each"); + PM("room has exits to three other rooms. (Look at a dodecahedron to"); + PM("see how this works --- if you don't know what a dodecahedron is,"); + PM("ask someone.)\n"); + + PM("You:"); + PM(" Each turn you may move to an adjacent room or throw a pie. If"); + PM("you run out of pies, you lose. Each pie can pass through up to"); + PM("five rooms (connected by a continuous path from where you are). " + "You"); + PM("aim by telling the computer which rooms you want to throw " + "through."); + PM("If the path is incorrect (presumes a nonexistent connection) the "); + PM("pie moves at random."); + + PM(" If a pie hits the superhack, you win. If it hits you, you " + "lose!\n"); + + (void)fputs("", stdout); + IGNORE(fgets(inp, sizeof(inp), stdin)); + (void)putchar('\n'); + + PM("Hazards:"); + PM(" Starlets --- two rooms contain lonely, beautiful women. If " + "you"); + PM("enter these, you will become fascinated and forget your mission " + "as"); + PM("you engage in futile efforts to pick one up. You weenie."); + PM(" Droids --- two rooms are guarded by experimental AI security "); + PM("droids. If you enter either, the droid will grab you and hustle"); + PM("you off to somewhere else, at random."); + PM(" Lusers --- two rooms contain hungry lusers. If you blunder " + "into"); + PM("either, they will eat one of your pies."); + PM(" Superhack --- the superhack is not bothered by hazards (the"); + PM("lusers are in awe of him, he's programmed the droids to ignore " + "him,"); + PM("and he has no sex life). Usually he is hacking. Two things can"); + PM("interrupt him; you throwing a pie or you entering his room.\n"); + PM(" On an interrupt, the superhack moves (3/4 chance) or stays " + "where"); + PM("he is (1/4 chance). After that, if he is where you are, he " + "flames"); + PM("you and you lose!\n"); + + (void)fputs("", stdout); + (void)fgets(inp, sizeof(inp), stdin); + (void)putchar('\n'); + + PM("Warnings:"); + PM(" When you are one room away from the superhack or a hazard,"); + PM("the computer says:"); + PM(" superhack: \"I smell a superhack!\""); + PM(" security droid: \"Droids nearby!\""); + PM(" starlet: \"I smell perfume!\""); + PM(" luser: \"Lusers nearby!\""); + + PM("If you take too long finding the superhack, hazards may move. " + "You"); + PM("will get a warning when this happens.\n"); + + PM("Commands:"); + PM(" Available commands are:\n"); + PM(" ? --- print long instructions."); + PM(" m --- move to room with given number."); + PM(" t --- throw through given rooms."); #ifdef DEBUG - PM(" d --- dump hazard locations."); + PM(" d --- dump hazard locations."); #endif /* DEBUG */ - PM("\nThe list of room numbers after t must be space-separated. Anything"); - PM("other than one of these commands displays a short help message."); + PM("\nThe list of room numbers after t must be space-separated. " + "Anything"); + PM("other than one of these commands displays a short help message."); } -void move_hazard(where) -int where; +void move_hazard(where) int where; { - int newloc; - - retry: - newloc = FNA(); - for (j = 0; j < LOCS; j++) - if (loc[j] == newloc) - goto retry; + int newloc; + +retry: + newloc = FNA(); + for (j = 0; j < LOCS; j++) { + if (loc[j] == newloc) { + goto retry; + } + } - loc[where] = newloc; + loc[where] = newloc; } -void check_hazards() -{ - /* basic status report */ - (void) printf("You are in room %d. Exits lead to %d, %d, %d. You have %d pies left.\n", - loc[YOU]+1, - cave[loc[YOU]][0]+1, - cave[loc[YOU]][1]+1, - cave[loc[YOU]][2]+1, - pies); - - /* maybe it's migration time */ - if (FNA() == 0) - switch(2 + FNB()) - { - case STARLET1: - case STARLET2: - PM("Swish, swish, swish --- starlets are moving!"); - move_hazard(STARLET1); - move_hazard(STARLET2); - break; - - case DROID1: - case DROID2: - PM("Clank, clank, clank --- droids are moving!"); - move_hazard(DROID1); - move_hazard(DROID2); - break; - - case LUSER1: - case LUSER2: - PM("Grumble, grumble, grumble --- lusers are moving!"); - move_hazard(LUSER1); - move_hazard(LUSER2); - break; +void check_hazards() { + /* basic status report */ + (void)printf("You are in room %d. Exits lead to %d, %d, %d. You have " + "%d pies left.\n", + loc[YOU] + 1, cave[loc[YOU]][0] + 1, cave[loc[YOU]][1] + 1, + cave[loc[YOU]][2] + 1, pies); + + /* maybe it's migration time */ + if (FNA() == 0) + switch (2 + FNB()) { + case STARLET1: + case STARLET2: + PM("Swish, swish, swish --- starlets are moving!"); + move_hazard(STARLET1); + move_hazard(STARLET2); + break; + + case DROID1: + case DROID2: + PM("Clank, clank, clank --- droids are moving!"); + move_hazard(DROID1); + move_hazard(DROID2); + break; + + case LUSER1: + case LUSER2: + PM("Grumble, grumble, grumble --- lusers are moving!"); + move_hazard(LUSER1); + move_hazard(LUSER2); + break; + } + + /* display hazard warnings */ + for (k = 0; k < 3; k++) { + int room = cave[loc[YOU]][k]; + + if (room == loc[RMS]) { + (void)puts("I smell a superhack!"); + } else if (room == loc[STARLET1] || room == loc[STARLET2]) { + (void)puts("I smell perfume!"); + } else if (room == loc[DROID1] || room == loc[DROID2]) { + (void)puts("Droids nearby!"); + } else if (room == loc[LUSER1] || room == loc[LUSER2]) { + (void)puts("Lusers nearby!"); + } } - - /* display hazard warnings */ - for (k = 0; k < 3; k++) - { - int room = cave[loc[YOU]][k]; - - if (room == loc[RMS]) - (void) puts("I smell a superhack!"); - else if (room == loc[STARLET1] || room == loc[STARLET2]) - (void) puts("I smell perfume!"); - else if (room == loc[DROID1] || room == loc[DROID2]) - (void) puts("Droids nearby!"); - else if (room == loc[LUSER1] || room == loc[LUSER2]) - (void) puts("Lusers nearby!"); - } } -void throw() -{ - extern void check_shot(), move_superhack(); - int j9; - - j9 = sscanf(inp + strcspn(inp, NUMBERS), "%d %d %d %d %d", - &path[0], &path[1], &path[2], &path[3], &path[4]); +void throw() { + extern void check_shot(), move_superhack(); + int j9; - if (j9 < 1) - { - PM("Sorry, I didn't see any room numbers after your throw command."); - return; - } + j9 = sscanf(inp + strcspn(inp, NUMBERS), "%d %d %d %d %d", &path[0], + &path[1], &path[2], &path[3], &path[4]); - for (k = 0; k < j9; k++) - if (k >= 2 && path[k] == path[k - 2]) - { - (void) puts("Pies can't fly that crookedly --- try again."); - return; + if (j9 < 1) { + PM("Sorry, I didn't see any room numbers after your throw " + "command."); + return; } - scratchloc = loc[YOU]; - - for (k = 0; k < j9; k++) - { - int k1; - - for (k1 = 0; k1 < 3; k1++) - { - if (cave[scratchloc][k1] == path[k]) - { - scratchloc = path[k]; - check_shot(); - if (finished != NOT) - return; - } - + for (k = 0; k < j9; k++) { + if (k >= 2 && path[k] == path[k - 2]) { + (void)puts( + "Pies can't fly that crookedly --- try again."); + return; + } } - scratchloc = cave[scratchloc][FNB()]; + scratchloc = loc[YOU]; - check_shot(); + for (k = 0; k < j9; k++) { + int k1; - } + for (k1 = 0; k1 < 3; k1++) { + if (cave[scratchloc][k1] == path[k]) { + scratchloc = path[k]; + check_shot(); + if (finished != NOT) { + return; + } + } + } - if (finished == NOT) - { - (void) puts("You missed."); + scratchloc = cave[scratchloc][FNB()]; - scratchloc = loc[YOU]; + check_shot(); + } - move_superhack(); + if (finished == NOT) { + (void)puts("You missed."); - if (--pies <= 0) - finished = LOSE; - } + scratchloc = loc[YOU]; -} + move_superhack(); -void check_shot() -{ - if (scratchloc == loc[RMS]) - { - (void) puts("Splat! You got the superhack! You win."); - finished = WIN; - } - - else if (scratchloc == loc[YOU]) - { - (void) puts("Ugh! The pie hit you! You lose."); - finished = LOSE; - } + if (--pies <= 0) { + finished = LOSE; + } + } } -void move_superhack() -{ - k = FNC(); +void check_shot() { + if (scratchloc == loc[RMS]) { + (void)puts("Splat! You got the superhack! You win."); + finished = WIN; + } - if (k < 3) - loc[RMS] = cave[loc[RMS]][k]; + else if (scratchloc == loc[YOU]) { + (void)puts("Ugh! The pie hit you! You lose."); + finished = LOSE; + } +} - if (loc[RMS] != loc[YOU]) - return; +void move_superhack() { + k = FNC(); + + if (k < 3) { + loc[RMS] = cave[loc[RMS]][k]; + } - (void) puts("The superhack flames you to a crisp. You lose!"); + if (loc[RMS] != loc[YOU]) { + return; + } - finished = LOSE; + (void)puts("The superhack flames you to a crisp. You lose!"); + finished = LOSE; } -void move() -{ - if (sscanf(inp + strcspn(inp, NUMBERS), "%d", &scratchloc) < 1) - { - PM("Sorry, I didn't see a room number after your `m' command."); - return; - } +void move() { + if (sscanf(inp + strcspn(inp, NUMBERS), "%d", &scratchloc) < 1) { + PM("Sorry, I didn't see a room number after your `m' command."); + return; + } - scratchloc--; + scratchloc--; - for (k = 0; k < 3; k++) - if (cave[loc[YOU]][k] == scratchloc) - goto goodmove; + for (k = 0; k < 3; k++) { + if (cave[loc[YOU]][k] == scratchloc) { + goto goodmove; + } + } - PM("You can't get there from here!"); - return; + PM("You can't get there from here!"); + return; goodmove: - loc[YOU] = scratchloc; - - if (scratchloc == loc[RMS]) - { - PM("Yow! You interrupted the superhack."); - move_superhack(); - } - else if (scratchloc == loc[STARLET1] || scratchloc == loc[STARLET2]) - { - PM("You begin to babble at an unimpressed starlet. You lose!"); - finished = LOSE; - } - else if (scratchloc == loc[DROID1] || scratchloc == loc[DROID2]) - { - PM("Zap --- security droid snatch. Elsewheresville for you!"); - scratchloc = loc[YOU] = FNA(); - goto goodmove; - } - else if (scratchloc == loc[LUSER1] || scratchloc == loc[LUSER2]) - { - PM("Munch --- lusers ate one of your pies!"); - pies--; - } + loc[YOU] = scratchloc; + + if (scratchloc == loc[RMS]) { + PM("Yow! You interrupted the superhack."); + move_superhack(); + } else if (scratchloc == loc[STARLET1] || scratchloc == loc[STARLET2]) { + PM("You begin to babble at an unimpressed starlet. You lose!"); + finished = LOSE; + } else if (scratchloc == loc[DROID1] || scratchloc == loc[DROID2]) { + PM("Zap --- security droid snatch. Elsewheresville for you!"); + scratchloc = loc[YOU] = FNA(); + goto goodmove; + } else if (scratchloc == loc[LUSER1] || scratchloc == loc[LUSER2]) { + PM("Munch --- lusers ate one of your pies!"); + pies--; + } } -int main(int argc, char *argv[]) -{ - if (argc >= 2 && strcmp(argv[1], "-s") == 0) - srand(atoi(argv[2])); - else - srand((int)time((long *) 0)); - - for (;;) - { - badlocs: - for (j = 0; j < LOCS; j++) - loc[j] = FNA(); - - for (j = 0; j < LOCS; j++) - for (k = 0; k < LOCS; k++) - if (j == k) - continue; - else if (loc[j] == loc[k]) - goto badlocs; - - (void) puts("Hunt the Superhack"); - - pies = 5; - scratchloc = loc[YOU]; - finished = NOT; - - while (finished == NOT) - { - int c; - - check_hazards(); - - c = getlet("Throw, move or help [t,m,?]"); +int main(int argc, char *argv[]) { + if (argc >= 2 && strcmp(argv[1], "-s") == 0) { + srand(atoi(argv[2])); + } else { + srand((int)time((long *)0)); + } - if (c == 't') - throw(); - else if (c == 'm') - move(); - else if (c == '?') - print_instructions(); + for (;;) { + badlocs: + for (j = 0; j < LOCS; j++) { + loc[j] = FNA(); + } + + for (j = 0; j < LOCS; j++) { + for (k = 0; k < LOCS; k++) { + if (j == k) { + continue; + } else if (loc[j] == loc[k]) { + goto badlocs; + } + } + } + + (void)puts("Hunt the Superhack"); + + pies = 5; + scratchloc = loc[YOU]; + finished = NOT; + + while (finished == NOT) { + int c; + + check_hazards(); + + c = getlet("Throw, move or help [t,m,?]"); + + if (c == 't') { + throw(); + } else if (c == 'm') { + move(); + } else if (c == '?') { + print_instructions(); + } #ifdef DEBUG - else if (c == 'd') - { - (void) printf("RMS is at %d, starlets at %d/%d, droids %d/%d, lusers %d/%d\n", - loc[RMS] + 1, - loc[STARLET1] + 1, loc[STARLET2] + 1, - loc[DROID1] + 1, loc[DROID2] + 1, - loc[LUSER1] + 1, loc[LUSER2] + 1); - } + else if (c == 'd') { + (void)printf("RMS is at %d, starlets at %d/%d, " + "droids %d/%d, lusers %d/%d\n", + loc[RMS] + 1, loc[STARLET1] + 1, + loc[STARLET2] + 1, loc[DROID1] + 1, + loc[DROID2] + 1, loc[LUSER1] + 1, + loc[LUSER2] + 1); + } #endif /* DEBUG */ - else - { - PM("Available commands are:\n"); - PM(" ? --- print long instructions."); - PM(" m --- move to room with given number."); - PM(" t --- throw through given rooms."); + else { + PM("Available commands are:\n"); + PM(" ? --- print long " + "instructions."); + PM(" m --- move to room with given " + "number."); + PM(" t --- throw through given " + "rooms."); #ifdef DEBUG - PM(" d --- dump hazard locations."); + PM(" d --- dump hazard locations."); #endif /* DEBUG */ - PM("The list of room numbers after t must be space-separated"); - } + PM("The list of room numbers after t must be " + "space-separated"); + } - (void) putchar('\n'); - } + (void)putchar('\n'); + } - if (getlet("Play again") != 'y') - { - PM("Happy hacking!"); - break; + if (getlet("Play again") != 'y') { + PM("Happy hacking!"); + break; + } } - } - return 0; + return 0; } /* superhack.c ends here */ diff --git a/wumpus.adoc b/wumpus.adoc new file mode 100644 index 0000000..fb98cae --- /dev/null +++ b/wumpus.adoc @@ -0,0 +1,28 @@ += wumpus(6) = +:doctype: manpage + +== NAME == +wumpus - the classic game of Hunt the Wumpus + +== SYNOPSIS == +galaxis + +[[description]] +== DESCRIPTION == + +wumpus is a faithful transcription of the 1974 game WUMPUS for the +Atari, the first computer game to maintain a consistent external map. +An article on the history of this classic game can be found at the +http://www.atariarchives.org/bcc1/showpage.php?page=247[Atari +Archives]. + +superhack is a structurally similar game with a different premise. + +[[authors]] +== AUTHORS == +The original Atari game was designed and written by Gregory Yob. This +version was cloned from the original BASIC sources by Eric S. Raymond +. See ESR's home page at +http://www.catb.org/~esr/ for updates and other resources. + +// end diff --git a/wumpus.c b/wumpus.c index b4d983c..3ce60c6 100644 --- a/wumpus.c +++ b/wumpus.c @@ -10,7 +10,7 @@ * >Below is the source code for _one_ (rather simple) Wumpus version, * >which I found in the PC-BLUE collection on SIMTEL20. I believe this is * >pretty much the same version that was published in David Ahl's "101 - * >Basic Computer Games" (or, possibly, in the sequel). + * >Basic Computer Games" (or, possibly, in the sequel). * * I have staunchly resisted the temptation to "improve" this game. It * is functionally identical to the BASIC version (source for which @@ -27,15 +27,16 @@ * limber up your fingers for a trip to nostalgia-land... * * SPDX-License-Identifier: BSD-2-Clause + * SPDX-FileCopyrightText: (C) Eric S. Raymond */ -#include #include +#include #include #include -#include -#include #include +#include +#include /* 5 REM *** HUNT THE WUMPUS *** */ @@ -43,20 +44,20 @@ static int path[5]; static int j, k, arrows, scratchloc; -static char inp[BUFSIZ]; /* common input buffer */ - -#define YOU 0 -#define WUMPUS 1 -#define PIT1 2 -#define PIT2 3 -#define BATS1 4 -#define BATS2 5 -#define LOCS 6 -static int loc[LOCS], save[LOCS]; /* locations */ - -#define NOT 0 -#define WIN 1 -#define LOSE -1 +static char inp[BUFSIZ]; /* common input buffer */ + +#define YOU 0 +#define WUMPUS 1 +#define PIT1 2 +#define PIT2 3 +#define BATS1 4 +#define BATS2 5 +#define LOCS 6 +static int loc[LOCS], save[LOCS]; /* locations */ + +#define NOT 0 +#define WIN 1 +#define LOSE -1 static int finished; /* 80 REM *** SET UP CAVE (DODECAHEDRAL NODE LIST) *** */ @@ -70,587 +71,622 @@ static int finished; /* 120 DATA 5,7,15,6,8,17,1,7,9,8,10,18,2,9,11 */ /* 125 DATA 10,12,19,3,11,13,12,14,20,4,13,15,6,14,16 */ /* 130 DATA 15,17,20,7,16,18,9,17,19,11,18,20,13,16,19 */ -static int cave[20][3] = -{ - {1,4,7}, - {0,2,9}, - {1,3,11}, - {2,4,13}, - {0,3,5}, - {4,6,14}, - {5,7,16}, - {0,6,8}, - {7,9,17}, - {1,8,10}, - {9,11,18}, - {2,10,12}, - {11,13,19}, - {3,12,14}, - {5,13,15}, - {14,16,19}, - {6,15,17}, - {8,16,18}, - {10,17,19}, - {12,15,18}, +static int cave[20][3] = { + {1, 4, 7}, {0, 2, 9}, {1, 3, 11}, {2, 4, 13}, {0, 3, 5}, + {4, 6, 14}, {5, 7, 16}, {0, 6, 8}, {7, 9, 17}, {1, 8, 10}, + {9, 11, 18}, {2, 10, 12}, {11, 13, 19}, {3, 12, 14}, {5, 13, 15}, + {14, 16, 19}, {6, 15, 17}, {8, 16, 18}, {10, 17, 19}, {12, 15, 18}, }; /* 135 DEF FNA(X)=INT(20*RND(1))+1 */ -#define FNA() (rand() % 20) +#define FNA() (rand() % 20) /* 140 DEF FNB(X)=INT(3*RND(1))+1 */ -#define FNB() (rand() % 3) +#define FNB() (rand() % 3) /* 145 DEF FNC(X)=INT(4*RND(1))+1 */ -#define FNC() (rand() % 4) +#define FNC() (rand() % 4) int getnum(prompt) char *prompt; { - (void) printf("%s\n?", prompt); - if (fgets(inp, sizeof(inp), stdin)) - return(atoi(inp)); - else { - fputs("\n",stdout); - exit(1); - } + (void)printf("%s\n?", prompt); + if (fgets(inp, sizeof(inp), stdin)) + return (atoi(inp)); + else { + fputs("\n", stdout); + exit(1); + } } int getlet(prompt) char *prompt; { - (void) printf("%s\n?", prompt); - if (fgets(inp, sizeof(inp), stdin)) - return(toupper(inp[0])); - else { - fputs("\n",stdout); - exit(1); - } + (void)printf("%s\n?", prompt); + if (fgets(inp, sizeof(inp), stdin)) + return (toupper(inp[0])); + else { + fputs("\n", stdout); + exit(1); + } } -void print_instructions() -{ -/* 375 REM *** INSTRUCTIONS *** */ -/* 380 PRINT "WELCOME TO 'HUNT THE WUMPUS'" */ - puts("WELCOME TO 'HUNT THE WUMPUS'"); -/* 385 PRINT " THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM" */ - puts(" THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM"); -/* 390 PRINT "HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A" */ - puts("HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A"); -/* 395 PRINT "DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW" */ - puts("DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW"); -/* 400 PRINT "WHAT A DODECAHEDRON IS, ASK SOMEONE)" */ - puts("WHAT A DODECAHEDRON IS, ASK SOMEONE)"); -/* 405 PRINT */ - puts(""); -/* 410 PRINT " HAZARDS:" */ - puts(" HAZARDS:"); -/* 415 PRINT " BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM */ - puts(" BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM"); -/* 420 PRINT " IF YOU GO THERE, YOU FALL INTO THE PIT (& LOSE!)" */ - puts(" IF YOU GO THERE, YOU FALL INTO THE PIT (& LOSE!)"); -/* 425 PRINT " SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU" */ - puts(" SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU"); -/* 430 PRINT " GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER" */ - puts(" GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER"); -/* 435 PRINT " ROOM AT RANDOM. (WHICH MAY BE TROUBLESOME)" */ - puts(" ROOM AT RANDOM. (WHICH MAY BE TROUBLESOME)"); -/* 440 INPUT "TYPE AN E THEN RETURN ";W9 */ - (void) getlet("TYPE AN E THEN RETURN "); -/* 445 PRINT " WUMPUS:" */ - puts(" WUMPUS:"); -/* 450 PRINT " THE WUMPUS IS NOT BOTHERED BY HAZARDS (HE HAS SUCKER" */ - puts(" THE WUMPUS IS NOT BOTHERED BY HAZARDS (HE HAS SUCKER"); -/* 455 PRINT " FEET AND IS TOO BIG FOR A BAT TO LIFT). USUALLY" */ - puts(" FEET AND IS TOO BIG FOR A BAT TO LIFT). USUALLY"); -/* 460 PRINT " HE IS ASLEEP. TWO THINGS WAKE HIM UP: YOU SHOOTING AN" */ - puts(" HE IS ASLEEP. TWO THINGS WAKE HIM UP: YOU SHOOTING AN"); -/* 465 PRINT "ARROW OR YOU ENTERING HIS ROOM." */ - puts("ARROW OR YOU ENTERING HIS ROOM."); -/* 470 PRINT " IF THE WUMPUS WAKES HE MOVES (P=.75) ONE ROOM" */ - puts(" IF THE WUMPUS WAKES HE MOVES (P=.75) ONE ROOM"); -/* 475 PRINT " OR STAYS STILL (P=.25). AFTER THAT, IF HE IS WHERE YOU" */ - puts(" OR STAYS STILL (P=.25). AFTER THAT, IF HE IS WHERE YOU"); -/* 480 PRINT " ARE, HE EATS YOU UP AND YOU LOSE!" */ - puts(" ARE, HE EATS YOU UP AND YOU LOSE!"); -/* 485 PRINT */ - puts(""); -/* 490 PRINT " YOU:" */ - puts(" YOU:"); -/* 495 PRINT " EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW" */ - puts(" EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW"); -/* 500 PRINT " MOVING: YOU CAN MOVE ONE ROOM (THRU ONE TUNNEL)" */ - puts(" MOVING: YOU CAN MOVE ONE ROOM (THRU ONE TUNNEL)"); -/* 505 PRINT " ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT */ - puts(" ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT"); -/* 510 PRINT " EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING*/ - puts(" EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING"); -/* 515 PRINT " THE COMPUTER THE ROOM#S YOU WANT THE ARROW TO GO TO." */ - puts(" THE COMPUTER THE ROOM#S YOU WANT THE ARROW TO GO TO."); -/* 520 PRINT " IF THE ARROW CAN'T GO THAT WAY (IF NO TUNNEL) IT MOVES"*/ - puts(" IF THE ARROW CAN'T GO THAT WAY (IF NO TUNNEL) IT MOVES"); -/* 525 PRINT " AT RANDOM TO THE NEXT ROOM." */ - puts(" AT RANDOM TO THE NEXT ROOM."); -/* 530 PRINT " IF THE ARROW HITS THE WUMPUS, YOU WIN." */ - puts(" IF THE ARROW HITS THE WUMPUS, YOU WIN."); -/* 535 PRINT " IF THE ARROW HITS YOU, YOU LOSE." */ - puts(" IF THE ARROW HITS YOU, YOU LOSE."); -/* 540 INPUT "TYPE AN E THEN RETURN ";W9 */ - (void) getlet("TYPE AN E THEN RETURN "); -/* 545 PRINT " WARNINGS:" */ - puts(" WARNINGS:"); -/* 550 PRINT " WHEN YOU ARE ONE ROOM AWAY FROM A WUMPUS OR HAZARD," */ - puts(" WHEN YOU ARE ONE ROOM AWAY FROM A WUMPUS OR HAZARD,"); -/* 555 PRINT " THE COMPUTER SAYS:" */ - puts(" THE COMPUTER SAYS:"); -/* 560 PRINT " WUMPUS: 'I SMELL A WUMPUS'" */ - puts(" WUMPUS: 'I SMELL A WUMPUS'"); -/* 565 PRINT " BAT : 'BATS NEARBY'" */ - puts(" BAT : 'BATS NEARBY'"); -/* 570 PRINT " PIT : 'I FEEL A DRAFT'" */ - puts(" PIT : 'I FEEL A DRAFT'"); -/* 575 PRINT */ - puts(""); -/* 580 RETURN */ +void print_instructions() { + /* 375 REM *** INSTRUCTIONS *** */ + /* 380 PRINT "WELCOME TO 'HUNT THE WUMPUS'" */ + puts("WELCOME TO 'HUNT THE WUMPUS'"); + /* 385 PRINT " THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM" + */ + puts(" THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM"); + /* 390 PRINT "HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A" + */ + puts("HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A"); + /* 395 PRINT "DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW" + */ + puts("DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW"); + /* 400 PRINT "WHAT A DODECAHEDRON IS, ASK SOMEONE)" */ + puts("WHAT A DODECAHEDRON IS, ASK SOMEONE)"); + /* 405 PRINT */ + puts(""); + /* 410 PRINT " HAZARDS:" */ + puts(" HAZARDS:"); + /* 415 PRINT " BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM + */ + puts(" BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM"); + /* 420 PRINT " IF YOU GO THERE, YOU FALL INTO THE PIT (& LOSE!)" + */ + puts(" IF YOU GO THERE, YOU FALL INTO THE PIT (& LOSE!)"); + /* 425 PRINT " SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU" + */ + puts(" SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU"); + /* 430 PRINT " GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME + * OTHER" */ + puts(" GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER"); + /* 435 PRINT " ROOM AT RANDOM. (WHICH MAY BE TROUBLESOME)" + */ + puts(" ROOM AT RANDOM. (WHICH MAY BE TROUBLESOME)"); + /* 440 INPUT "TYPE AN E THEN RETURN ";W9 */ + (void)getlet("TYPE AN E THEN RETURN "); + /* 445 PRINT " WUMPUS:" */ + puts(" WUMPUS:"); + /* 450 PRINT " THE WUMPUS IS NOT BOTHERED BY HAZARDS (HE HAS SUCKER" + */ + puts(" THE WUMPUS IS NOT BOTHERED BY HAZARDS (HE HAS SUCKER"); + /* 455 PRINT " FEET AND IS TOO BIG FOR A BAT TO LIFT). USUALLY" + */ + puts(" FEET AND IS TOO BIG FOR A BAT TO LIFT). USUALLY"); + /* 460 PRINT " HE IS ASLEEP. TWO THINGS WAKE HIM UP: YOU SHOOTING AN" + */ + puts(" HE IS ASLEEP. TWO THINGS WAKE HIM UP: YOU SHOOTING AN"); + /* 465 PRINT "ARROW OR YOU ENTERING HIS ROOM." */ + puts("ARROW OR YOU ENTERING HIS ROOM."); + /* 470 PRINT " IF THE WUMPUS WAKES HE MOVES (P=.75) ONE ROOM" + */ + puts(" IF THE WUMPUS WAKES HE MOVES (P=.75) ONE ROOM"); + /* 475 PRINT " OR STAYS STILL (P=.25). AFTER THAT, IF HE IS WHERE YOU" + */ + puts(" OR STAYS STILL (P=.25). AFTER THAT, IF HE IS WHERE YOU"); + /* 480 PRINT " ARE, HE EATS YOU UP AND YOU LOSE!" */ + puts(" ARE, HE EATS YOU UP AND YOU LOSE!"); + /* 485 PRINT */ + puts(""); + /* 490 PRINT " YOU:" */ + puts(" YOU:"); + /* 495 PRINT " EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW" + */ + puts(" EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW"); + /* 500 PRINT " MOVING: YOU CAN MOVE ONE ROOM (THRU ONE TUNNEL)" + */ + puts(" MOVING: YOU CAN MOVE ONE ROOM (THRU ONE TUNNEL)"); + /* 505 PRINT " ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT + */ + puts(" ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT"); + /* 510 PRINT " EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY + * TELLING*/ + puts(" EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING"); + /* 515 PRINT " THE COMPUTER THE ROOM#S YOU WANT THE ARROW TO GO TO." + */ + puts(" THE COMPUTER THE ROOM#S YOU WANT THE ARROW TO GO TO."); + /* 520 PRINT " IF THE ARROW CAN'T GO THAT WAY (IF NO TUNNEL) IT + * MOVES"*/ + puts(" IF THE ARROW CAN'T GO THAT WAY (IF NO TUNNEL) IT MOVES"); + /* 525 PRINT " AT RANDOM TO THE NEXT ROOM." */ + puts(" AT RANDOM TO THE NEXT ROOM."); + /* 530 PRINT " IF THE ARROW HITS THE WUMPUS, YOU WIN." + */ + puts(" IF THE ARROW HITS THE WUMPUS, YOU WIN."); + /* 535 PRINT " IF THE ARROW HITS YOU, YOU LOSE." */ + puts(" IF THE ARROW HITS YOU, YOU LOSE."); + /* 540 INPUT "TYPE AN E THEN RETURN ";W9 */ + (void)getlet("TYPE AN E THEN RETURN "); + /* 545 PRINT " WARNINGS:" */ + puts(" WARNINGS:"); + /* 550 PRINT " WHEN YOU ARE ONE ROOM AWAY FROM A WUMPUS OR HAZARD," + */ + puts(" WHEN YOU ARE ONE ROOM AWAY FROM A WUMPUS OR HAZARD,"); + /* 555 PRINT " THE COMPUTER SAYS:" */ + puts(" THE COMPUTER SAYS:"); + /* 560 PRINT " WUMPUS: 'I SMELL A WUMPUS'" */ + puts(" WUMPUS: 'I SMELL A WUMPUS'"); + /* 565 PRINT " BAT : 'BATS NEARBY'" */ + puts(" BAT : 'BATS NEARBY'"); + /* 570 PRINT " PIT : 'I FEEL A DRAFT'" */ + puts(" PIT : 'I FEEL A DRAFT'"); + /* 575 PRINT */ + puts(""); + /* 580 RETURN */ } -void check_hazards() -{ - /* 585 REM *** PRINT LOCATION & HAZARD WARNINGS *** */ - /* 590 PRINT */ - (void) puts(""); - - /* 595 FOR J=2 TO 6 */ - /* 600 FOR K=1 TO 3 */ - /* 605 IF S(L(1),K)<>L(J) THEN 640 */ - /* 610 ON J-1 GOTO 615,625,625,635,635 */ - /* 615 PRINT "I SMELL A WUMPUS!" */ - /* 620 GOTO 640 */ - /* 625 PRINT "I FEEL A DRAFT" */ - /* 630 GOTO 640 */ - /* 635 PRINT "BATS NEARBY!" */ - /* 640 NEXT K */ - /* 645 NEXT J */ - for (k = 0; k < 3; k++) - { - int room = cave[loc[YOU]][k]; - - if (room == loc[WUMPUS]) - (void) puts("I SMELL A WUMPUS!"); - else if (room == loc[PIT1] || room == loc[PIT2]) - (void) puts("I FEEL A DRAFT"); - else if (room == loc[BATS1] || room == loc[BATS2]) - (void) puts("BATS NEARBY!"); - } - - /* 650 PRINT "YOU ARE IN ROOM "L(1) */ - (void) printf("YOU ARE IN ROOM %d\n", loc[YOU]+1); - - /* 655 PRINT "TUNNELS LEAD TO "S(L,1);S(L,2);S(L,3) */ - (void) printf("TUNNELS LEAD TO %d %d %d\n", - cave[loc[YOU]][0]+1, cave[loc[YOU]][1]+1, cave[loc[YOU]][2]+1); - - /* 660 PRINT */ - (void) puts(""); - - /* 665 RETURN */ +void check_hazards() { + /* 585 REM *** PRINT LOCATION & HAZARD WARNINGS *** */ + /* 590 PRINT */ + (void)puts(""); + + /* 595 FOR J=2 TO 6 */ + /* 600 FOR K=1 TO 3 */ + /* 605 IF S(L(1),K)<>L(J) THEN 640 */ + /* 610 ON J-1 GOTO 615,625,625,635,635 */ + /* 615 PRINT "I SMELL A WUMPUS!" */ + /* 620 GOTO 640 */ + /* 625 PRINT "I FEEL A DRAFT" */ + /* 630 GOTO 640 */ + /* 635 PRINT "BATS NEARBY!" */ + /* 640 NEXT K */ + /* 645 NEXT J */ + for (j = WUMPUS; j < LOCS; j++) { + for (k = 0; k < 3; k++) { + if (cave[loc[YOU]][k] != loc[j]) { + continue; + } + + if (j == WUMPUS) { + (void)puts("I SMELL A WUMPUS!"); + } else if (j == PIT1 || j == PIT2) { + (void)puts("I FEEL A DRAFT"); + } else if (j == BATS1 || j == BATS2) { + (void)puts("BATS NEARBY!"); + } + } + } + + /* 650 PRINT "YOU ARE IN ROOM "L(1) */ + (void)printf("YOU ARE IN ROOM %d\n", loc[YOU] + 1); + + /* 655 PRINT "TUNNELS LEAD TO "S(L,1);S(L,2);S(L,3) */ + (void)printf("TUNNELS LEAD TO %d %d %d\n", cave[loc[YOU]][0] + 1, + cave[loc[YOU]][1] + 1, cave[loc[YOU]][2] + 1); + + /* 660 PRINT */ + (void)puts(""); + + /* 665 RETURN */ } -int move_or_shoot() -{ - int c; +int move_or_shoot() { + int c; - /* 670 REM *** CHOOSE OPTION *** */ + /* 670 REM *** CHOOSE OPTION *** */ badin: - /* 675 PRINT "SHOOT OR MOVE (S-M)"; */ - /* 680 INPUT I$ */ - c = getlet("SHOOT OR MOVE (S-M)"); - - /* 685 IF I$<>"S" THEN 700 */ - /* 690 O=1 */ - /* 695 RETURN */ - /* 700 IF I$<>"M" THEN 675 */ - /* 705 O=2 */ - /* 710 RETURN */ - if (c == 'S') - return(1); - else if (c == 'M') - return(0); - else - goto badin; + /* 675 PRINT "SHOOT OR MOVE (S-M)"; */ + /* 680 INPUT I$ */ + c = getlet("SHOOT OR MOVE (S-M)"); + + /* 685 IF I$<>"S" THEN 700 */ + /* 690 O=1 */ + /* 695 RETURN */ + /* 700 IF I$<>"M" THEN 675 */ + /* 705 O=2 */ + /* 710 RETURN */ + if (c == 'S') { + return (1); + } else if (c == 'M') { + return (0); + } else { + goto badin; + } } +void shoot() { + extern void check_shot(), move_wumpus(); + int j9; + /* 715 REM *** ARROW ROUTINE *** */ + /* 720 F=0 */ + finished = NOT; -void shoot() -{ - extern void check_shot(), move_wumpus(); - int j9; + /* 725 REM *** PATH OF ARROW *** */ +badrange: + /* 735 PRINT "NO. OF ROOMS (1-5)"; */ + /* 740 INPUT J9 */ + j9 = getnum("NO. OF ROOMS (1-5)"); + + /* 745 IF J9<1 THEN 735 */ + /* 750 IF J9>5 THEN 735 */ + if (j9 < 1 || j9 > 5) { + goto badrange; + } - /* 715 REM *** ARROW ROUTINE *** */ - /* 720 F=0 */ - finished = NOT; + /* 755 FOR K=1 TO J9 */ + for (k = 0; k < j9; k++) { + /* 760 PRINT "ROOM #"; */ + /* 765 INPUT P(K) */ + path[k] = getnum("ROOM #") - 1; - /* 725 REM *** PATH OF ARROW *** */ -badrange: - /* 735 PRINT "NO. OF ROOMS (1-5)"; */ - /* 740 INPUT J9 */ - j9 = getnum("NO. OF ROOMS (1-5)"); - - /* 745 IF J9<1 THEN 735 */ - /* 750 IF J9>5 THEN 735 */ - if (j9 < 1 || j9 > 5) - goto badrange; - - /* 755 FOR K=1 TO J9 */ - for (k = 0; k < j9; k++) - { - /* 760 PRINT "ROOM #"; */ - /* 765 INPUT P(K) */ - path[k] = getnum("ROOM #") - 1; - - /* 770 IF K<=2 THEN 790 */ - if (k <= 1) - continue; - - /* 775 IF P(K)<>P(K-2) THEN 790 */ - if (path[k] != path[k - 2]) - continue; - - /* 780 PRINT "ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM" */ - (void) puts("ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM"); - /* 785 GOTO 760 */ - k--; - - /* 790 NEXT K */ - } - - /* 795 REM *** SHOOT ARROW *** */ - /* 800 L=L(1) */ - scratchloc = loc[YOU]; - - /* 805 FOR K=1 TO J9 */ - for (k = 0; k < j9; k++) - { - int k1; - - /* 810 FOR K1=1 TO 3 */ - for (k1 = 0; k1 < 3; k1++) - { - /* 815 IF S(L,K1)=P(K) THEN 895 */ - if (cave[scratchloc][k1] == path[k]) - { - /* - * This is the only bit of the translation I'm not sure - * about. It requires the trajectory of the arrow to - * be a path. Without it, all rooms on the trajectory - * would be required by the above to be adjacent to the - * player, making for a trivial game --- just move to where - * you smell a wumpus and shoot into all adjacent passages! - * However, I can't find an equivalent in the BASIC. - */ - scratchloc = path[k]; + /* 770 IF K<=2 THEN 790 */ + if (k <= 1) { + continue; + } - /* this simulates logic at 895 in the BASIC code */ - check_shot(); - if (finished != NOT) - return; - } + /* 775 IF P(K)<>P(K-2) THEN 790 */ + if (path[k] != path[k - 2]) { + continue; + } + + /* 780 PRINT "ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM" + */ + (void)puts("ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM"); + /* 785 GOTO 760 */ + k--; - /* 820 NEXT K1 */ + /* 790 NEXT K */ } - /* 825 REM *** NO TUNNEL FOR ARROW *** */ - /* 830 L=S(L,FNB(1)) */ - scratchloc = cave[scratchloc][FNB()]; + /* 795 REM *** SHOOT ARROW *** */ + /* 800 L=L(1) */ + scratchloc = loc[YOU]; + + /* 805 FOR K=1 TO J9 */ + for (k = 0; k < j9; k++) { + int k1; + +#ifdef DEBUG + (void)printf("Location is %d, looking for tunnel to room %d\n", + scratchloc + 1, path[k] + 1); +#endif + + /* 810 FOR K1=1 TO 3 */ + for (k1 = 0; k1 < 3; k1++) { + /* 815 IF S(L,K1)=P(K) THEN 895 */ + if (cave[scratchloc][k1] == path[k]) { + /* + * This is the only bit of the translation I'm + * not sure about. It requires the trajectory + * of the arrow to be a path. Without it, all + * rooms on the trajectory would be required by + * the above to be adjacent to the player, + * making for a trivial game --- just move to + * where you smell a wumpus and shoot into all + * adjacent passages! However, I can't find an + * equivalent in the BASIC. + */ + scratchloc = path[k]; + +#ifdef DEBUG + (void)printf("Found tunnel to room %d\n", + scratchloc + 1); +#endif + + /* this simulates logic at 895 in the BASIC code + */ + check_shot(); + if (finished != NOT) { + return; + } + goto nextpath; + } + /* 820 NEXT K1 */ + } + + /* 825 REM *** NO TUNNEL FOR ARROW *** */ + /* 830 L=S(L,FNB(1)) */ + scratchloc = cave[scratchloc][FNB()]; - /* 835 GOTO 900 */ - check_shot(); +#ifdef DEBUG + (void)printf("No tunnel for room %d, new location is %d\n", + path[k] + 1, scratchloc + 1); +#endif + + /* 835 GOTO 900 */ + check_shot(); + if (finished != NOT) { + return; + } /* 840 NEXT K */ - } + nextpath:; + } - if (finished == NOT) - { - /* 845 PRINT "MISSED" */ - (void) puts("MISSED"); + if (finished == NOT) { + /* 845 PRINT "MISSED" */ + (void)puts("MISSED"); - /* 850 L=L(1) */ - scratchloc = loc[YOU]; + /* 850 L=L(1) */ + scratchloc = loc[YOU]; - /* 855 REM *** MOVE WUMPUS *** */ - /* 860 GOSUB 935 */ - move_wumpus(); + /* 855 REM *** MOVE WUMPUS *** */ + /* 860 GOSUB 935 */ + move_wumpus(); - /* 865 REM *** AMMO CHECK *** */ - /* 870 A=A-1 */ - /* 875 IF A>0 THEN 885 */ - /* 880 F=-1 */ - if (--arrows <= 0) - finished = LOSE; - } + /* 865 REM *** AMMO CHECK *** */ + /* 870 A=A-1 */ + /* 875 IF A>0 THEN 885 */ + /* 880 F=-1 */ + if (--arrows <= 0) { + finished = LOSE; + } + } - /* 885 RETURN */ + /* 885 RETURN */ } -void check_shot() -{ - /* 890 REM *** SEE IF ARROW IS AT L(1) OR AT L(2) */ - /* 895 L=P(K) */ - - /* 900 IF L<>L(2) THEN 920 */ - /* 905 PRINT "AHA! YOU GOT THE WUMPUS!" */ - /* 910 F=1 */ - /* 915 RETURN */ - if (scratchloc == loc[WUMPUS]) - { - (void) puts("AHA! YOU GOT THE WUMPUS!"); - finished = WIN; - } - - /* 920 IF L<>L(1) THEN 840 */ - /* 925 PRINT "OUCH! ARROW GOT YOU!" */ - /* 930 GOTO 880 */ - else if (scratchloc == loc[YOU]) - { - (void) puts("OUCH! ARROW GOT YOU!"); - finished = LOSE; - } +void check_shot() { + /* 890 REM *** SEE IF ARROW IS AT L(1) OR AT L(2) */ + /* 895 L=P(K) */ + + /* 900 IF L<>L(2) THEN 920 */ + /* 905 PRINT "AHA! YOU GOT THE WUMPUS!" */ + /* 910 F=1 */ + /* 915 RETURN */ + if (scratchloc == loc[WUMPUS]) { + (void)puts("AHA! YOU GOT THE WUMPUS!"); + finished = WIN; + } + + /* 920 IF L<>L(1) THEN 840 */ + /* 925 PRINT "OUCH! ARROW GOT YOU!" */ + /* 930 GOTO 880 */ + else if (scratchloc == loc[YOU]) { + (void)puts("OUCH! ARROW GOT YOU!"); + finished = LOSE; + } } -void move_wumpus() -{ - /* 935 REM *** MOVE WUMPUS ROUTINE *** */ - /* 940 K=FNC(0) */ - k = FNC(); +void move_wumpus() { + /* 935 REM *** MOVE WUMPUS ROUTINE *** */ + /* 940 K=FNC(0) */ + k = FNC(); - /* 945 IF K=4 THEN 955 */ - /* 950 L(2)=S(L(2),K) */ - if (k < 3) - loc[WUMPUS] = cave[loc[WUMPUS]][k]; + /* 945 IF K=4 THEN 955 */ + /* 950 L(2)=S(L(2),K) */ + if (k < 3) { + loc[WUMPUS] = cave[loc[WUMPUS]][k]; + } - /* 955 IF L(2)<>L THEN 970 */ - if (loc[WUMPUS] != loc[YOU]) - return; +#ifdef DEBUG + (void)printf("Wumpus location is now room %d\n", loc[WUMPUS] + 1); +#endif - /* 960 PRINT "TSK TSK TSK - WUMPUS GOT YOU!" */ - (void) puts("TSK TSK TSK - WUMPUS GOT YOU!"); + /* 955 IF L(2)<>L THEN 970 */ + if (loc[WUMPUS] != loc[YOU]) { + return; + } - /* 965 F=-1 */ - finished = LOSE; + /* 960 PRINT "TSK TSK TSK - WUMPUS GOT YOU!" */ + (void)puts("TSK TSK TSK - WUMPUS GOT YOU!"); + + /* 965 F=-1 */ + finished = LOSE; - /* 970 RETURN */ + /* 970 RETURN */ } -void move() -{ - /* 975 REM *** MOVE ROUTINE *** */ - /* 980 F=0 */ - finished = NOT; +void move() { + /* 975 REM *** MOVE ROUTINE *** */ + /* 980 F=0 */ + finished = NOT; badmove: - /* 985 PRINT "WHERE TO"; */ - /* 990 INPUT L */ - scratchloc = getnum("WHERE TO"); - - /* 995 IF L<1 THEN 985 */ - /* 1000 IF L>20 THEN 985 */ - if (scratchloc < 1 || scratchloc > 20) - goto badmove; - scratchloc--; - - /* 1005 FOR K=1 TO 3 */ - for (k = 0; k < 3; k++) - { - /* 1010 REM *** CHECK IF LEGAL MOVE *** */ - /* 1015 IF S(L(1),K)=L THEN 1045 */ - if (cave[loc[YOU]][k] == scratchloc) - goto goodmove; - - /* 1020 NEXT K */ - } - - /* 1025 IF L=L(1) THEN 1045 */ - if (scratchloc != loc[YOU]) - { - /* 1030 PRINT "NOT POSSIBLE -"; */ - (void) puts("NOT POSSIBLE -"); - - /* 1035 GOTO 985 */ - goto badmove; - } + /* 985 PRINT "WHERE TO"; */ + /* 990 INPUT L */ + scratchloc = getnum("WHERE TO"); + + /* 995 IF L<1 THEN 985 */ + /* 1000 IF L>20 THEN 985 */ + if (scratchloc < 1 || scratchloc > 20) { + goto badmove; + } + scratchloc--; + + /* 1005 FOR K=1 TO 3 */ + for (k = 0; k < 3; k++) { + /* 1010 REM *** CHECK IF LEGAL MOVE *** */ + /* 1015 IF S(L(1),K)=L THEN 1045 */ + if (cave[loc[YOU]][k] == scratchloc) { + goto goodmove; + } + + /* 1020 NEXT K */ + } + + /* 1025 IF L=L(1) THEN 1045 */ + if (scratchloc != loc[YOU]) { + /* 1030 PRINT "NOT POSSIBLE -"; */ + (void)puts("NOT POSSIBLE -"); + + /* 1035 GOTO 985 */ + goto badmove; + } goodmove: - /* 1040 REM *** CHECK FOR HAZARDS *** */ - /* 1045 L(1)=L */ - loc[YOU] = scratchloc; - - if (scratchloc == loc[WUMPUS]) - { - /* 1050 REM *** WUMPUS *** */ - /* 1055 IF L<>L(2) THEN 1090 */ - /* 1060 PRINT "... OOPS! BUMPED A WUMPUS!" */ - /* 1065 REM *** MOVE WUMPUS *** */ - /* 1070 GOSUB 940 */ - /* 1075 IF F=0 THEN 1090 */ - /* 1080 RETURN */ - (void) puts("... OOPS! BUMPED A WUMPUS!"); - move_wumpus(); - } - else if (scratchloc == loc[PIT1] || scratchloc == loc[PIT2]) - { - /* 1085 REM *** PIT *** */ - /* 1090 IF L=L(3) THEN 1100 */ - /* 1095 IF L<>L(4) THEN 1120 */ - /* 1100 PRINT "YYYYIIIIEEEE . . . FELL IN PIT" */ - /* 1105 F=-1 */ - /* 1110 RETURN */ - (void) puts("YYYYIIIIEEEE . . . FELL IN PIT"); - finished = LOSE; - } - else if (scratchloc == loc[BATS1] || scratchloc == loc[BATS2]) - { - /* 1115 REM *** BATS *** */ - /* 1120 IF L=L(5) THEN 1130 */ - /* 1125 IF L<>L(6) THEN 1145 */ - /* 1130 PRINT "ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!" */ - /* 1135 L=FNA(1) */ - /* 1140 GOTO 1045 */ - /* 1145 RETURN */ - /* 1150 END */ - (void) puts("ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!"); - scratchloc = loc[YOU] = FNA(); - goto goodmove; - } + /* 1040 REM *** CHECK FOR HAZARDS *** */ + /* 1045 L(1)=L */ + loc[YOU] = scratchloc; + + if (scratchloc == loc[WUMPUS]) { + /* 1050 REM *** WUMPUS *** */ + /* 1055 IF L<>L(2) THEN 1090 */ + /* 1060 PRINT "... OOPS! BUMPED A WUMPUS!" */ + /* 1065 REM *** MOVE WUMPUS *** */ + /* 1070 GOSUB 940 */ + /* 1075 IF F=0 THEN 1090 */ + /* 1080 RETURN */ + (void)puts("... OOPS! BUMPED A WUMPUS!"); + move_wumpus(); + if (finished < 0) { + return; + } + /* Fall through since Wumpus could have been in a pit or bat + * room */ + } + if (scratchloc == loc[PIT1] || scratchloc == loc[PIT2]) { + /* 1085 REM *** PIT *** */ + /* 1090 IF L=L(3) THEN 1100 */ + /* 1095 IF L<>L(4) THEN 1120 */ + /* 1100 PRINT "YYYYIIIIEEEE . . . FELL IN PIT" */ + /* 1105 F=-1 */ + /* 1110 RETURN */ + (void)puts("YYYYIIIIEEEE . . . FELL IN PIT"); + finished = LOSE; + return; + } + if (scratchloc == loc[BATS1] || scratchloc == loc[BATS2]) { + /* 1115 REM *** BATS *** */ + /* 1120 IF L=L(5) THEN 1130 */ + /* 1125 IF L<>L(6) THEN 1145 */ + /* 1130 PRINT "ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!" + */ + /* 1135 L=FNA(1) */ + /* 1140 GOTO 1045 */ + /* 1145 RETURN */ + /* 1150 END */ + (void)puts("ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!"); + scratchloc = loc[YOU] = FNA(); + goto goodmove; + } } int main(argc, argv) int argc; char *argv[]; { - int c; - - if (argc >= 2 && strcmp(argv[1], "-s") == 0) - srand(atoi(argv[2])); - else - srand((int)time((long *) 0)); - - /* 15 PRINT "INSTRUCTIONS (Y-N)"; */ - /* 20 INPUT I$ */ - c = getlet("INSTRUCTIONS (Y-N)"); - - /* 25 IF I$="N" THEN 35 */ - /* 30 GOSUB 375 */ - /* 35 GOTO 80 */ - if (c == 'Y') - print_instructions(); - - /* 150 REM *** LOCATE L ARRAY ITEMS *** */ - /* 155 REM *** 1-YOU, 2-WUMPUS, 3&4-PITS, 5&6-BATS *** */ - /* 160 DIM L(6) */ - /* 165 DIM M(6) */ + int c; + + if (argc >= 2 && strcmp(argv[1], "-s") == 0) { + srand(atoi(argv[2])); + } else { + srand((int)time((long *)0)); + } + + /* 15 PRINT "INSTRUCTIONS (Y-N)"; */ + /* 20 INPUT I$ */ + c = getlet("INSTRUCTIONS (Y-N)"); + + /* 25 IF I$="N" THEN 35 */ + /* 30 GOSUB 375 */ + /* 35 GOTO 80 */ + if (c == 'Y') + print_instructions(); + + /* 150 REM *** LOCATE L ARRAY ITEMS *** */ + /* 155 REM *** 1-YOU, 2-WUMPUS, 3&4-PITS, 5&6-BATS *** */ + /* 160 DIM L(6) */ + /* 165 DIM M(6) */ badlocs: - /* 170 FOR J=1 TO 6 */ - /* 175 L(J)=FNA(0) */ - /* 180 M(J)=L(J) */ - /* 185 NEXT J */ - for (j = 0; j < LOCS; j++) - loc[j] = save[j] = FNA(); - - /* 190 REM *** CHECK FOR CROSSOVERS (IE L(1)=L(2), ETC) *** */ - /* 195 FOR J=1 TO 6 */ - /* 200 FOR K=1 TO 6 */ - /* 205 IF J=K THEN 215 */ - /* 210 IF L(J)=L(K) THEN 170 */ - /* 215 NEXT K */ - /* 220 NEXT J */ - for (j = 0; j < LOCS; j++) - for (k = 0; k < LOCS; k++) - if (j == k) - continue; - else if (loc[j] == loc[k]) - goto badlocs; + /* 170 FOR J=1 TO 6 */ + /* 175 L(J)=FNA(0) */ + /* 180 M(J)=L(J) */ + /* 185 NEXT J */ + for (j = 0; j < LOCS; j++) { + loc[j] = save[j] = FNA(); + } + + /* 190 REM *** CHECK FOR CROSSOVERS (IE L(1)=L(2), ETC) *** + */ + /* 195 FOR J=1 TO 6 */ + /* 200 FOR K=1 TO 6 */ + /* 205 IF J=K THEN 215 */ + /* 210 IF L(J)=L(K) THEN 170 */ + /* 215 NEXT K */ + /* 220 NEXT J */ + for (j = 0; j < LOCS; j++) { + for (k = 0; k < LOCS; k++) { + if (j == k) { + continue; + } else if (loc[j] == loc[k]) { + goto badlocs; + } + } + } - /* 225 REM *** SET NO. OF ARROWS *** */ -newgame: - /* 230 A=5 */ - /* 235 L=L(1) */ - arrows = 5; - scratchloc = loc[YOU]; + /* 225 REM *** SET NO. OF ARROWS *** */ +newgame: + /* 230 A=5 */ + /* 235 L=L(1) */ + arrows = 5; + scratchloc = loc[YOU]; - /* 240 REM *** RUN THE GAME *** */ - /* 245 PRINT "HUNT THE WUMPUS" */ - (void) puts("HUNT THE WUMPUS"); + /* 240 REM *** RUN THE GAME *** */ + /* 245 PRINT "HUNT THE WUMPUS" */ + (void)puts("HUNT THE WUMPUS"); #ifdef DEBUG - (void) printf("Wumpus is at %d, pits at %d & %d, bats at %d & %d\n", - loc[WUMPUS]+1, - loc[PIT1]+1, loc[PIT2]+1, - loc[BATS1]+1, loc[BATS2]+1); + (void)printf("Wumpus is at %d, pits at %d & %d, bats at %d & %d\n", + loc[WUMPUS] + 1, loc[PIT1] + 1, loc[PIT2] + 1, + loc[BATS1] + 1, loc[BATS2] + 1); #endif -nextmove: - /* 250 REM *** HAZARD WARNING AND LOCATION *** */ - /* 255 GOSUB 585 */ - check_hazards(); - - /* 260 REM *** MOVE OR SHOOT *** */ - /* 265 GOSUB 670 */ - /* 270 ON O GOTO 280,300 */ - if (move_or_shoot()) - { - /* 275 REM *** SHOOT *** */ - /* 280 GOSUB 715 */ - shoot(); - - /* 285 IF F=0 THEN 255 */ - if (finished == NOT) - goto nextmove; - - /* 290 GOTO 310 */ - } - else - { - /* 295 REM *** MOVE *** */ - /* 300 GOSUB 975 */ - move(); - - /* 305 IF F=0 THEN 255 */ - if (finished == NOT) - goto nextmove; - } - - /* 310 IF F>0 THEN 335 */ - if (finished == LOSE) - { - /* 315 REM *** LOSE *** */ - /* 320 PRINT "HA HA HA - YOU LOSE!" */ - /* 325 GOTO 340 */ - (void) puts("HA HA HA - YOU LOSE!"); - } - else - { - /* 330 REM *** WIN *** */ - /* 335 PRINT "HEE HEE HEE - THE WUMPUS'LL GET YOU NEXT TIME!!" */ - (void) puts("HEE HEE HEE - THE WUMPUS'LL GET YOU NEXT TIME!!"); - } - - /* 340 FOR J=1 TO 6 */ - /* 345 L(J)=M(J) */ - /* 350 NEXT J */ - for (j = YOU; j < LOCS; j++) - loc[j] = save[j]; - - /* 355 PRINT "SAME SETUP (Y-N)"; */ - /* 360 INPUT I$ */ - c = getlet("SAME SETUP (Y-N)"); - - /* 365 IF I$<>"Y"THEN 170 */ - /* 370 GOTO 230 */ - if (c != 'Y') - goto badlocs; - else - goto newgame; +nextmove: + /* 250 REM *** HAZARD WARNING AND LOCATION *** */ + /* 255 GOSUB 585 */ + check_hazards(); + + /* 260 REM *** MOVE OR SHOOT *** */ + /* 265 GOSUB 670 */ + /* 270 ON O GOTO 280,300 */ + if (move_or_shoot()) { + /* 275 REM *** SHOOT *** */ + /* 280 GOSUB 715 */ + shoot(); + + /* 285 IF F=0 THEN 255 */ + if (finished == NOT) { + goto nextmove; + } + + /* 290 GOTO 310 */ + } else { + /* 295 REM *** MOVE *** */ + /* 300 GOSUB 975 */ + move(); + + /* 305 IF F=0 THEN 255 */ + if (finished == NOT) { + goto nextmove; + } + } + + /* 310 IF F>0 THEN 335 */ + if (finished == LOSE) { + /* 315 REM *** LOSE *** */ + /* 320 PRINT "HA HA HA - YOU LOSE!" */ + /* 325 GOTO 340 */ + (void)puts("HA HA HA - YOU LOSE!"); + } else { + /* 330 REM *** WIN *** */ + /* 335 PRINT "HEE HEE HEE - THE WUMPUS'LL GET YOU NEXT TIME!!" + */ + (void)puts("HEE HEE HEE - THE WUMPUS'LL GET YOU NEXT TIME!!"); + } + + /* 340 FOR J=1 TO 6 */ + /* 345 L(J)=M(J) */ + /* 350 NEXT J */ + for (j = YOU; j < LOCS; j++) { + loc[j] = save[j]; + } + + /* 355 PRINT "SAME SETUP (Y-N)"; */ + /* 360 INPUT I$ */ + c = getlet("SAME SETUP (Y-N)"); + + /* 365 IF I$<>"Y"THEN 170 */ + /* 370 GOTO 230 */ + if (c != 'Y') { + goto badlocs; + } else { + goto newgame; + } } /* wumpus.c ends here */ diff --git a/wumpus.xml b/wumpus.xml deleted file mode 100644 index e92aa2f..0000000 --- a/wumpus.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - -wumpus -6 -Sep 7 1992 -wumpus -wumpus -Games - - -wumpus -the classic game of Hunt the Wumpus - - - - - wumpus - - - superhack - - - - -DESCRIPTION - -wumpus is a faithful transcription of -the 1974 game WUMPUS for the Atari, the first computer game to -maintain a consistent external map. An article on the history of this -classic game can be found here. - -superhack is a structurally similar -game with a different premise. - - -AUTHORS -The original Atari game was designed and written by Gregory Yob. -This version was cloned from the original BASIC sources by Eric -S. Raymond esr@snark.thyrsus.com. See ESR's home page at -http://www.catb.org/~esr/ -for updates and other resources. - - -