One of the first computer games in the 1970's was an adventure game called "Hunt the Wumpus". In this game, you are forced to wander around a maze of caves, hunting the dreaded wumpus (or possibly more than one wumpi). You are armed only with hand grenades, which you can throw at a wumpus to kill it. The problem is that wumpi are both fierce and fast. If you ever wander into a cave that contains a wumpus, then that wumpus will attack and kill you before you even have a chance to throw a grenade. Your only hope is to throw the grenade into the cave from an adjacent cave. Fortunately, wumpi are rather odorous creatures, so you will be able to smell a wumpus when you are in an adjacent cave. Of course, you won't know which cave the wumpus is in (every cave is connected to three other caves), so you will have to guess when you throw your grenade.
The object of the game is to kill all of the wumpi before you run out of grenades (and without getting killed). As if this weren't hard enough, you don't know exactly how many wumpi there are, or how many grenades you have (you will have 4 grenades for every wumpus). Plus, there are other things to watch out for. Somewhere in the maze is a group of giant bats, which will pick you up and fly you to some random cave (but at least they will only drop you in an empty cave). There is also a bottomless pit which you must avoid. Luckily, there is some warning about these hazards: you will be able to hear the flapping wings of the bats and feel a draft coming from the pit when you are in an adjacent cave. Oh, and there are the Lost Caverns of the Wyrm, which are very difficult to get out of. Below is a sample execution of the game:
Your assignment is to develop and test two objects that will be used in the "Hunt the Wumpus" game. Then you will write a program that allows a user to interactively play the game as shown in the introduction.
As described above "Hunt the Wumpus" is played in a maze of caves. Given this the two objects you will be developing and testing are a WumpusCave and a WumpusMaze object.
The two classes you need to develop and test are WumpusCave.java and a WumpusMaze.java. These two classes are described in javaDoc form:
The WumpusCave Class
The WumpusCave object represents a cave within the maze. The cave must keep track of its name, what is contained in the cave (a wumpus, bats or a pit) and whether or not the cave has been visited. A WumpusCave is not concerned with what other caves it is connected too. It is just a cave, it knows what it's name is, what it's contents are and wheather or not it has been visitied, but that is all! You should write the methods in WumpusCave.java one by one and test them by writing WumpusCaveTest.java at the same time. Compile and run your tests as you complete each method. I suggest writing and testing the constructor and toString first. Then add each of the other methods, testing each one as you go along.
The WumpusMaze Class
The WumpusMaze object will keep track of all of the WumpusCave objects and will know how the caves are connected to each other. This object will also be responsible for placing wumpi, tossing grenades, tracking your location in the maze and several other important aspects of the game. You can download the file:
The WumpusMaze.java file contains some code to help you get started. You should save this file into your lab9 directory.
The caves.dat file
The structure of the maze for "Hunt the Wumpus" is contained in a file called caves.dat. This file must be read by the constructor for your WumpusMaze object and used to define the maze in which the game will be played. You should copy the file:
To understand what the contents of this file mean let's consider the first few lines:
This means that cave #0 is named "The Fountainhead". If the player moves through tunnel #1 they will enter cave #1 ("The Rumpus Room"). If the player moves through tunnel #2 they will enter cave #4 and following tunnel #3 will lead to cave #9.
Reading the caves.dat file
The WumpusMaze.java file you downloaded contains some code that will be helpful for reading the data in the caves.dat file. You are not expected to understand how this code works but you will need to know how to use the two private methods:
As an example of how you might use caveFileReadInt() in the WumpusMaze constructor, consider the following code:
Placing this code in the constructor of WumpusMaze will read the first 5 integers from the caves.dat file and place them into the variables. The next item in the file is a string, to read it see the caveFileReadLine() method below.
As an example of how you might use the caveFileReadLine() method in the WumpusMaze constructor, consider the following line of code:
If you were to place this line of code in the constructor of WumpusMaze (following the 5 calls to caveFileReadInt()) it will read the name "The Fountainhead" and place it in to the variable name.
Keeping Track of the Caves
As you read the data for each cave in the maze you will need to construct a new WumpusCave object for that cave. You will probably want to create an array of references to WumpusCave objects as instance data in WumpusMaze to keep track of the caves. This array should contain one element for each of the caves in the maze. I would suggest using the reference in the 0'th location of the array to refer to the WumpusCave object for cave #0 and so forth. In this way the WumpusCave object for a given cave can easily be found by using its cave number as the index for the array.
To test what you have done so far, I suggest adding a toString() method to the WumpusMaze class that simply prints out the name of each cave. Keep in mind that if you implemented WumpusCave correctly getName() will return "unknown" until a cave has been visited. So for testing purposes, your toString() method could visit every cave and then print its name.
Keeping Track of the Tunnels
As you read in the caves.dat file and create the WumpusCave objects for each cave you will also need to keep track of how the caves are interconnected by the tunnels. To do this I suggest creating a 2 dimensional array of integers as instance data in the WumpusMaze class. This array will need to be created in the constructor to have a row for every cave and 3 columns (one for each tunnel).
The row number of the array will represent the cave number and the column number will represent the tunnel number. With this arrangement the integer in row R and column C will be the number of the cave that is reached if the tunnel C is followed from the cave R. The first few rows of the array for the given caves.dat file would look as follows:
From the table it can be seen that from cave 0 (row 0) if tunnel 1 (column 0) is followed the player will end up in cave 1. Similarly, if the player were in cave 3 (row 3) and followed tunnel 3 (column 2) they would end up in cave 7.
To test the addition of the array for keeping track of the tunnels, I would suggest adding to the toString() method in WumpusMaze. When toString() prints out the name of a cave have it also print out the caves to which it is connected by the tunnels. You can then compare this output to the caves.dat file to check if your program is working.
Randomizing the Game
Once you have created maze and recorded all of the tunnels you will need to place the Wumpi, bats and pits throughout the maze. These items must be placed randomly so that the game will be different every time it is played. The constructor for the WumpusMaze class should:
When placing these items keep in mind that a cave may only contain one item. Also, the game should always start with the player in "The Fountainhead" so cave 0 should always begin empty.
To be sure that you have correctly placed these items you should add code to toString() that prints out the contents of each cave. Being able to display this information will also be invaluable when it comes time to test methods like smell(), listen() and feel().
Moving Around the Maze
The move(int theTunnel) method will handle everything associated with moving a player around the maze. It will update instance data that indicates which cave a player is currently in and if the player is still alive after the move. If the player moves into a cave containing a wumpus or pit then the the player will no longer be alive after that move. If the player moves into a cave containing bats then they should be transported to a random cave in the maze. This method should print informative and possibly funny messages when the player is killed or transported to another cave.
The toss(int theTunnel) method will handle everything associated with tossing a grenade. It will update instance data that indicates the number of grenades remaining and decrease the number of live wumpi if one is killed. This method must also move any wumpi that are scared but not killed by a grenade. Finally, the method must handle the situation in which a scared wumpus flees into the same room as the player and Chomps them to death! This method should print informative messages indicating if a wumpus has been killed or not and if the player has been Chomped.
Playing the Game
This is the easy part! Once your two classes are working writing the code to play the game is quite easy. The following pseudo code should give you a start: