CS 200 - Assignment 4

Due: Tuesday, October 23rd by 11:59 PM

Text Adventure

Your task is to write a simple text adventure game.

Text adventure games were an early form of computer game: the first one, the Colossal Cave Adventure, was written in the early 1970s.  (Computers capable of displaying graphics did not become widely available until the 1980s.)

Maps and Connections

The basic idea of a text adventure game is that it consists of a map that you explore.  A map is a collection of rooms that are connected to each other: each room has 4 possible connections to other rooms in the north, south, east, and west directions.  Each connection may lead to another room, or may not lead to any room.

Here is a simple 4-room map, where each room is shown as an integer from 0 to 3:

Room 0 connects to room 1 to the north and room 3 to the south.

Room 1 connects to room 0 to the south and room 2 to the west.

Room 2 connects to room 1 to the east.

Room 3 connects to room 0 to the north.

One way to represent a map is as a table.  Each row of the table lists the rooms reached via the north, south, east, and west directions.  A special value -1 represents a direction that does not lead to another room.  Here is the table representing the map above:

Room North South East West
0 1 3 -1 -1
1 -1 0 -1 2
2 -1 -1 1 -1
3 0 -1 -1 -1

As long as the rooms are numbered starting at 0, this table can be represented easily as a two-dimensional array:

The first dimension (index) of the array is the room number, corresponding to the yellow column.

The second dimension (index) is the direction. We can adopt the convention that north is 0, south is 1, east is 2, and west is 3.  Each row shown in the blue part of the table specifies---for one of the rooms of the map---which other rooms can be reached.

Global variables

You can define the array storing the map table as a global variable.  A global variable is one that is declared outside of any function.  As long as you declare your array before any functions that need to use it, it will be visible in each of those functions.

Global variables are usually a bad idea.  Because any function in the program can assign a new value to a global variable at any time, they can be difficult to use correctly.

However, for this program, making the map table array a global variable is a reasonable choice because once its elements have been assigned values, those values will not change.

In my implementation of this program, I declared the map table array like this:

int map[MAX_ROOMS][NUM_DIRECTIONS];

Note that I used constants to define the size of each dimension of the array (see "Constants" section below).

You will need to make sure that the elements of your room array are initialized appropriately.

Getting started

Download CS200_Assign4.zip.

If you have the Marmoset Add-in installed, you can import the zip file using File->Import....

If you do not have the Marmoset Add-in installed, create a new folder, extract the contents of the zip file into the folder, navigate into the folder using a file browser, and then double-click the solution file (CS200_Assign4.sln).

Add your code to the source file Advent.c.

If you are using Linux or Mac OS X, extract the zip file into a new folder.  In a terminal window, use the make command to compile the program and the ./Advent command to execute the program.

Your Task

Your task is to write a text adventure program that allows the user to move around a map, printing the appropriate room description each time a room is entered.  The commands nse, and w move the player north, south, east, and west, respectively.  The command l (that's a lower-case L) repeats the description of the current room.  The command q quits the program.

Your map should contain at least 4 rooms.

Here is an example run of my implementation, which uses the map described above.  The player starts in room 0.  (User input in bold red.)

You are standing at the end of a road before a small brick building.
Around you is a forest. A small stream flows out of the building and
down a gully.
> n
You have walked up a hill, still in the forest. The road slopes back
down the other side of the hill. There is a building in the distance.
> e
You can't go that way.
> w
The road, which approaches from the east, ends here amid the trees.
> e
You have walked up a hill, still in the forest. The road slopes back
down the other side of the hill. There is a building in the distance.
> s
You are standing at the end of a road before a small brick building.
Around you is a forest. A small stream flows out of the building and
down a gully.
> s
You are inside a building, a well house for a large spring.
> l
You are inside a building, a well house for a large spring.
> q
Bye!

Constants

Use named constants in your program as appropriate.  Here are the ones I used:

#define NORTH 0
#define SOUTH 1
#define EAST 2
#define WEST 3
#define MAX_ROOMS 50
#define NUM_DIRECTIONS 4

Functions

The best way to approach this assignment is through top-down design.  Come up with an overall algorithm, break it up into subproblems, and use functions to solve the subproblems.

Here are some of the functions I wrote and used in my implementation:

print_room_description - given a room number, it prints the description of that room

command_to_direction - given a direction command ('n', 's', 'e', or 'w') it translates the command into the corresponding direction constant (NORTH, SOUTH, EAST, or WEST).

get_next_room - given a room number and a direction number (NORTH, SOUTH, EAST, or WEST), return the number of the room reachable by travelling from the given room in the given direction.  This function returns -1 if there is no reachable room in that direction.

You can use similar functions in your program, or you may come up with a different way of dividing the overall problem into subproblems.

Grading Criteria

80% of your grade will be based on whether or not the program functions correctly when it is run, as specified in the "Your task" section above.

20% of your grade will be based on your programming style.  To earn full credit, make sure that your code is indented properly, that you choose meaningful variable and function names, and that you use functions to break down the overall task into manageable subproblems.

Extra Credit

The basic game isn't terribly interesting.  Here are some ways you can improve it for extra credit:

  1. More interesting map: add additional rooms to the map.

  2. Objects: Implement support for one or more objects, e.g., a lamp, weapon, etc.  When the player enters a room with an object in it, the program should print a message like "There is a lamp here.".  The player can pick up the object with the p command (pick up) and drop the object with the d command (drop).  If you choose to support multiple objects, the p and d commands may need to prompt the user which object he/she wants to pick up or drop.

  3. Monster: Implement a monster.  The monster moves randomly from room to room (you can use the rand function to generate random numbers.)  If the player and the monster are in the same room, the player can use the f command (fight) to fight the monster.

  4. Goal.  Allow the player to "win".  Winning could involve, for example, finding each object and defeating the monster.

If you implement extra credit features, please add a comment at the top of the source file explaining which features you implemented.

Submitting

If you have the Marmoset Add-in installed, you can submitonline automatically by using the Tools->Submit... menu item.  Just type in your Marmoset username and password and click Submit.  After a few seconds, you should see a dialog box informing you whether or not the submission was uploaded successfully.  If successful, the dialog will look like this:


If you do not have the Marmoset Add-in installed, or if the automatic online submission does not work, create a zip file containing your entire project and manually upload it to the Marmoset server.  (See the submission instructions for details.)