This tutorial will guide you through creating a text adventure game in C++ using parallel arrays. This project is designed for first-year programming students to teach array manipulation, indexing, and game design concepts.
Parallel arrays are multiple arrays where the same index in each array refers to the same entity. It's like having a table with rows and columns, but each column is stored in its own separate array.
Index | Array1 | Array2 | Array3 |
---|---|---|---|
0 | Value1A | Value1B | Value1C |
1 | Value2A | Value2B | Value2C |
2 | Value3A | Value3B | Value3C |
"The Basics"
"The Collector"
"The Interactor"
"The Container"
"The Ultimate"
We'll start with parallel arrays for rooms and items:
// ROOM ARRAYS vector<string> room_names = { "Player", // Index 0 = Player (not a room) "Entrance Hall", "Kitchen", "Living Room", "Secret Passage" }; vector<string> room_descriptions = { "That's you!", // Player description "A grand entrance with marble floors and a chandelier.", "A small kitchen with an old stove and sink.", "A cozy room with a fireplace and comfortable chairs.", "A narrow, dark passage hidden behind a bookshelf." }; // Exits: N, E, S, W (-1 means no exit) vector<vector<int>> room_exits = { {-1, -1, -1, -1}, // Player (not a location) {-1, 3, 2, -1}, // Entrance: No N, E to Living Room, S to Kitchen, No W {1, -1, -1, -1}, // Kitchen: N to Entrance, No other exits {-1, 4, -1, 1}, // Living Room: No N, E to Secret Passage, No S, W to Entrance {-1, -1, -1, 3} // Secret Passage: No N, No E, No S, W to Living Room };
// ITEM ARRAYS vector<string> item_names = { "rusty key", "flashlight", "apple", "knife", "old book", "letter" }; // Location of each item (0=player, 1-4=rooms) vector<int> item_locs = { 1, // rusty key in Entrance Hall 1, // flashlight in Entrance Hall 2, // apple in Kitchen 2, // knife in Kitchen 3, // old book in Living Room 3 // letter in Living Room };
// Display current room info cout << "You are in the " << room_names[currentRoom] << endl; cout << room_descriptions[currentRoom] << endl; // Display items in this room cout << "You see: "; bool foundItems = false; for (int i = 0; i < item_locs.size(); i++) { if (item_locs[i] == currentRoom) { if (foundItems) cout << ", "; cout << item_names[i]; foundItems = true; } } if (!foundItems) cout << "nothing of interest"; cout << endl; // Display inventory cout << "Inventory: "; bool hasItems = false; for (int i = 0; i < item_locs.size(); i++) { if (item_locs[i] == 0) { // 0 = player inventory if (hasItems) cout << ", "; cout << item_names[i]; hasItems = true; } } if (!hasItems) cout << "empty"; cout << endl;
// Process movement commands if (command == "north" || command == "n") { if (room_exits[currentRoom][0] != -1) currentRoom = room_exits[currentRoom][0]; else cout << "You can't go that way." << endl; } else if (command == "east" || command == "e") { if (room_exits[currentRoom][1] != -1) currentRoom = room_exits[currentRoom][1]; else cout << "You can't go that way." << endl; }
currentRoom
to a new value effectively moves the player through the game world.
// Add item descriptions vector<string> item_descriptions = { "An old rusty key that might open something.", "A working flashlight with fresh batteries.", "A shiny red apple that looks delicious.", "A sharp kitchen knife.", "A dusty book with strange symbols on the cover.", "A sealed envelope with elegant handwriting." };
// Command parsing (add near the command input section) string input, verb, noun; cout << "> "; getline(cin, input); // Get the whole line stringstream ss(input); // Create a string stream ss >> verb; // Extract first word as verb ss >> noun; // Extract second word as noun
if (verb == "take" && !noun.empty()) { bool found = false; for (int i = 0; i < item_names.size(); i++) { // If item matches name and is in current room if (item_names[i] == noun && item_locs[i] == currentRoom) { // Move to inventory (location 0) item_locs[i] = 0; cout << "You take the " << item_names[i] << "." << endl; found = true; break; } } if (!found) cout << "You don't see that here." << endl; }
else if (verb == "drop" && !noun.empty()) { bool found = false; for (int i = 0; i < item_names.size(); i++) { // If item matches name and is in inventory if (item_names[i] == noun && item_locs[i] == 0) { // Move to current room item_locs[i] = currentRoom; cout << "You drop the " << item_names[i] << "." << endl; found = true; break; } } if (!found) cout << "You don't have that." << endl; }
else if (verb == "examine" || verb == "look") { if (noun.empty()) { // Look at room again cout << room_descriptions[currentRoom] << endl; } else { // Look at specific item bool found = false; for (int i = 0; i < item_names.size(); i++) { // If item matches name and is in current room or inventory if (item_names[i] == noun && (item_locs[i] == currentRoom || item_locs[i] == 0)) { cout << item_descriptions[i] << endl; found = true; break; } } if (!found) cout << "You don't see that here." << endl; } }
item_locs[i] = 0
) moves an item from a room to inventory. This demonstrates the power of parallel arrays!
Here are some challenges to help you extend your text adventure game:
Create a simple visual map of the rooms that displays when the player types "map".
Add a new parallel array called item_weights
and implement a weight limit for the player.
Implement a "use [item]" command that performs special actions for certain items.
Add a room_states
array to track conditions like "light/dark" or "locked/unlocked".
Remember, you're encouraged to use AI tools like Claude to help you understand concepts. Here are some effective prompts:
Avoid asking the AI to "write the complete code for me" - instead, focus on understanding the concepts!
#include <iostream> #include <string> #include <vector> using namespace std; int main() { // ROOM ARRAYS vector<string> room_names = { "Player", // Index 0 = Player (not a room) "Entrance Hall", "Kitchen", "Living Room", "Secret Passage" }; vector<string> room_descriptions = { "That's you!", // Player description "A grand entrance with marble floors and a chandelier.", "A small kitchen with an old stove and sink.", "A cozy room with a fireplace and comfortable chairs.", "A narrow, dark passage hidden behind a bookshelf." }; // Exits: N, E, S, W (-1 means no exit) vector<vector<int>> room_exits = { {-1, -1, -1, -1}, // Player (not a location) {-1, 3, 2, -1}, // Entrance: No N, E to Living Room, S to Kitchen, No W {1, -1, -1, -1}, // Kitchen: N to Entrance, No other exits {-1, 4, -1, 1}, // Living Room: No N, E to Secret Passage, No S, W to Entrance {-1, -1, -1, 3} // Secret Passage: No N, No E, No S, W to Living Room }; // ITEM ARRAYS vector<string> item_names = { "rusty key", "flashlight", "apple", "knife", "old book", "letter" }; // Location of each item (0=player, 1-4=rooms) // Initially distributed in different rooms vector<int> item_locs = { 1, // rusty key in Entrance Hall 1, // flashlight in Entrance Hall 2, // apple in Kitchen 2, // knife in Kitchen 3, // old book in Living Room 3 // letter in Living Room }; // Player starts in the entrance hall (room 1) int currentRoom = 1; // Game loop while (true) { cout << "\n----------------------------------------\n"; // Display current room info cout << "You are in the " << room_names[currentRoom] << endl; cout << room_descriptions[currentRoom] << endl; // Display items in this room cout << "You see: "; bool foundItems = false; for (int i = 0; i < item_locs.size(); i++) { if (item_locs[i] == currentRoom) { if (foundItems) cout << ", "; cout << item_names[i]; foundItems = true; } } if (!foundItems) cout << "nothing of interest"; cout << endl; // Display inventory cout << "Inventory: "; bool hasItems = false; for (int i = 0; i < item_locs.size(); i++) { if (item_locs[i] == 0) { // 0 = player inventory if (hasItems) cout << ", "; cout << item_names[i]; hasItems = true; } } if (!hasItems) cout << "empty"; cout << endl; // Display available exits cout << "Exits: "; if (room_exits[currentRoom][0] != -1) cout << "North "; if (room_exits[currentRoom][1] != -1) cout << "East "; if (room_exits[currentRoom][2] != -1) cout << "South "; if (room_exits[currentRoom][3] != -1) cout << "West "; cout << endl; // Get player command string command; cout << "> "; cin >> command; // Process movement commands if (command == "north" || command == "n") { if (room_exits[currentRoom][0] != -1) currentRoom = room_exits[currentRoom][0]; else cout << "You can't go that way." << endl; } else if (command == "east" || command == "e") { if (room_exits[currentRoom][1] != -1) currentRoom = room_exits[currentRoom][1]; else cout << "You can't go that way." << endl; } else if (command == "south" || command == "s") { if (room_exits[currentRoom][2] != -1) currentRoom = room_exits[currentRoom][2]; else cout << "You can't go that way." << endl; } else if (command == "west" || command == "w") { if (room_exits[currentRoom][3] != -1) currentRoom = room_exits[currentRoom][3]; else cout << "You can't go that way." << endl; } else if (command == "quit") { break; } else { cout << "I don't understand that command." << endl; } } cout << "Thanks for playing!" << endl; return 0; }
Have fun teaching parallel arrays through text adventures!