Created
May 9, 2024 22:52
-
-
Save CodingDino/2302bb54d2f8128495b6167ded8d7231 to your computer and use it in GitHub Desktop.
Inheritance in an Adventure Game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Item.h" | |
#include <iostream> | |
Item::Item() | |
: Thing() | |
, useable(false) | |
{ | |
} | |
Item::Item(string newName, string newDesc, bool newUseable) | |
: Thing(newName, newDesc) | |
, useable(newUseable) | |
{ | |
} | |
Item::~Item() | |
{ | |
} | |
void Item::Print() | |
{ | |
Thing::Print(); | |
if (useable) | |
{ | |
cout << " This item can be used."; | |
} | |
} | |
bool Item::IsUseable() | |
{ | |
return useable; | |
} | |
void Item::UseItem() | |
{ | |
cout << "You use the " << name << "." << endl; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "Thing.h" | |
class Item : | |
public Thing | |
{ | |
private: | |
bool useable; | |
public: | |
Item(); | |
Item(string newName, string newDesc, bool newUseable); | |
~Item(); | |
void Print(); | |
bool IsUseable(); | |
void UseItem(); | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Libraries | |
#include <string> | |
#include <iostream> | |
#include <vector> | |
#include "Room.h" | |
#include "Item.h" | |
// Needed to avoid having to type std:: a lot! | |
using namespace std; | |
void TempFuncRoomDestructorTest(Room* existingRoom) | |
{ | |
Room tempRoom("TempName", "TempDesc"); | |
tempRoom.AddExit(existingRoom); | |
existingRoom->AddExit(&tempRoom); | |
} | |
// Function to Move the player to a different room | |
void Move(Room * ¤tRoom, int& stamina) | |
{ | |
// Print out the room the player is in | |
cout << "You are in the "; | |
currentRoom->Print(); | |
// INITIALISE a local bool vairable called processInput, to true | |
bool processInput = true; | |
// WHILE processInput is true... | |
while (processInput) | |
{ | |
// INITIALISE a local playerChoice variable | |
int playerChoice = 0; | |
// DISPLAY the player's current stamina | |
cout << "Stamina remaining: " << stamina << endl; | |
// DISPLAY the player's current stamina | |
cout << "Where would you like to go? (enter the number)" << endl; | |
// READ the player's response into the playerChoice variable | |
cin >> playerChoice; | |
// IF the player's choice between 1 and the roomNames vector size... | |
if (playerChoice >= 1 && playerChoice <= currentRoom->GetNumExits()) | |
{ | |
currentRoom = currentRoom->GetExit(playerChoice-1); | |
processInput = false; | |
} | |
// ELSE | |
else | |
{ | |
// DISPLAY an error message due to unrecognised input | |
cout << "Sorry, the number you typed was not one of the options: " << playerChoice << endl; | |
// CLEAR the input stream | |
cin.clear(); | |
cin.ignore(numeric_limits<streamsize>::max(), '\n'); | |
} // END IF | |
} // ENDWHILE | |
} | |
// Function to Pick up an item and add it to the backpack | |
void PickUp(Room* currentRoom, vector<Item*>& backpack) | |
{ | |
// Print out the room the player is in | |
cout << "You are in the "; | |
currentRoom->Print(); | |
// EXIT if there are no items | |
if (currentRoom->GetNumItems() == 0) | |
{ | |
cout << "There are no items in this room." << endl; | |
return; | |
} | |
// INITIALISE a local bool vairable called processInput, to true | |
bool processInput = true; | |
// WHILE processInput is true... | |
while (processInput) | |
{ | |
// INITIALISE a local playerChoice variable | |
int playerChoice = 0; | |
// DISPLAY the player's current stamina | |
cout << "What item would you like to take? (enter the number)" << endl; | |
// READ the player's response into the playerChoice variable | |
cin >> playerChoice; | |
// IF the player's choice between 1 and the roomNames vector size... | |
if (playerChoice >= 1 && playerChoice <= currentRoom->GetNumItems()) | |
{ | |
cout << "You take the " << currentRoom->GetItem(playerChoice - 1)->GetName() << " and put it in your backpack." << endl; | |
backpack.push_back(currentRoom->GetItem(playerChoice - 1)); | |
currentRoom->RemoveItem(playerChoice - 1); | |
processInput = false; | |
} | |
// ELSE | |
else | |
{ | |
// DISPLAY an error message due to unrecognised input | |
cout << "Sorry, the number you typed was not one of the options: " << playerChoice << endl; | |
// CLEAR the input stream | |
cin.clear(); | |
cin.ignore(numeric_limits<streamsize>::max(), '\n'); | |
} // END IF | |
} // ENDWHILE | |
} | |
// Function to use an item from the backpack | |
void UseItem(vector<Item*>& backpack) | |
{ | |
if (backpack.size() == 0) | |
{ | |
cout << "You currently have nothing in your backpack, so you cannot use an item." << endl; | |
return; | |
} | |
// Print out the contents of the backpack | |
cout << "Your backpack holds the following:" << endl; | |
// FOR each item in the items vector... | |
for (unsigned int i = 0; i < backpack.size(); ++i) | |
{ | |
// DISPLAY the loop index + 1 and the name of the item at that index | |
cout << (i + 1) << ". " << backpack[i]->GetName() << endl; | |
} | |
// END FOR | |
// INITIALISE a local bool vairable called processInput, to true | |
bool processInput = true; | |
// WHILE processInput is true... | |
while (processInput) | |
{ | |
// INITIALISE a local playerChoice variable | |
int playerChoice = 0; | |
// DISPLAY the player's current stamina | |
cout << "What item would you like to use? (enter the number)" << endl; | |
// READ the player's response into the playerChoice variable | |
cin >> playerChoice; | |
// IF the player's choice between 1 and the roomNames vector size... | |
if (playerChoice >= 1 && playerChoice <= backpack.size()) | |
{ | |
if (backpack[playerChoice - 1]->IsUseable()) | |
{ | |
backpack[playerChoice - 1]->UseItem(); | |
backpack.erase(next(backpack.begin(), playerChoice - 1)); | |
} | |
else | |
{ | |
cout << "The " << backpack[playerChoice - 1]->GetName() << " cannot be used." << endl; | |
} | |
processInput = false; | |
} | |
// ELSE | |
else | |
{ | |
// DISPLAY an error message due to unrecognised input | |
cout << "Sorry, the number you typed was not one of the options: " << playerChoice << endl; | |
// CLEAR the input stream | |
cin.clear(); | |
cin.ignore(numeric_limits<streamsize>::max(), '\n'); | |
} // END IF | |
} // ENDWHILE | |
} | |
// Main function where program code execution begins and ends. | |
int main() | |
{ | |
// INITIALISE variables | |
string playerName = ""; | |
int playerChoice = -1; | |
int moveCost = 5; | |
int playerStamina = 20; | |
bool exit = false; | |
vector<Item*> backpack; | |
// Create rooms | |
Room courtyard("Courtyard", "A barren, weed-filled courtyard of a crumbling ruined castle."); | |
Room entryHall("Entry Hall", "A once-grand hll with a rotting red carpet, lined with rusted suits of armour."); | |
Room gate("Gate", "The dilapidated gates hang crookedly from their hinges, set into the crumbling stone wall that surrounds the ruined castle."); | |
courtyard.AddExit(&entryHall); | |
courtyard.AddExit(&gate); | |
gate.AddExit(&courtyard); | |
entryHall.AddExit(&courtyard); | |
Room * currentRoom = &courtyard; | |
// TEST our room destructor. If successful, we should not have a connection to the temp room as it will delete itself | |
TempFuncRoomDestructorTest(&courtyard); | |
// CREATE items | |
Item hat("Hat", "A battered old hat.", false); | |
Item potion("Potion", "A mysterious blue potion.", true); | |
Item coin("Coin", "A tarnished old copper coin.", false); | |
// ADD the items to rooms | |
courtyard.AddItem(&potion); | |
courtyard.AddItem(&coin); | |
gate.AddItem(&hat); | |
// DISPLAY the title of the program. | |
cout << "Welcome to the Example Adventure Game!" << endl; | |
// DISPLAY a message to the player asking their name. | |
cout << "What are you called, brave adventurer?" << endl; | |
// READ the player's response into the playerName variable | |
getline(cin, playerName); | |
cout << endl; | |
// DISPLAY a greeting to the player, using the playerName variable | |
cout << "Welcome, " << playerName << ", soon to be hero of the realm!" << endl << endl; | |
// WHILE exit is false... | |
while (!exit) | |
{ | |
cout << "You are in the " << currentRoom->GetName() << endl; | |
cout << "What would you like to do? Enter the number for your choice." << endl; | |
cout << "1. Move" << endl; | |
cout << "2. Pick Up Item" << endl; | |
cout << "3. Use Item" << endl; | |
cout << "4. Quit" << endl; | |
// Initialise player choice | |
playerChoice = -1; | |
// READ the player's response into the playerChoice variable | |
cin >> playerChoice; | |
if (playerChoice == 1) | |
{ | |
// Move! | |
Move(currentRoom, playerStamina); | |
// SUBTRACT the stamina required to move from the player's stamina value | |
playerStamina = playerStamina - moveCost; | |
// DISPLAY a message that the player has moved and used moveCost stamina | |
cout << "You have changed rooms and used " << moveCost << " stamina." << endl; | |
// IF the player stamina reaches 0 or lower... | |
if (playerStamina <= 0) | |
{ | |
// DISPLAY a message to the player telling them they have died | |
cout << "You have run out of stamina and died! Better luck next time. Please play again!" << endl; | |
// SET exit to true | |
exit = true; | |
} | |
// ENDIF | |
} | |
else if (playerChoice == 2) | |
{ | |
// Pick Up Item! | |
PickUp(currentRoom, backpack); | |
} | |
else if (playerChoice == 3) | |
{ | |
// Use Item! | |
UseItem(backpack); | |
} | |
else if (playerChoice == 4) | |
{ | |
// Quit! | |
// DISPLAY a goodbye message to the player | |
cout << "Thank you for playing!" << endl; | |
// SET exit to true | |
exit = true; | |
} | |
// ELSE | |
else | |
{ | |
// DISPLAY an error message due to unrecognised input | |
cout << "Sorry, the number you typed was not one of the options: " << playerChoice << endl; | |
// CLEAR the input stream | |
cin.clear(); | |
cin.ignore(numeric_limits<streamsize>::max(), '\n'); | |
} // END IF | |
} | |
// END WHILE | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Room.h" | |
#include <iostream> | |
Room::Room() | |
: Thing() | |
, exits() | |
{ | |
} | |
Room::Room(string newName, string newDesc) | |
: Thing(newName, newDesc) | |
, exits() | |
{ | |
} | |
Room::~Room() | |
{ | |
// Check each connected room | |
// and erase THIS room from it, since this room is being destroyed and cannot connect anymore. | |
for (int i = 0; i < exits.size(); ++i) | |
{ | |
// Store the other room in a temporary variable to make our code more easy to understand | |
Room* otherRoom = exits[i]; | |
// We will check the OTHER room's list of exits (exits[i]->exits) for THIS room (the "this" pointer) | |
// We use the find function to do this | |
auto it = find(otherRoom->exits.begin(), otherRoom->exits.end(), this); | |
// If the element was not found, it will be equal to the end() value. | |
// So if it is NOT equal to that, it was found, and we should erase it! | |
if (it != otherRoom->exits.end()) { | |
otherRoom->exits.erase(it); | |
} | |
} | |
} | |
void Room::Print() | |
{ | |
Thing::Print(); | |
// DISPLAY exits | |
cout << endl << "Exits are:" << endl; | |
// FOR each room in the exits vector... | |
for (unsigned int i = 0; i < exits.size(); ++i) | |
{ | |
// DISPLAY the loop index + 1 and the name of the room at that index | |
cout << (i + 1) << ". " << exits[i]->name << endl; | |
} | |
// END FOR | |
// DISPLAY items, if any | |
if (GetNumItems() > 0) | |
{ | |
cout << endl << "You see these items lying on the ground:" << endl; | |
// FOR each item in the items vector... | |
for (unsigned int i = 0; i < items.size(); ++i) | |
{ | |
// DISPLAY the loop index + 1 and the name of the item at that index | |
cout << (i + 1) << ". " << items[i]->GetName() << endl; | |
} | |
// END FOR | |
} | |
} | |
void Room::AddExit(Room* newExit) | |
{ | |
exits.push_back(newExit); | |
} | |
int Room::GetNumExits() | |
{ | |
return exits.size(); | |
} | |
Room* Room::GetExit(int index) | |
{ | |
return exits[index]; | |
} | |
void Room::AddItem(Item* newItem) | |
{ | |
items.push_back(newItem); | |
} | |
void Room::RemoveItem(int index) | |
{ | |
items.erase(next(items.begin(), index)); | |
} | |
int Room::GetNumItems() | |
{ | |
return items.size(); | |
} | |
Item* Room::GetItem(int index) | |
{ | |
return items[index]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <string> | |
#include <vector> | |
#include "Thing.h" | |
#include "Item.h" | |
using namespace std; | |
class Room : public Thing | |
{ | |
private: | |
vector<Room*> exits; | |
vector<Item*> items; | |
public: | |
Room(); | |
Room(string newName, string newDesc); | |
~Room(); | |
void Print(); | |
void AddExit(Room* newExit); | |
int GetNumExits(); | |
Room* GetExit(int index); | |
void AddItem(Item* newItem); | |
void RemoveItem(int index); | |
int GetNumItems(); | |
Item* GetItem(int index); | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Thing.h" | |
#include <iostream> | |
Thing::Thing() | |
: name("") | |
, desc("") | |
{ | |
} | |
Thing::Thing(string newName, string newDesc) | |
: name(newName) | |
, desc(newDesc) | |
{ | |
} | |
Thing::~Thing() | |
{ | |
} | |
void Thing::Print() | |
{ | |
// DISPLAY the the name | |
cout << name << " - "; | |
// DISPLAY the description | |
cout << desc; | |
} | |
string Thing::GetName() | |
{ | |
return name; | |
} | |
string Thing::GetDescription() | |
{ | |
return desc; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <string> | |
using namespace std; | |
class Thing | |
{ | |
protected: | |
string name; | |
string desc; | |
public: | |
Thing(); | |
Thing(string newName, string newDesc); | |
~Thing(); | |
void Print(); | |
string GetName(); | |
string GetDescription(); | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment