Created
May 16, 2024 12:17
-
-
Save CodingDino/7e14018338a2f334094e02436d55f82d to your computer and use it in GitHub Desktop.
Polymorphism in an Adventure Game (Room and Thing unchanged so not included)
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(int& playerStamina) | |
{ | |
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(); | |
virtual void UseItem(int& playerStamina); | |
}; | |
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" | |
#include "Potion.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, int & playerStamina) | |
{ | |
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(playerStamina); | |
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); | |
Potion potion("Potion", "A mysterious blue potion.", 10); | |
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, playerStamina); | |
} | |
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 "Potion.h" | |
#include <iostream> | |
Potion::Potion() | |
: Item () | |
, toHeal (0) | |
{ | |
} | |
Potion::Potion(string newName, string newDesc, int newToHeal) | |
: Item (newName, newDesc, true) | |
, toHeal (newToHeal) | |
{ | |
} | |
Potion::~Potion() | |
{ | |
} | |
void Potion::UseItem(int& playerStamina) | |
{ | |
cout << "You use the " << name << " and recover "<< toHeal <<" stamina." << endl; | |
playerStamina = playerStamina + toHeal; | |
} |
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 "Item.h" | |
class Potion : | |
public Item | |
{ | |
private: | |
int toHeal; | |
public: | |
Potion(); | |
Potion(string newName, string newDesc, int newToHeal); | |
~Potion(); | |
void UseItem(int& playerStamina); | |
}; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment