I'm not sure why but it had to be done. Hunt the Wumpus is now in Second Life. The program was originally written somewhere around 1973 by Gregory Yob and is considered one of the earliest adventure games (it predates Colossal Cave Adventure). Although there have been many versions created after the original, this port recreates the original game (from the earliest version of the source code I could find). It is a command line based game where the player is in a network of connected rooms. The object of the game is to hunt down and kill the wumpus. To read the original description written by the man himself, go here:
http://www.atariarchives.org/bcc1/showpage.php?page=247
To use this script:
1. Create a new script in your inventory, copy/paste this code into it, and save.
2. Rez a new prim.
3. Drag and drop the script into the new prim.
4. Change the name of the prim to: Hunt the Wumpus v1.0
5. Take the prim to inventory.
After all of that, the object will be named "Hunt the Wumpus v1.0" in your inventory so you can find it. When it's rezzed though, it will be renamed to an empty string so that chatting with it looks nicer.
Usage of the program itself is simple and self descriptive.
Have fun!
--Hugsy
P.S. Gregory Yob died October 13, 2006 (two years ago today). May he rest in peace.
//////////////////////////////////////////////////////////////////////////////
//
// _ _________ _________ _______
// |\ /||\ /|( ( /|\__ __/ \__ __/|\ /|( ____ \
// | ) ( || ) ( || \ ( | ) ( ) ( | ) ( || ( \/
// | (___) || | | || \ | | | | | | | (___) || (__
// | ___ || | | || (\ \) | | | | | | ___ || __)
// | ( ) || | | || | \ | | | | | | ( ) || (
// | ) ( || (___) || ) \ | | | | | | ) ( || (____/\
// |/ \|(_______)|/ )_) )_( )_( |/ \|(_______/
//
// _______ _______ _______
// |\ /||\ /|( )( ____ )|\ /|( ____ \
// | ) ( || ) ( || () () || ( )|| ) ( || ( \/
// | | _ | || | | || || || || (____)|| | | || (_____
// | |( )| || | | || |(_)| || _____)| | | |(_____ )
// | || || || | | || | | || ( | | | | ) |
// | () () || (___) || ) ( || ) | (___) |/\____) |
// (_______)(_______)|/ \||/ (_______)\_______)
//
// Version 1.0
//
// October 13, 2007
//
// COPYRIGHT:
//
// "Hunt the Wumpus" (LSL Port)
// Copyright (C) 2007 Hugsy Penguin
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// ORIGINAL CONCEPT:
//
// By: Gregory Yob circa 1973
// Published By: People's Computer Company
// Published In: newsletter dated November 1973
//
// Republished:
//
// Magazine: Creative Computing
// Issue: September/October 1975
// Article: "Hunt the Wumpus"
// By: Gregory Yob
//
// "The Best of Creative Computing Volume 1"
// Edited by David H. Ahl
// 1976
// ISBN O-916688-01-1
//
/////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
// Globals
//---------------------------------------------------------------------------
integer gDEBUG = FALSE;
list gCave;
integer gLocPlayer;
integer gHoldPlayer;
integer gLocWumpus;
integer gHoldWumpus;
integer gLocPit1;
integer gHoldPit1;
integer gLocPit2;
integer gHoldPit2;
integer gLocBat1;
integer gHoldBat1;
integer gLocBat2;
integer gHoldBat2;
integer gNumArrows;
integer gStatus;
//
// Debug method(s)
//
DBGPrintLocs()
{
llSay(0, "gLocPlayer = " + (string)gLocPlayer);
llSay(0, "gLocWumpus = " + (string)gLocWumpus);
llSay(0, "gLocPit1 = " + (string)gLocPit1);
llSay(0, "gLocPit2 = " + (string)gLocPit2);
llSay(0, "gLocBat1 = " + (string)gLocBat1);
llSay(0, "gLocBat2 = " + (string)gLocBat2);
}
//
// Initialize the script.
//
Initialize()
{
llSetObjectName(""
;
//setup cave (dodecahedral node list)
gCave = [
2,5,8,
1,3,10,
2,4,12,
3,5,14,
1,4,6,
5,7,15,
6,8,17,
1,7,9,
8,10,18,
2,9,11,
10,12,19,
3,11,13,
12,14,20,
4,13,15,
6,14,16,
15,17,20,
7,16,18,
9,17,19,
11,18,20,
13,16,19];
SetupNewGame(FALSE);
}
SetupNewGame(integer restore)
{
gNumArrows = 5;
gStatus = 0;
if (restore == TRUE)
{
gLocPlayer = gHoldPlayer;
gLocWumpus = gHoldWumpus;
gLocPit1 = gHoldPit1;
gLocPit2 = gHoldPit2;
gLocBat1 = gHoldBat1;
gLocBat2 = gHoldBat2;
}
else
{
//player location
gLocPlayer = (integer)(llFrand(20) + 1);
//wumpus location
integer done = FALSE;
while (!done)
{
gLocWumpus = (integer)(llFrand(20) + 1);
if (gLocWumpus != gLocPlayer)
done = TRUE;
}
//pit 1 location
done = FALSE;
while (!done)
{
gLocPit1 = (integer)(llFrand(20) + 1);
if ((gLocPit1 != gLocPlayer) &&
(gLocPit1 != gLocWumpus))
{
done = TRUE;
}
}
//pit 2 location
done = FALSE;
while (!done)
{
gLocPit2 = (integer)(llFrand(20) + 1);
if ((gLocPit2 != gLocPlayer) &&
(gLocPit2 != gLocWumpus) &&
(gLocPit2 != gLocPit1))
{
done = TRUE;
}
}
//bat 1 location
done = FALSE;
while (!done)
{
gLocBat1 = (integer)(llFrand(20) + 1);
if ((gLocBat1!= gLocPlayer) &&
(gLocBat1!= gLocWumpus) &&
(gLocBat1!= gLocPit1) &&
(gLocBat1!= gLocPit2))
{
done = TRUE;
}
}
//bat 2 location
done = FALSE;
while (!done)
{
gLocBat2 = (integer)(llFrand(20) + 1);
if ((gLocBat2!= gLocPlayer) &&
(gLocBat2!= gLocWumpus) &&
(gLocBat2!= gLocPit1) &&
(gLocBat2!= gLocPit2) &&
(gLocBat2!= gLocBat1))
{
done = TRUE;
}
}
gHoldPlayer = gLocPlayer;
gHoldWumpus = gLocWumpus;
gHoldPit1 = gLocPit1;
gHoldPit2 = gLocPit2;
gHoldBat1 = gLocBat1;
gHoldBat2 = gLocBat2;
}
}
//
// Returns the room based on given values:
//
// x = room number (range: 1-20)
// y = adjacent room index (range: 1-3)
//
integer RoomAt(integer x, integer y)
{
x--;
y--;
integer index = (x * 3) + y;
return llList2Integer(gCave, index);
}
//
// Print player location and nearby hazards
//
PrintLocAndHaz()
{
if (gDEBUG == TRUE)
DBGPrintLocs();
integer i;
//check for wumpus
for (i = 1; i < 4; i++)
{
if (RoomAt(gLocPlayer, i) == gLocWumpus)
{
llSay(0, "I SMELL A WUMPUS!"
;
}
}
//check for pit 1
for (i = 1; i < 4; i++)
{
if (RoomAt(gLocPlayer, i) == gLocPit1)
{
llSay(0, "I FEEL A DRAFT"
;
}
}
//check for pit 2
for (i = 1; i < 4; i++)
{
if (RoomAt(gLocPlayer, i) == gLocPit2)
{
llSay(0, "I FEEL A DRAFT"
;
}
}
//check for bat 1
for (i = 1; i < 4; i++)
{
if (RoomAt(gLocPlayer, i) == gLocBat1)
{
llSay(0, "BATS NEARBY!"
;
}
}
//check for bat 2
for (i = 1; i < 4; i++)
{
if (RoomAt(gLocPlayer, i) == gLocBat2)
{
llSay(0, "BATS NEARBY!"
;
}
}
llSay(0, "YOU ARE IN ROOM " + (string)gLocPlayer);
llSay(0, "TUNNELS LEAD TO " + (string)RoomAt(gLocPlayer, 1)
+ " " + (string)RoomAt(gLocPlayer, 2)
+ " " + (string)RoomAt(gLocPlayer, 3));
}
integer MoveWumpus()
{
integer dir = (integer)(llFrand(4) + 1);
if (dir != 4)
{
gLocWumpus = RoomAt(gLocWumpus, dir);
}
if (gLocPlayer == gLocWumpus)
{
llSay(0, "TSK TSK TSK- WUMPUS GOT YOU!"
;
return -1;
}
return 0;
}
//---------------------------------------------------------------------------
// Globals for shooting
//---------------------------------------------------------------------------
integer gShootingNumRooms;
integer gShootingRoom1;
integer gShootingRoom2;
integer gShootingRoom3;
integer gShootingRoom4;
integer gShootingRoom5;
integer gShootingCurRoom;
SetShootingRoom(integer index, integer value)
{
if (index == 1) gShootingRoom1 = value;
if (index == 2) gShootingRoom2 = value;
if (index == 3) gShootingRoom3 = value;
if (index == 4) gShootingRoom4 = value;
if (index == 5) gShootingRoom5 = value;
}
integer GetShootingRoom(integer index)
{
if (index == 1) return gShootingRoom1;
if (index == 2) return gShootingRoom2;
if (index == 3) return gShootingRoom3;
if (index == 4) return gShootingRoom4;
if (index == 5) return gShootingRoom5;
return 0;
}
ShootArrow()
{
integer loc = gLocPlayer;
integer i;
integer j;
for (i = 1; i <= gShootingNumRooms; i++)
{
//determine which room to check next
integer validRoom = FALSE;
for (j = 1; j <= 3; j++)
{
if (RoomAt(loc, j) == GetShootingRoom(i))
{
validRoom = TRUE;
loc = GetShootingRoom(i);
}
}
if (!validRoom)
{
loc = RoomAt(loc, (integer)(llFrand(3) + 1));
}
//check the room for wumpus or player
if (loc == gLocWumpus)
{
llSay(0, "AHA! YOU GOT THE WUMPUS!"
;
gStatus = 1;
}
else if (loc == gLocPlayer)
{
llSay(0, "OUCH! ARROW GOT YOU!"
;
gStatus = -1;
}
//return if in win or lose state
if (gStatus != 0)
return;
}
llSay(0, "MISSED"
;
//move wumpus
gStatus = MoveWumpus();
if (gStatus != 0)
return;
//ammo check
gNumArrows--;
if (gNumArrows == 0)
gStatus = -1;
}
//---------------------------------------------------------------------------
// Globals for moving
//---------------------------------------------------------------------------
MoveTo(integer loc)
{
gLocPlayer = loc;
if (gLocPlayer == gLocWumpus)
{
llSay(0, "... OOPS! BUMPED A WUMPUS!"
;
gStatus = MoveWumpus();
}
else if ((gLocPlayer == gLocPit1) || (gLocPlayer == gLocPit2))
{
llSay(0, "YYYIIIIEEEE . . . FELL IN PIT"
;
gStatus = -1;
}
else if ((gLocPlayer == gLocBat1) || (gLocPlayer == gLocBat2))
{
llSay(0, "ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!"
;
MoveTo((integer)(llFrand(20) + 1));
}
}
//############################################################################
//
// GAME STATES
//
//############################################################################
//----------------------------------------------------------------------------
// state default
//----------------------------------------------------------------------------
default
{
state_entry()
{
Initialize();
state instructions;
}
on_rez(integer start_param)
{
Initialize();
state instructions;
}
}
//----------------------------------------------------------------------------
// state instructions
//----------------------------------------------------------------------------
state instructions
{
state_entry()
{
llSay(0, "INSTRUCTIONS (Y-N)?"
;
llListen(0, "", llGetOwner(), ""
;
}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
if (llToLower(message) != "n"
{
llSay(0, "WELCOME TO 'HUNT THE WUMPUS'"
;
llSay(0, " "
;
llSay(0, " THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM"
;
llSay(0, "HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A"
;
llSay(0, "DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW"
;
llSay(0, "WHAT A DODECAHEDRON IS, ASK SOMEONE)"
;
llSay(0, " "
;
llSay(0, " HAZARDS:"
;
llSay(0, " BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM"
;
llSay(0, " IF YOU GO THERE, YOU FALL INTO THE PIT (&LOSE!)"
;
llSay(0, " SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU"
;
llSay(0, " GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER"
;
llSay(0, " ROOM AT RANDOM. (WHICH MIGHT BE TROUBLESOME)"
;
llSay(0, " "
;
llSay(0, " WUMPUS:"
;
llSay(0, " THE WUMPUS IS NOT BOTHERED BY THE HAZARDS (HE HAS SUCKER"
;
llSay(0, " FEET AND IS TOO BIG FOR A BAT TO LIFT). USUALLY"
;
llSay(0, " HE IS ASLEEP. TWO THINGS WAKE HIM UP: YOUR ENTERING"
;
llSay(0, " HIS ROOM OR YOUR SHOOTING AN ARROW."
;
llSay(0, " IF THE WUMPUS WAKES, HE MOVES (P=.75) ONE ROOM"
;
llSay(0, " OR STAYS STILL (P=.25). AFTER THAT, IF HE IS WHERE YOU"
;
llSay(0, " ARE, HE EATS YOU UP (& YOU LOSE!)"
;
llSay(0, " "
;
llSay(0, " YOU:"
;
llSay(0, " EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW"
;
llSay(0, " MOVING: YOU CAN GO ONE ROOM (THRU ONE TUNNEL)"
;
llSay(0, " ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT."
;
llSay(0, " EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING"
;
llSay(0, " THE COMPUTER THE ROOMS YOU WANT THE ARROW TO GO TO."
;
llSay(0, " IF THE ARROW CAN'T GO THAT WAY(IE NO TUNNEL) IT MOVES"
;
llSay(0, " AT RANDOM TO THE NEXT ROOM."
;
llSay(0, " IF THE ARROW HITS THE WUMPUS, YOU WIN."
;
llSay(0, " IF THE ARROW HITS YOU, YOU LOSE."
;
llSay(0, " "
;
llSay(0, " WARNINGS:"
;
llSay(0, " WHEN YOU ARE ONE ROOM AWAY FROM WUMPUS OR HAZARD,"
;
llSay(0, " THE COMPUTER SAYS:"
;
llSay(0, " WUMPUS- 'I SMELL A WUMPUS'"
;
llSay(0, " BAT - 'BATS NEARBY'"
;
llSay(0, " PIT - 'I FEEL A DRAFT'"
;
llSay(0, " "
;
}
llSay(0, "HUNT THE WUMPUS"
;
llSay(0, " "
;
state run_game;
}
}
//----------------------------------------------------------------------------
// state run_game
//----------------------------------------------------------------------------
state run_game
{
state_entry()
{
PrintLocAndHaz();
llSay(0, "SHOOT OR MOVE (S-M)?"
;
llListen(0, "", llGetOwner(), ""
;
}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
if (llToLower(message) == "s"
{
state shooting_num_rooms;
}
else if (llToLower(message) == "m"
{
state moving_where_to;
}
else if (llToLower(message) == "debug"
{
gDEBUG = !gDEBUG;
llSay(0, "DEBUG MODE IS NOW " + (string)gDEBUG);
}
else
{
llSay(0, "SHOOT OR MOVE (S-M)?"
;
}
}
}
state end_game
{
state_entry()
{
if (gStatus == 1)
{
llSay(0, "HEE HEE HEE - THE WUMPUS'LL GETCHA NEXT TIME!!"
;
}
else if (gStatus == -1)
{
llSay(0, "HA HA HA - YOU LOSE!"
;
}
llSay(0, "SAME SET-UP (Y-N)?"
;
llListen(0, "", llGetOwner(), ""
;
}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
llSay(0, "HUNT THE WUMPUS"
;
llSay(0, " "
;
if (llToLower(message) != "y"
{
SetupNewGame(FALSE);
}
else
{
SetupNewGame(TRUE);
}
state run_game;
}
}
//############################################################################
//
// SHOOTING
//
//############################################################################
//----------------------------------------------------------------------------
// state shooting_num_rooms
//----------------------------------------------------------------------------
state shooting_num_rooms
{
state_entry()
{
llSay(0, "NO. OF ROOMS(1-5)?"
;
llListen(0, "", llGetOwner(), ""
;
}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
gShootingNumRooms = (integer)message;
if ((gShootingNumRooms < 1) || (gShootingNumRooms > 5))
{
llSay(0, "NO. OF ROOMS(1-5)?"
;
}
else
{
state shooting_get_rooms;
}
}
}
//----------------------------------------------------------------------------
// state shooting_get_rooms
//----------------------------------------------------------------------------
state shooting_get_rooms
{
state_entry()
{
gShootingCurRoom = 1;
llSay(0, "ROOM #?"
;
llListen(0, "", llGetOwner(), ""
;
}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
integer roomNum = (integer)message;
SetShootingRoom(gShootingCurRoom, roomNum);
if (gShootingCurRoom == gShootingNumRooms)
{
ShootArrow();
if (gStatus == 0)
{
state run_game;
}
state end_game;
}
if (gShootingCurRoom > 2)
{
if (GetShootingRoom(gShootingCurRoom) ==
GetShootingRoom(gShootingCurRoom - 2))
{
llSay(0, "ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM"
;
}
}
gShootingCurRoom++;
llSay(0, "ROOM #?"
;
}
}
//############################################################################
//
// MOVING
//
//############################################################################
//----------------------------------------------------------------------------
// state moving_where_to
//----------------------------------------------------------------------------
state moving_where_to
{
state_entry()
{
llSay(0, "WHERE TO?"
;
llListen(0, "", llGetOwner(), ""
;
}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
integer loc = (integer)message;
if ((loc < 1) || (loc > 20))
{
llSay(0, "WHERE TO?"
;
}
else
{
integer i;
for (i = 1; i <=3; i++)
{
if (RoomAt(gLocPlayer, i) == loc)
{
MoveTo(loc);
if (gStatus == 0)
{
state run_game;
}
state end_game;
}
}
llSay(0, "NOT POSSIBLE -WHERE TO?"
;
}
}
}
//
// _ _________ _________ _______
// |\ /||\ /|( ( /|\__ __/ \__ __/|\ /|( ____ \
// | ) ( || ) ( || \ ( | ) ( ) ( | ) ( || ( \/
// | (___) || | | || \ | | | | | | | (___) || (__
// | ___ || | | || (\ \) | | | | | | ___ || __)
// | ( ) || | | || | \ | | | | | | ( ) || (
// | ) ( || (___) || ) \ | | | | | | ) ( || (____/\
// |/ \|(_______)|/ )_) )_( )_( |/ \|(_______/
//
// _______ _______ _______
// |\ /||\ /|( )( ____ )|\ /|( ____ \
// | ) ( || ) ( || () () || ( )|| ) ( || ( \/
// | | _ | || | | || || || || (____)|| | | || (_____
// | |( )| || | | || |(_)| || _____)| | | |(_____ )
// | || || || | | || | | || ( | | | | ) |
// | () () || (___) || ) ( || ) | (___) |/\____) |
// (_______)(_______)|/ \||/ (_______)\_______)
//
// Version 1.0
//
// October 13, 2007
//
// COPYRIGHT:
//
// "Hunt the Wumpus" (LSL Port)
// Copyright (C) 2007 Hugsy Penguin
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// ORIGINAL CONCEPT:
//
// By: Gregory Yob circa 1973
// Published By: People's Computer Company
// Published In: newsletter dated November 1973
//
// Republished:
//
// Magazine: Creative Computing
// Issue: September/October 1975
// Article: "Hunt the Wumpus"
// By: Gregory Yob
//
// "The Best of Creative Computing Volume 1"
// Edited by David H. Ahl
// 1976
// ISBN O-916688-01-1
//
/////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
// Globals
//---------------------------------------------------------------------------
integer gDEBUG = FALSE;
list gCave;
integer gLocPlayer;
integer gHoldPlayer;
integer gLocWumpus;
integer gHoldWumpus;
integer gLocPit1;
integer gHoldPit1;
integer gLocPit2;
integer gHoldPit2;
integer gLocBat1;
integer gHoldBat1;
integer gLocBat2;
integer gHoldBat2;
integer gNumArrows;
integer gStatus;
//
// Debug method(s)
//
DBGPrintLocs()
{
llSay(0, "gLocPlayer = " + (string)gLocPlayer);
llSay(0, "gLocWumpus = " + (string)gLocWumpus);
llSay(0, "gLocPit1 = " + (string)gLocPit1);
llSay(0, "gLocPit2 = " + (string)gLocPit2);
llSay(0, "gLocBat1 = " + (string)gLocBat1);
llSay(0, "gLocBat2 = " + (string)gLocBat2);
}
//
// Initialize the script.
//
Initialize()
{
llSetObjectName(""
;//setup cave (dodecahedral node list)
gCave = [
2,5,8,
1,3,10,
2,4,12,
3,5,14,
1,4,6,
5,7,15,
6,8,17,
1,7,9,
8,10,18,
2,9,11,
10,12,19,
3,11,13,
12,14,20,
4,13,15,
6,14,16,
15,17,20,
7,16,18,
9,17,19,
11,18,20,
13,16,19];
SetupNewGame(FALSE);
}
SetupNewGame(integer restore)
{
gNumArrows = 5;
gStatus = 0;
if (restore == TRUE)
{
gLocPlayer = gHoldPlayer;
gLocWumpus = gHoldWumpus;
gLocPit1 = gHoldPit1;
gLocPit2 = gHoldPit2;
gLocBat1 = gHoldBat1;
gLocBat2 = gHoldBat2;
}
else
{
//player location
gLocPlayer = (integer)(llFrand(20) + 1);
//wumpus location
integer done = FALSE;
while (!done)
{
gLocWumpus = (integer)(llFrand(20) + 1);
if (gLocWumpus != gLocPlayer)
done = TRUE;
}
//pit 1 location
done = FALSE;
while (!done)
{
gLocPit1 = (integer)(llFrand(20) + 1);
if ((gLocPit1 != gLocPlayer) &&
(gLocPit1 != gLocWumpus))
{
done = TRUE;
}
}
//pit 2 location
done = FALSE;
while (!done)
{
gLocPit2 = (integer)(llFrand(20) + 1);
if ((gLocPit2 != gLocPlayer) &&
(gLocPit2 != gLocWumpus) &&
(gLocPit2 != gLocPit1))
{
done = TRUE;
}
}
//bat 1 location
done = FALSE;
while (!done)
{
gLocBat1 = (integer)(llFrand(20) + 1);
if ((gLocBat1!= gLocPlayer) &&
(gLocBat1!= gLocWumpus) &&
(gLocBat1!= gLocPit1) &&
(gLocBat1!= gLocPit2))
{
done = TRUE;
}
}
//bat 2 location
done = FALSE;
while (!done)
{
gLocBat2 = (integer)(llFrand(20) + 1);
if ((gLocBat2!= gLocPlayer) &&
(gLocBat2!= gLocWumpus) &&
(gLocBat2!= gLocPit1) &&
(gLocBat2!= gLocPit2) &&
(gLocBat2!= gLocBat1))
{
done = TRUE;
}
}
gHoldPlayer = gLocPlayer;
gHoldWumpus = gLocWumpus;
gHoldPit1 = gLocPit1;
gHoldPit2 = gLocPit2;
gHoldBat1 = gLocBat1;
gHoldBat2 = gLocBat2;
}
}
//
// Returns the room based on given values:
//
// x = room number (range: 1-20)
// y = adjacent room index (range: 1-3)
//
integer RoomAt(integer x, integer y)
{
x--;
y--;
integer index = (x * 3) + y;
return llList2Integer(gCave, index);
}
//
// Print player location and nearby hazards
//
PrintLocAndHaz()
{
if (gDEBUG == TRUE)
DBGPrintLocs();
integer i;
//check for wumpus
for (i = 1; i < 4; i++)
{
if (RoomAt(gLocPlayer, i) == gLocWumpus)
{
llSay(0, "I SMELL A WUMPUS!"
;}
}
//check for pit 1
for (i = 1; i < 4; i++)
{
if (RoomAt(gLocPlayer, i) == gLocPit1)
{
llSay(0, "I FEEL A DRAFT"
;}
}
//check for pit 2
for (i = 1; i < 4; i++)
{
if (RoomAt(gLocPlayer, i) == gLocPit2)
{
llSay(0, "I FEEL A DRAFT"
;}
}
//check for bat 1
for (i = 1; i < 4; i++)
{
if (RoomAt(gLocPlayer, i) == gLocBat1)
{
llSay(0, "BATS NEARBY!"
;}
}
//check for bat 2
for (i = 1; i < 4; i++)
{
if (RoomAt(gLocPlayer, i) == gLocBat2)
{
llSay(0, "BATS NEARBY!"
;}
}
llSay(0, "YOU ARE IN ROOM " + (string)gLocPlayer);
llSay(0, "TUNNELS LEAD TO " + (string)RoomAt(gLocPlayer, 1)
+ " " + (string)RoomAt(gLocPlayer, 2)
+ " " + (string)RoomAt(gLocPlayer, 3));
}
integer MoveWumpus()
{
integer dir = (integer)(llFrand(4) + 1);
if (dir != 4)
{
gLocWumpus = RoomAt(gLocWumpus, dir);
}
if (gLocPlayer == gLocWumpus)
{
llSay(0, "TSK TSK TSK- WUMPUS GOT YOU!"
;return -1;
}
return 0;
}
//---------------------------------------------------------------------------
// Globals for shooting
//---------------------------------------------------------------------------
integer gShootingNumRooms;
integer gShootingRoom1;
integer gShootingRoom2;
integer gShootingRoom3;
integer gShootingRoom4;
integer gShootingRoom5;
integer gShootingCurRoom;
SetShootingRoom(integer index, integer value)
{
if (index == 1) gShootingRoom1 = value;
if (index == 2) gShootingRoom2 = value;
if (index == 3) gShootingRoom3 = value;
if (index == 4) gShootingRoom4 = value;
if (index == 5) gShootingRoom5 = value;
}
integer GetShootingRoom(integer index)
{
if (index == 1) return gShootingRoom1;
if (index == 2) return gShootingRoom2;
if (index == 3) return gShootingRoom3;
if (index == 4) return gShootingRoom4;
if (index == 5) return gShootingRoom5;
return 0;
}
ShootArrow()
{
integer loc = gLocPlayer;
integer i;
integer j;
for (i = 1; i <= gShootingNumRooms; i++)
{
//determine which room to check next
integer validRoom = FALSE;
for (j = 1; j <= 3; j++)
{
if (RoomAt(loc, j) == GetShootingRoom(i))
{
validRoom = TRUE;
loc = GetShootingRoom(i);
}
}
if (!validRoom)
{
loc = RoomAt(loc, (integer)(llFrand(3) + 1));
}
//check the room for wumpus or player
if (loc == gLocWumpus)
{
llSay(0, "AHA! YOU GOT THE WUMPUS!"
;gStatus = 1;
}
else if (loc == gLocPlayer)
{
llSay(0, "OUCH! ARROW GOT YOU!"
;gStatus = -1;
}
//return if in win or lose state
if (gStatus != 0)
return;
}
llSay(0, "MISSED"
;//move wumpus
gStatus = MoveWumpus();
if (gStatus != 0)
return;
//ammo check
gNumArrows--;
if (gNumArrows == 0)
gStatus = -1;
}
//---------------------------------------------------------------------------
// Globals for moving
//---------------------------------------------------------------------------
MoveTo(integer loc)
{
gLocPlayer = loc;
if (gLocPlayer == gLocWumpus)
{
llSay(0, "... OOPS! BUMPED A WUMPUS!"
;gStatus = MoveWumpus();
}
else if ((gLocPlayer == gLocPit1) || (gLocPlayer == gLocPit2))
{
llSay(0, "YYYIIIIEEEE . . . FELL IN PIT"
;gStatus = -1;
}
else if ((gLocPlayer == gLocBat1) || (gLocPlayer == gLocBat2))
{
llSay(0, "ZAP--SUPER BAT SNATCH! ELSEWHEREVILLE FOR YOU!"
;MoveTo((integer)(llFrand(20) + 1));
}
}
//############################################################################
//
// GAME STATES
//
//############################################################################
//----------------------------------------------------------------------------
// state default
//----------------------------------------------------------------------------
default
{
state_entry()
{
Initialize();
state instructions;
}
on_rez(integer start_param)
{
Initialize();
state instructions;
}
}
//----------------------------------------------------------------------------
// state instructions
//----------------------------------------------------------------------------
state instructions
{
state_entry()
{
llSay(0, "INSTRUCTIONS (Y-N)?"
;llListen(0, "", llGetOwner(), ""
;}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
if (llToLower(message) != "n"

{
llSay(0, "WELCOME TO 'HUNT THE WUMPUS'"
;llSay(0, " "
;llSay(0, " THE WUMPUS LIVES IN A CAVE OF 20 ROOMS. EACH ROOM"
;llSay(0, "HAS 3 TUNNELS LEADING TO OTHER ROOMS. (LOOK AT A"
;llSay(0, "DODECAHEDRON TO SEE HOW THIS WORKS-IF YOU DON'T KNOW"
;llSay(0, "WHAT A DODECAHEDRON IS, ASK SOMEONE)"
;llSay(0, " "
;llSay(0, " HAZARDS:"
;llSay(0, " BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM"
;llSay(0, " IF YOU GO THERE, YOU FALL INTO THE PIT (&LOSE!)"
;llSay(0, " SUPER BATS - TWO OTHER ROOMS HAVE SUPER BATS. IF YOU"
;llSay(0, " GO THERE, A BAT GRABS YOU AND TAKES YOU TO SOME OTHER"
;llSay(0, " ROOM AT RANDOM. (WHICH MIGHT BE TROUBLESOME)"
;llSay(0, " "
;llSay(0, " WUMPUS:"
;llSay(0, " THE WUMPUS IS NOT BOTHERED BY THE HAZARDS (HE HAS SUCKER"
;llSay(0, " FEET AND IS TOO BIG FOR A BAT TO LIFT). USUALLY"
;llSay(0, " HE IS ASLEEP. TWO THINGS WAKE HIM UP: YOUR ENTERING"
;llSay(0, " HIS ROOM OR YOUR SHOOTING AN ARROW."
;llSay(0, " IF THE WUMPUS WAKES, HE MOVES (P=.75) ONE ROOM"
;llSay(0, " OR STAYS STILL (P=.25). AFTER THAT, IF HE IS WHERE YOU"
;llSay(0, " ARE, HE EATS YOU UP (& YOU LOSE!)"
;llSay(0, " "
;llSay(0, " YOU:"
;llSay(0, " EACH TURN YOU MAY MOVE OR SHOOT A CROOKED ARROW"
;llSay(0, " MOVING: YOU CAN GO ONE ROOM (THRU ONE TUNNEL)"
;llSay(0, " ARROWS: YOU HAVE 5 ARROWS. YOU LOSE WHEN YOU RUN OUT."
;llSay(0, " EACH ARROW CAN GO FROM 1 TO 5 ROOMS. YOU AIM BY TELLING"
;llSay(0, " THE COMPUTER THE ROOMS YOU WANT THE ARROW TO GO TO."
;llSay(0, " IF THE ARROW CAN'T GO THAT WAY(IE NO TUNNEL) IT MOVES"
;llSay(0, " AT RANDOM TO THE NEXT ROOM."
;llSay(0, " IF THE ARROW HITS THE WUMPUS, YOU WIN."
;llSay(0, " IF THE ARROW HITS YOU, YOU LOSE."
;llSay(0, " "
;llSay(0, " WARNINGS:"
;llSay(0, " WHEN YOU ARE ONE ROOM AWAY FROM WUMPUS OR HAZARD,"
;llSay(0, " THE COMPUTER SAYS:"
;llSay(0, " WUMPUS- 'I SMELL A WUMPUS'"
;llSay(0, " BAT - 'BATS NEARBY'"
;llSay(0, " PIT - 'I FEEL A DRAFT'"
;llSay(0, " "
;}
llSay(0, "HUNT THE WUMPUS"
;llSay(0, " "
;state run_game;
}
}
//----------------------------------------------------------------------------
// state run_game
//----------------------------------------------------------------------------
state run_game
{
state_entry()
{
PrintLocAndHaz();
llSay(0, "SHOOT OR MOVE (S-M)?"
;llListen(0, "", llGetOwner(), ""
;}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
if (llToLower(message) == "s"

{
state shooting_num_rooms;
}
else if (llToLower(message) == "m"

{
state moving_where_to;
}
else if (llToLower(message) == "debug"

{
gDEBUG = !gDEBUG;
llSay(0, "DEBUG MODE IS NOW " + (string)gDEBUG);
}
else
{
llSay(0, "SHOOT OR MOVE (S-M)?"
;}
}
}
state end_game
{
state_entry()
{
if (gStatus == 1)
{
llSay(0, "HEE HEE HEE - THE WUMPUS'LL GETCHA NEXT TIME!!"
;}
else if (gStatus == -1)
{
llSay(0, "HA HA HA - YOU LOSE!"
;}
llSay(0, "SAME SET-UP (Y-N)?"
;llListen(0, "", llGetOwner(), ""
;}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
llSay(0, "HUNT THE WUMPUS"
;llSay(0, " "
;if (llToLower(message) != "y"

{
SetupNewGame(FALSE);
}
else
{
SetupNewGame(TRUE);
}
state run_game;
}
}
//############################################################################
//
// SHOOTING
//
//############################################################################
//----------------------------------------------------------------------------
// state shooting_num_rooms
//----------------------------------------------------------------------------
state shooting_num_rooms
{
state_entry()
{
llSay(0, "NO. OF ROOMS(1-5)?"
;llListen(0, "", llGetOwner(), ""
;}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
gShootingNumRooms = (integer)message;
if ((gShootingNumRooms < 1) || (gShootingNumRooms > 5))
{
llSay(0, "NO. OF ROOMS(1-5)?"
;}
else
{
state shooting_get_rooms;
}
}
}
//----------------------------------------------------------------------------
// state shooting_get_rooms
//----------------------------------------------------------------------------
state shooting_get_rooms
{
state_entry()
{
gShootingCurRoom = 1;
llSay(0, "ROOM #?"
;llListen(0, "", llGetOwner(), ""
;}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
integer roomNum = (integer)message;
SetShootingRoom(gShootingCurRoom, roomNum);
if (gShootingCurRoom == gShootingNumRooms)
{
ShootArrow();
if (gStatus == 0)
{
state run_game;
}
state end_game;
}
if (gShootingCurRoom > 2)
{
if (GetShootingRoom(gShootingCurRoom) ==
GetShootingRoom(gShootingCurRoom - 2))
{
llSay(0, "ARROWS AREN'T THAT CROOKED - TRY ANOTHER ROOM"
;}
}
gShootingCurRoom++;
llSay(0, "ROOM #?"
;}
}
//############################################################################
//
// MOVING
//
//############################################################################
//----------------------------------------------------------------------------
// state moving_where_to
//----------------------------------------------------------------------------
state moving_where_to
{
state_entry()
{
llSay(0, "WHERE TO?"
;llListen(0, "", llGetOwner(), ""
;}
on_rez(integer start_param)
{
state default;
}
listen(integer channel, string name, key id, string message)
{
integer loc = (integer)message;
if ((loc < 1) || (loc > 20))
{
llSay(0, "WHERE TO?"
;}
else
{
integer i;
for (i = 1; i <=3; i++)
{
if (RoomAt(gLocPlayer, i) == loc)
{
MoveTo(loc);
if (gStatus == 0)
{
state run_game;
}
state end_game;
}
}
llSay(0, "NOT POSSIBLE -WHERE TO?"
;}
}
}