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