Due: Friday, December 3, 2004
To ensure progress, you are to upload (at least) your completed WumpusCave.java
file to VikingWeb by 5PM on Tuesday, November 23.
You may work on this assignment in pairs (you do not have to). Each person in the pair will receive the same grade for the assignment.
One of the first computer games created in the 1970s was an adventure game called "Hunt the Wumpus." In this game, you wander through 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 where a wumpus is sitting, it will attack and kill you before you even have a chance to pull the grenade pin. Your only hope is to throw the grenade into a cave with a wumpus while you are in an adjacent cave. Fortunately, wumpi are somewhat 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 where to throw your grenades.
The object of the game is to kill all the wumpi before you run out of grenades (and before they kill you). As if this weren't hard enough, you don't know exactly how many wumpi there are, or how many grenades you've got (although you will have 4 grenades for every wumpus there is). Plus, there are other dangers lurking in the caves. Somewhere in the maze is a group of giant bats, which will pick you up and fly you around, dropping you in some random cave (but at least they will only drop you in an empty cave). Additionally, there is a bottomless pit in one of the caves, which you must avoid. Luckily, just like you can smell the wumpi, you will also be able to hear the flapping of the bats' wings from an adjacent cave, or feel a draft coming from the pit if it is in a nearby cave. Ahh, and there are the Lost Caverns of the Wyrm, which are painfully difficult to navigate if you get lost in them.
To see a sample run of the game click
here. Or, you may download the compiled Java files for my
solution here or get them from the M:\
drive on the computers in the lab. To run the game, change to
the appropriate directory using the command prompt and type
java WumpusGame
.
Your assignment is to develop two classes that represent the
objects in the game, and then write a main program that will
allow the user to interact with those objects to play the game
as described above in the introduction. To get you started,
based on the description in the introduction, you can see that
the game is played in a maze of caves. Thus, the two classes you
will develop are WumpusCave
and
WumpusMaze
. I am providing you with some skeleton
files of these classes for you to fill in. These files list some
public methods that you should implement with comments about
what each method does. You can define as many additional methods
and fields as you want. In addition, you should read the
programming suggestions section below.
WumpusCave
ClassThis class represents a single cave within the maze. This should be the first class definition you fill in. The skeleton file above includes a main method which you can use to test your implementation.
The cave must keep track of its name, what is contained within it (nothing, wumpus, bats, or pit) and whether or not the cave has been visited yet in the maze. Every cave also has three tunnels leading out of it (referred to as 0, 1, or 2). The cave should keep track of what other caves it is linked to along those tunnels. It can refer to other caves by their position in the array of caves in the complete maze (see below).
Write the methods in this class one by one and then uncomment
pieces of the main method to test them. Compile and run your
program as you complete each method. You should probably start
by implementing the constructor and then the
toString
method, for example.
WumpusMaze
ClassThe WumpusMaze
object keeps track of all the
WumpusCave
objects (in an array) and is responsible
for setting up the wumpi, keeping track of the player's current
cave, tossing grenades, moving the player, and other important
aspects of the game.
One of the first things this class must do is read in the caves.dat (click to download) file which describes the structure of the maze. Let's examine a few lines from the caves.dat file:
20 0 1 4 9 The Fountainhead 1 0 2 5 The Rumpus Room 2 1 3 6 Buford's Folly ... |
The first line indicates how many caves are listed in the remainder of the file. Then on each line following that is a description of the caves. Take the second line of the file above:
The Fountainhead
is the name of cave#0
This means cave #0 is named "The Fountainhead." If the player moves through tunnel 0 they will enter cave #1 ("The Rumpus Room"), and so on.
You may create a simpler caves.dat
file following
this format for your
use as you are initially developing and testing your program.
Reading the caves.dat
file: The
WumpusMaze
file you downloaded above contains some
methods that will be helpful for reading in the data from the
caves.dat file. You do not need to understand how the code works
but you need to know how to use the two methods:
private int caveFileReadInt()
will read and return
the next integer from the caves.dat
file. As an
example of how you might use this method in your constructor:
int numCaves = caveFileReadInt(); // read in the 20 int caveNum = caveFileReadInt(); // read in the 0 int adj0 = caveFileReadInt(); // read in the 1 int adj1 = caveFileReadInt(); // read in the 4 int adj2 = caveFileReadInt(); // read in the 9 |
This code will read the the first 5 integers from the file (going to the next line as necessary or skipping spaces). To read in the remainder of the line, use the method:
private String caveFileReadLine()
will read and
return the remainder of the current line of the
caves.dat
file. For example, after reading in the
five integers above, you would call this method to read in the
name "The Fountainhead".
Keeping track of the caves: As you read each line of
the data file, you will need to construct a new
WumpusCave
object appropriately. You will use an
array of references to WumpusCave
objects in the
WumpusMaze
class (it's already defined there for
you as a field) to keep track of the caves. Thus, cave #0 can be
stored at element 0 of the array, cave #1 at element 1, and so
on. This makes it easy to look up the caves by using their cave
number as an index into the array. Don't forget to use the
setConnection
method of the WumpusCave
objects to connect caves to adjacent caves along the appropriate
tunnels.
Randomizing the game: Once you have created and
initialized the array of caves and their connections, you will
need to place the wumpi, bats, and pit in the maze. They should
be randomly placed so that each time you play the game it is
different. The constructor for WumpusMaze
should:
When placing these items, keep in mind that a cave may only contain one item. Since you will be required to find random empty caves at several places in your program, it might be a good idea to add a method for this purpose.
Note: When the game begins, the player should start out in cave #0. Therefore, make sure that cave is always empty; don't put a wumpus, bats, or pit in it.
Your toString
method should return a complete
description of the caves, including their contents. This will be
an invaluable help when it comes to debugging or testing other
code as you're writing the game.
Moving around the maze: The move(int
tunnel)
method should handle everything associated with
moving a player around the maze. It should update the player's
current position, mark caves as visited, and decide if the player
is still alive after the move. If the player moves into a cave
containing a wumpus or pit, then the player should no longer be
alive after that move. If the player moves into a cave
containing bats, then they should be transported to a random
empty cave in the maze. This method should print informative and
possibly randomized, funny messages when the player is killed or
transported to another cave. You can be creative.
Tossing grenades: The tossGrenade(int
tunnel)
method handles everything associated with
tossing a grenade into an adjacent cave along the specified
tunnel. It should update the number of remaining grenades,
decrease the number of live wumpi, if one is killed. Also, even if
there are no wumpi in that cave, tossing a grenade should cause
any wumpi in adjacent caves that are scared to run around
(i.e. move to a random adjacent cave). Be sure to handle the
case where a scared
wumpus flees into the same room as the player and chomps them to
death! The method should print out informative messages about
what is going on. Again, you can be creative.
This is the easy part! Once you have the two main classes above
completed, you can create another class, for example,
WumpusGame.java
, which contains a main method that
puts everything into proper operation. Here's some pseudo-code
to give you an idea of how to start:
create a maze while (the player is alive && wumpi are alive) { display the player's current location and any smells, sounds, feelings read in the player's command for this turn move the player, toss the grenade, or quit } |
Game shell: This file [WumpusGame.java] contains a shell for the main method of the wumpus game. You can use this for your final program, modifying any parts of it as you wish.
Game play commands: At each turn, the player can type in a command like "M 0" to move along tunnel 0, or "T 1" to toss a grenade into the cave along tunnel 1, or "Q" to quit the game. Additionally, in my implementation, you can type the command "?" (a question mark) to get a printout of the entire state of the maze- useful again for debugging and testing.
Robustness: At this point, you must make sure your
program is fairly robust. That is, other than errors that may
occur when initially reading in the caves.dat
file
if it is incorrectly formatted, your program should not crash,
no matter what input the user types for commands. If the user
types in invalid commands or invalid tunnel numbers, you must
print out appropriate error messages.
As always, start working early on this assignment. If you need clarifications on any aspects please ask, by email or in person. If your question is general enough that its answer would benefit the entire class, I will modify this web page to indicate the clarification, as well as send email to everyone else.
Hand in a printout of all the commented Java program files that are necessary to make your program run correctly, and also submit them online through VikingWeb.
Acknowledgements: This assignment based on one prepared by Grant Braught, Dickinson College