Implementing Hunt the Wumpus in C

Original Wumpus artwork
In last week’s Lesson, I described the history and gameplay for the classic text mode game, Hunt the Wumpus. The task of coding the game took considerably longer than writing the blog post.

As with most of my larger projects, I started with the basics and then added functions to integrate and debug. The entire process took me several hours of coding. About 40 percent of the time was spent working out the kinks and stress-testing.

For implementations of Wumpus I’ve seen in other languages, the 20-chamber maze is hard-coded, with the rooms’ relationships and connections preset. It’s not a grid, so a matrix can’t be used. And it’s not linear, so a simple array doesn’t suffice. Still, I used an array, but one with an algorithm to access the three rooms.

The way my labyrinth array works is to have adjacent elements represent left-room and right-room choices. The algorithm wraps element 19 back to element 0 and vice-versa. The third room, in the “backward” direction, offsets 10 places in the array. With this arrangement, no matter where the player moves, reversing direction takes him back to the previous room, as illustrated in Figure 1.

Animated Illustration

Figure 1. How the hunter character moves three ways through the array.

(An underlying strategy of the game is that it’s possible to maneuver around the wumpus to determine his position and, therefore, launch an arrow in the proper room to win.)

Originally, the array was composed of structures to represent the rooms. Each structure contained links to the adjacent rooms as well as members that described whether a pit, bat, or wumpus was in the room. This approach became cumbersome as I implemented the code, so I opted instead for a straight integer array.

Each room in the array holds a value representing its contents. These are defined as enumerated constants:

enum { EMPTY,WUMPUS,BAT,PIT };

The player’s position in the array is tracked separately. In fact, the player is implemented as a structure:

struct hunter {
    int position,arrows,alive,won;
} player;

Member position represents the player’s location (element number) in the array; arrows are the number of arrows left in the quiver; alive and won are TRUE/FALSE values depending on gameplay.

The main() function contains these elements:

  • Initialization. The randomizer is seeded. Array labyrinth[] is initialized with all empty rooms. The player’s structure is filled: position=0 (traditional), arrows=5, alive=TRUE, and won=FALSE. The two bats, two pits, and wumpus are set in various rooms in a manner that ensures no two objects occupy the same room.
  • Message. A welcome/about message is output describing gameplay.
  • Main Loop. An endless while loop controls the action. If the player structure’s alive member is FALSE or won member is TRUE, the loop stops, game over. Otherwise, a description generated based on the contents of the surrounding rooms. User input is prompted.
  • Command Interpretation. A switch-case structure evaluates the first letter of input. The player can choose to move right, left, or back. They can choose to fire an arrow right, left, or back. They can prompt for a help message. They can quit.
  • Denouement. If the player quits, loses, or wins, appropriate text is output after the main loop is exited. A final message says “Game Over.”

Of course, the details are far more complex, including various checks to ensure that bizarre input is dealt with and other specifics that hamper all code design. I cover these details in next week’s Lesson. For now, you can click here to view my code on GitHub.

2 thoughts on “Implementing Hunt the Wumpus in C

  1. Your animation looks like two Turing Machines! Your previous post got me thinking about the underlying data structure and if I were to implement this I think I would go with a graph (as in graph theory).

Leave a Reply