CSC 120A Homework Assignment 9 - Fall 2004

[Course home page]

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.

Introduction: "Hunt the Wumpus"

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.

 

Assignment

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.

 

Suggestions and Guidelines

The WumpusCave Class

This 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.

The WumpusMaze Class

The 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:

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.

Playing the Game

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.

 

Questions

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

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

Last modified: Thu Dec 2 09:45:43 EST 2004