CS 231: Assignment #9

Hunt the Wumpus

The final project uses a graph to represent a game map for the game Hunt the Wumpus, a classic RPG with very simple rules.

You have almost two weeks for this project, which will be due the last day of classes. You are free to change the rules of the game, so long as the game is still built around the idea of a graph specifiying the relationship between locations in the world.

Documentation for Java 1.6 is located at: Java 1.6 SE API

Problem Description

You are are a hunter exploring a cave and hunting the Wumpus, a large, smelly monster with a keen sense of hearing that lurks in the shadows.

You do not know how the cave is laid out initially—you know only how the rooms you have visited appear. As you carefully move from room to room in the cave, you will find clues that tell how far you are from the Wumpus: if the Wumpus is two or fewer rooms away, you will smell it.

If you wander into the room with the Wumpus, it will hear you and eat you. However, you are armed with a single arrow that you can fire from one room into an adjacent room where you suspect the Wumpus is hiding. If you fire your arrow correctly, the Wumpus will be slain. If you guess incorrectly, the Wumpus, alarmed by the sound of the arrow bouncing off the cave wall, will come eat you.

You have some freedom for how you choose to implement the details of this game. This guide is intentionally vague. If you want to find out more about the original game, visit wikipedia or download a nice version of the game from here.

For this project, the minimum you are implementing is a version of the game in which the only peril in the cave is the Wumpus and the hunter has a single arrow. For reference, I did not modify Landscape, LandscapeDisplay, or Cell in my implementation.


  1. Vertex class - use the vertex class to implement a room in the game. Have it extend the Cell class and implement the required abstract functions. Both updateState and isNeighbor need do nothing in the basic game. You probably want to add a new field to a vertex indicating whether it is visible or not.

    All rooms should initially be invisible except the one occupied by the hunter. When the hunter enters a room, it should become visible.

    The Vertex.draw() method should indicate several things about the room: it should show possible exits from the room and it should indicate whether the Wumpus is two rooms away or closer. Connected rooms do not need to be linked visually—if you place the rooms roughly on a grid, it will be easy to figure out where an exit leads.

    The following is a basic implementation that works well for a LandscapeDisplay scale of 64 or 100.

    public void draw(Graphics g, int x, int y, int scale)
        if (this.visible)
            int border = 2;
            int half = scale / 2;
            // draw rectangle for the walls of the cave
            if (this.cost <= 2)
                // wumpus is nearby
                // wumpus is not nearby
            g.drawRect(x + border, y + border, scale - 2*border, scale - 2 * border);
            // draw doorways as boxes
            if (this.edges.containsKey(Direction.North))
                g.fillRect(x + half - 4, y, 8, 12);
            if (this.edges.containsKey(Direction.South))
                g.fillRect(x + half - 4, y + scale - 12, 8, 12);
            if (this.edges.containsKey(Direction.West))
                g.fillRect(x, y + half - 4, 12, 8);
            if (this.edges.containsKey(Direction.East))
                g.fillRect(x + scale - 12, y + half - 4, 12, 8);
  2. Hunter class - the Hunter should extend the Cell class. It represents the player moving around the cave. The Hunter should store a reference to its current location, which should be a Vertex object. When the Hunter's current vertex changes, it should also change its location. The Hunter is always visible on the map.
  3. Wumpus class - the Wumpus should also extend the Cell class. It represents the Wumpus; in the default game the Wumpus does not move. The Wumpus should also have a reference to its home vertex. Unlike the Hunter, the Wumpus is only visible if it is killed by the Hunter or it eats the Hunter. Until then, it should not be drawn. Somehow, you need to pass in the visibility information to the Wumpus, including whether it should adopt a victorious pose or play dead.
  4. HuntTheWumpus class - this class is the main game controller class. It should contain at least: a Landscape, a LandscapeDisplay, a Graph, a Hunter, and a Wumpus. Other things you may want to define are a GameState enumerated type and a status field, as in the Elevator Simulation. (The ElevatorSimulation.java file from project 7 is a nice template.)

    The constructor needs to build the graph, insert the vertices, Hunter, and Wumpus into the Landscape, and add any other user interface elements. As part of the UI setup, it should add a KeyListener and an ActionListener to the display to listen for keystrokes and clicks (if you define a quit buttom). Look at the example code from last week for an example.

    The most important function in the game is the one listening for keystrokes. My implemention uses 'wasd' functionality for moving around the graph. If the player hits the space bar, it arms the Hunter's arrow. With an armed arrow, the next 'wasd' key hit determines which direction to shoot. Hitting the space bar without hitting one of 'wasd' disarms the arrow and enables the Hunter to move again.

    In the keyTyped method in the KeyListener, you can evaluate the effect of the user's actions, changing the state of the game, the position of the Hunter, the state of the Wumpus, or the position of the Wumpus, as needed. Most of the gameplay rules are executed there.

    You may also want to implement a very simple iterate function that simply calls scape.advance(), this.display.repaint(), and then sleeps for some amount of time.

    The overall simulation should be run from the main method of HuntTheWumpus. It should also be simple: create a HuntTheWumpus object, enter a while loop that calls Iterate so long as the GameState is not Quit, then call the dispose method on the display object after the while loop terminates.

The basic game should not take a significant effort to implement. Think carefully about extensions and how you want to make it more interesting.


  1. Add user interface elements like a replay button that resets the game.
  2. Have your game generate interesting random graphs so you can replay a different game every time. You probably still want to have rooms on a grid.
  3. Make the game visually interesting.
  4. Modify the rules so the game is more challenging. Think carefully about balancing the gameplay.
  5. Develop your own implementations of one or more of the data structures in the project (e.g. priority queue or hash map).

Writeup and Handin

Make your writeup for the project a wiki page in your personal space.

Your writeup should have a simple format.

Once you have written up your assignment, give the page the label:


You can give any page a label when you're editing it using the label field at the bottom of the page.

Do not put code on your writeup page or anywhere it can be publicly accessed. To hand in code, please put it on the Courses server in your private folder within the CS231 directory.