#include #include #include #include enum ePLDFlags { HP = 1, EP = 2, XP = 4, }; inline ePLDFlags operator|(ePLDFlags a, ePLDFlags b) { return static_cast(static_cast(a) | static_cast(b)); } enum eSpecOut { REG, TRS, EXT, }; struct Outcome { int iPlayerLevelDelta; int iPlayerHealthDelta; int iPlayerEnduranceDelta; int iPlayerXperienceDelta; int eLevelFlags; // PlayerLevelDependent eSpecOut eSpecial; }; struct Choices { std::vector vsNames; std::vector vsDescriptions; std::vector vOutcomes; }; struct Room { std::string sName; std::string sDescription; Choices choices; }; struct Player { int iHealth; int iEndurance; int iXperience; int iKeys; int iLevel; int iArmor; int iWeapon; }; std::ostream &operator<<(std::ostream &out, Player player) { out << "[HP: " << player.iHealth << "] [EP: " << player.iEndurance << "] [XP: " << player.iXperience << "] [WP: " << player.iWeapon << "] [AP: " << player.iArmor << "] [Keys: " << player.iKeys << "] [Level: " << player.iLevel << "]"; return out; } int main() { using namespace std; vector vRooms = { {"Empty Room", "You enter an empty room with nothing going on.", {{"Rest", "Scavenge for food", "Move on"}, {"You found a comfy place to take a nap.", "After some looking around you found a pack of food the previous adventurer left here.", "Your curiosity couldn't stop you, so you moved on immdediately"}, {{0, 1, 3, 0, 0, REG}, {0, 3, -1, 0, 0, REG}, {0, 0, 0, 0, 0, REG}}}}, {"Trap Room", "You stop yourself right before you trigger the trap.", {{"Trigger the trap", "Disarm the trap"}, {"YEOWCH!", "After some fiddling around you finally disarmed the trap"}, {{0, -1, 0, 0, HP, REG}, {0, 0, -1, 0, EP, REG}}}}, {"Empty Corridor", "You enter an empty corridor with nothing going on.", {{"Rest", "Scavenge for food", "Move on"}, {"You found a comfy place to take a nap.", "After some looking around you found a pack of food the previous adventurer left here.", "Your curiosity couldn't stop you, so you moved on immdediately"}, {{0, 1, 3, 0, 0, REG}, {0, 3, -1, 0, 0, REG}, {0, 0, 0, 0, 0, REG}}}}, {"Monster Room", "You turn the corner and see an ugly monster!", {{"Fight", "Run"}, {"You defeat the monster. Your armor still dripping blood, its and yours.", "You became so scared you ran away. Can't blame ya."}, {{0, -1, -1, 1, HP | EP | XP, REG}, {0, 0, 0, 0, 0, REG}}}}, {"Monster Corridor", "You turn the corner and see an ugly monster!", {{"Fight", "Run"}, {"You defeat the monster. Your armor still dripping blood, its and yours.", "You became so scared you ran away. Can't blame ya."}, {{0, -1, -1, 1, HP | EP | XP, REG}, {0, 0, 0, 0, 0, REG}}}}, {"Treasure Room", "As you enter the room something shiny catches your eye.", {{"Take the shiny", "Move on"}, {"You pick up the shiny and put it in your pocket.", "You decide not to pick the shiny thing up, maybe it was a trap?"}, {{0, 0, 0, 1, XP, TRS}, {0, 0, 0, 0, 0, REG}}}}, {"Stair Room", "You enter the room and see old, cracked stairs going down.", {{"Go down", "Move on"}, {"You go down the old stairs, trying not to trip.", "You decided that it's best not to go down there."}, {{1, 0, 0, 0, 0, REG}, {0, 0, 0, 0, 0, REG}}}}, {"Boss Room", "As you enter the room you can smell the boss monster, it's a terrible " "smell.", {{"Fight"}, {"You fought glouriously."}, {{0, -2, -2, 2, HP | EP | XP, REG}}}}, {"Exit of the dungeon", "You see some sunlight coming from the top. It's the exit!", {{"Exit the dungeon", "Move on"}, {"You exit this damned dungeon. Good job.", "You wanted to stay here for longer, likely because you think your mission isn't over."}, {{0, 0, 0, 0, 0, EXT}, {0, 0, 0, 0, 0, REG}}}}, }; int iShouldStop = 0; Player player = {6, 6, 0, 0, 1, 0, 0}; int iRoomId; Room room; char inp[2]; int iInputIsCorrect = 1; int iXPFlag = 0; int iTurns = 0; srand(time(0)); while (!iShouldStop) { if (player.iXperience >= 50) iXPFlag = 1; else iXPFlag = 0; if (iInputIsCorrect && !iXPFlag) { iRoomId = rand() % 6 + player.iKeys; room = vRooms[iRoomId]; cout << noshowpos << player << " [Turns: " << iTurns << "]" << endl; iTurns++; cout << "> " << room.sName << "\n"; cout << "=> " << room.sDescription << "\n"; for (int i = 0; i < room.choices.vsNames.size(); i++) { cout << " [" << room.choices.vsNames[i][0] << "]" << room.choices.vsNames[i].substr(1) << ": "; auto outcome = room.choices.vOutcomes[i]; if (outcome.eSpecial == REG) { int iHPDelta = outcome.iPlayerHealthDelta; int iEPDelta = outcome.iPlayerEnduranceDelta; int iXPDelta = outcome.iPlayerXperienceDelta; if (outcome.eLevelFlags & HP) iHPDelta *= player.iLevel; if (outcome.eLevelFlags & EP) iEPDelta *= player.iLevel; if (outcome.eLevelFlags & XP) iXPDelta *= player.iLevel; if (iHPDelta < 0) { iHPDelta += player.iArmor; iHPDelta = min(0, iHPDelta); } if (iEPDelta < 0) { iEPDelta += player.iWeapon; iEPDelta = min(0, iEPDelta); } if (outcome.iPlayerHealthDelta) cout << showpos << "[" << iHPDelta << "hp]" << " "; if (outcome.iPlayerEnduranceDelta) cout << showpos << "[" << iEPDelta << "ep]" << " "; if (outcome.iPlayerXperienceDelta) cout << showpos << "[" << iXPDelta << "xp]" << " "; if (outcome.iPlayerLevelDelta) cout << showpos << "[" << outcome.iPlayerLevelDelta << "lvl]"; if (!outcome.iPlayerEnduranceDelta && !outcome.iPlayerHealthDelta && !outcome.iPlayerXperienceDelta) cout << "[Nothing]"; } else { switch (outcome.eSpecial) { case TRS: cout << "[+1 Treasure]"; break; case EXT: cout << "[Get outta here!]"; break; default: break; } } cout << endl; } cout << endl; } else if (iInputIsCorrect && iXPFlag) { cout << noshowpos << player << endl; cout << "=> You have 50+ XP! You can get better armor or a better weapon" << endl; cout << " [W]eapon [+1 weapon]" << endl; cout << " [A]rmor [+1 armor]" << endl; } else { cout << "Invalid Input: \"" << inp[0] << "\"" << endl; } iInputIsCorrect = 0; scanf("%1s", inp); inp[0] = tolower(inp[0], locale()); while (getchar() != '\n'); if (iXPFlag) { switch (inp[0]) { case 'w': cout << "You got yourself a mighty good weapon." << endl; iInputIsCorrect = 1; player.iWeapon++; player.iXperience -= 50; break; case 'a': cout << "You got yourself some brilliant armor." << endl; iInputIsCorrect = 1; player.iArmor++; player.iXperience -= 50; break; } } else { for (int i = 0; i < room.choices.vsNames.size(); i++) { if (inp[0] == tolower(room.choices.vsNames[i][0], locale())) { auto outcome = room.choices.vOutcomes[i]; if (outcome.eSpecial == REG) { int iHPDelta = outcome.iPlayerHealthDelta; int iEPDelta = outcome.iPlayerEnduranceDelta; int iXPDelta = outcome.iPlayerXperienceDelta; if (outcome.eLevelFlags & HP) iHPDelta *= player.iLevel; if (outcome.eLevelFlags & EP) iEPDelta *= player.iLevel; if (outcome.eLevelFlags & XP) iXPDelta *= player.iLevel; if (iHPDelta < 0) { iHPDelta += player.iArmor; iHPDelta = min(0, iHPDelta); } if (iEPDelta < 0) { iEPDelta += player.iWeapon; iEPDelta = min(0, iEPDelta); } player.iHealth += iHPDelta; player.iEndurance += iEPDelta; player.iXperience += iXPDelta; player.iLevel += outcome.iPlayerLevelDelta; } else if (outcome.eSpecial == TRS) { if (player.iKeys < 3) { if (rand() % 2 == 0) player.iKeys++; else player.iXperience += player.iLevel; } else { player.iXperience += player.iLevel; } } else if (outcome.eSpecial == EXT) { cout << "You exit the dungeon with " << player.iXperience + player.iArmor * 50 + player.iWeapon * 50 << "xp. Congrats!" << endl; iShouldStop = 1; } cout << room.choices.vsDescriptions[i] << endl; iInputIsCorrect = 1; } cout << endl; } } if (player.iHealth < 1) { cout << "You bled out." << endl; iShouldStop = 1; } if (player.iEndurance < 1) { cout << "You collapsed onto the floor." << endl; iShouldStop = 1; } } return 0; }