Computer Science 132
Introduction To Computing II

Dickinson College
Spring Semester 2001
Grant Braught

Lab #9 - Hunt The Wumpus

Introduction

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:

> java WumpusHunt HUNT THE WUMPUS: Your mission is to explore the maze of caves and destroy all of the wumpi (without getting yourself killed). To move to an adjacent cave, enter 'M' and the tunnel number. To toss a grenade into a cave, enter 'T' and the tunnel number. You are currently in The Fountainhead (1) unknown (2) unknown (3) unknown What do you want to do? m 2 You are currently in The Silver Mirror (1) The Fountainhead (2) unknown (3) unknown What do you want to do? m 3 You are currently in Shelob's Lair (1) The Silver Mirror (2) unknown (3) unknown What do you want to do? m 3 You are currently in The Lost Caverns of the Wyrm (1) unknown (2) unknown (3) unknown You smell a WUMPUS! What do you want to do? t 1 Missed, dagnabit! DANGER: Any nearby wumpi are on the move. A wumpus is coming toward you with big, gnarly teeth... CHOMP CHOMP CHOMP GAME OVER

Assignment

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 javaDoc documentation describes the public interface to these classes. It does not specify anything about the implementation details. You need to decide what private instance data is needed in each class and how to implement the public methods. Your solution must implement all of the methods described and they must behave as described. As you implement the classes think about how the game will eventually work and why a particular method would be designed to behave the way it does. You should also be developing a test program as you go along.

Programming Hints

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:

into your lab9directory.

To understand what the contents of this file mean let's consider the first few lines:

The first line of the file contains an integer that indicates how many caves are described in the file. So in the maze described by the given caves.dat file there are 20 caves. This first line will be followed by one line for each of the caves (20 more lines in this case.) Each of these lines contains exactly 4 integers and a string. To understand what the numbers and the string mean let's consider the first line of the file:

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:

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:

Column: 0 1 2 +---+---+---+ 0 | 1 | 4 | 9 | +---+---+---+ 1 | 0 | 2 | 5 | Row: +---+---+---+ 2 | 1 | 3 | 6 | +---+---+---+ 3 | 2 | 4 | 7 | +---+---+---+ ...

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.

Tossing Grenades

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:

Handing in the Lab