////////////////////////////////////////////////////////////////////////////// // // _ _________ _________ _______ // |\ /||\ /|( ( /|\__ __/ \__ __/|\ /|( ____ \ // | ) ( || ) ( || \ ( | ) ( ) ( | ) ( || ( \/ // | (___) || | | || \ | | | | | | | (___) || (__ // | ___ || | | || (\ \) | | | | | | ___ || __) // | ( ) || | | || | \ | | | | | | ( ) || ( // | ) ( || (___) || ) \ | | | | | | ) ( || (____/\ // |/ \|(_______)|/ )_) )_( )_( |/ \|(_______/ // // _______ _______ _______ // |\ /||\ /|( )( ____ )|\ /|( ____ \ // | ) ( || ) ( || () () || ( )|| ) ( || ( \/ // | | _ | || | | || || || || (____)|| | | || (_____ // | |( )| || | | || |(_)| || _____)| | | |(_____ ) // | || || || | | || | | || ( | | | | ) | // | () () || (___) || ) ( || ) | (___) |/\____) | // (_______)(_______)|/ \||/ (_______)\_______) // // 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?"); } } }