Skills you will practice

  • C++ terminal I/O
  • C++ Loops
  • C++ functions
  • File input
  • Arrays

Description

Your professor wants to give you something fun to implement. Therefore, you will be implementing an escape game. However, writing such a game is pretty meaty, so your professor will give you two assignments to make writing the game easier. For this first assignment, called Escape! (Part 1), you will read a game file that sets up the game world, then in the next assignment, cleverly called Escape! (Part 2), you will implement the game logic that actually plays the game.

The game is a very simple escape game. Your program will, when completed, read the game file that describes the state of the "world", describe the current situation to the user, and prompts the user for an action. The user will provide actions that change the state of the world. The user is attempting to "win" the game by escaping.

In particular, the world will be a set of rooms where the user can travel from room to room. The user is trying to find the "Exit" room. Moving from room to room requires going through doors that may or may not be locked. Unlocking a door requires using a key. Keys can be out in the open or hidden. To find a hidden key, the user must search the item in which the key is hidden. For example, a key could be hidden in a bookcase. Therefore, when a user searches the bookcase, the use will find the key.

First things first - Describing the world

In order to play the game, your program must understand the state of the world. The state of the world in defined in a file. Your program must read the file and store its data in arrays. Then your program can use the arrays to implement the game logic. However, for Escape! (Part 1), you will only implement reading the file.

Your code will read the file and store the information from the file in the following arrays:

  • char rooms[MAX_ROOMS][MAX_ROOM_NAME]
    • MAX_ROOMS = 50, MAX_ROOM_NAME = 21
    • The descriptions of the rooms
  • bool exits[MAX_EXITS]
    • MAX_EXITS = MAX_ROOMS * 4
    • For each exit, whether the exit is locked or not
  • char items[MAX_ITEMS][MAX_ITEM_NAME];
    • MAX_ITEMS = MAX_ROOMS * MAX_ITEMS_PER_ROOM, MAX_ITEM_NAME = 41
    • The description of each room
  • bool hidden[MAX_ITEMS];
    • (see above)
    • Whether each item is hidden or not
  • int directions[MAX_ROOMS][4]
    • (see above)
    • Where you can exit the given room. For example: if directions[0][1] is 3 then you can exit room 0 by going East through door 3, where North = 0, East = 1, South = 2, West = 3
  • int transitions[MAX_ROOMS][MAX_ROOMS];
    • (see above)
    • What exit you can use to get from one room to another. For example, if transitions[1][2] is 3 then to get from room 1 to room 2 then you can use door 3.
  • bool room_items[MAX_ROOMS][MAX_ITEMS];
    • (see above)
    • What rooms contain what items
  • bool reveals[MAX_ITEMS][MAX_ITEMS]
    • (see above)
    • When an item is searched it may reveal another item. That revealed item should have its hidden state set to false. For example, if reveals[1][4] is true, then searching for item 1 will reveal item 4.
  • bool unlocks[MAX_ITEMS][MAX_EXITS]
    • (see above)
    • Using a item (a key) on an exit may unlock it. For example, if unlocks[2][5] is true, then using item 2 on exit 5 unlocks the exit.
  • int inventory[MAX_ITEMS];
    • (see above)
    • The players inventory. For example, if inventory[0] is 3, then the user has item 3 in their inventory. The TAKE and DROP commands should update this

The file will have the following format:

rooms < number of rooms>
< descripton>
< description>
...
exits < number of exits>
< either "locked" or "unlocked">
< either "locked" or "unlocked">
...
items < number of items>
< hidden or revealed> < description>
< hidden or revealed> < description>
...
directions < number of directions>
< room #> < exit #> < either north, east, south, or west>
< room #> < exit #> < either north, east, south, or west>
...
transitions < number of transitions>
< room #> < room #> < exit #>
< room #> < room #> < exit #>
...
room_items < number of room item entries>
< room #> < item #>
< room #> < item #>
...
reveals < number of reveals entries>
< item #> < item #>
< item #> < item #>
...
unlocks < number of unlocks entries>
< item #> < exit #>
< item #> < exit #>
...
win
< room #>

So, give the following layout: see image.

Then the following file describes the layout:

rooms 7
front of the house
living room
guest bedroom
closet
hallway
master bedroom
garden
exits 6
locked
locked
unlocked
unlocked
locked
locked
items 8
hidden Rusty key
revealed Television set
revealed Potted plant
hidden slotted key
revealed welcome mat
hidden Book: War and Peace
revealed Bookcase
hidden silver key
directions 12
0 0 east
4 3 south
4 1 north
4 2 east
4 0 west
3 3 north
1 4 north
1 2 west
2 4 south
5 1 south
2 5 east
6 5 west
transitions 6
# room room exit
0 4 0
4 5 1
4 3 3
4 1 2
1 2 4
2 6 5
room_items 8
0 0
0 4
1 1
1 2
1 3
5 5
5 6
5 7
reveals 4
2 3
4 0
6 5
5 7
unlocks 2
# key exit
0 0
3 2
win
6
(Figure 2: Configuration file that describes the example layout.)

You will write a program that reads the file and fills your arrays. You must provide the following functions:

Calls the rest of the functions in this table to read the config file.

int read_world( std::ifstream &input,
char rooms[][MAX_ROOM_NAME], int &num_rooms,
bool exits[], int &num_exits,
char items[][MAX_ITEM_NAME],
bool hidden[], int &num_items,
int directions[][4],
int transitions[][MAX_ROOMS],
bool room_items[][MAX_ITEMS],
bool reveals[][MAX_ITEMS],
bool unlocks[][MAX_EXITS],
int &win);

Reads the room section into the rooms array

int read_rooms(std::ifstream &input, char rooms[][MAX_ROOM_NAME], int &num_rooms);

Reads the exits section into the exits array.

int read_exits(std::ifstream &input, bool exits[], int &num_exits);

Reads the items section into the items array.

int read_items(std::ifstream &input,
char items[][MAX_ITEM_NAME],
bool hidden[MAX_ITEMS],
int &num_items);

Reads the directions section into the directions array.

int read_directions(std::ifstream &input, int directions[MAX_ROOMS][4]);

Reads the transitions section into the transitions array.

int read_transitions(std::ifstream &input, int transitions[][MAX_ROOMS]);

Reads the room_items section into the room_items array.

int read_room_items(std::ifstream &input, bool room_items[MAX_ROOMS][MAX_ITEMS]);

Reads the reveals section into the reveals array.

int read_reveals(std::ifstream &input, bool reveals[][MAX_ITEMS]);

Reads the unlocks section into the unlocks array.

int read_unlocks(std::ifstream &input, bool unlocks[MAX_ITEMS][MAX_EXITS]);

Reads the win section and returns the room number.

int read_win(std::ifstream &input, int &room);

You program will call the read_world() function from the main() to read the entire configuration file. Each of these function should return 0 if the function was able to read the configuration file, or 1 if an error occured. An error can occur if you are expecting to read a section name, such as "items", but you get some other string. An error can also occur if you are expecting a number, your file object fails to get the number. You can check the fail flag to detect these errors (example: if (input.fail()) {...}). An error can occur if you need to read the file, but you reach end-of-file too soon. If a file error does occur, you main should print an error message to the user: "Could not read the configuration file".

Lastly, you will provide a function to print the contents of your arrays to demonstrate that you wrote your array functions correctly. (More to come!)

You should follow good programming practices (Program header, meaningful variable names, and adequate comments, proper indentation) while writing your program

Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.