Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cmath>
- #include <string>
- #include <cstdlib>
- #include <ctime>
- #include <algorithm>
- #include <utility>
- #include <array>
- #include <vector>
- #include <cassert>
- #include <cstdint>
- #include <initializer_list>
- #include <stdlib.h>
- #include <stdio.h>
- #include <time.h>
- //another update to the game. Makes the game a bit easier as the previous version had some enemies that did too much damage.
- int getRandomNumber(int min, int max)
- {
- static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0); // static used for efficiency, so we only calculate this value once
- // evenly distribute the random number across our range
- return static_cast<int>(rand() * fraction * (max - min + 1) + min);
- }
- class Creature
- {
- protected: //note that the members are protected, meaning derived classes can access them.
- std::string m_name;
- char m_symbol;
- int m_health;
- int m_damage;
- int m_gold;
- public:
- Creature(std::string name, char symbol, int health, int damage, int gold) :
- m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold) {}
- std::string getName() { return m_name; }
- char getSymbol() { return m_symbol; }
- int getHealth() { return m_health; }
- int getDamage() { return m_damage; }
- int getGold() { return m_gold; }
- void reduceHealth(int healthLost) { m_health -= healthLost; }
- bool isDead() { return m_health <= 0; }
- void addGold(int goldGained) { m_gold += goldGained; }
- };
- class Player : public Creature
- {
- int m_level = 1;
- public:
- Player(std::string name) : Creature(name, '@', 10, 1, 0) {}
- int getLevel() { return m_level; }
- void increaseDamage(int x) { m_damage += x; }
- void levelUp()
- {
- ++m_level;
- ++m_damage;
- }
- bool hasWon() { return m_level >= 20; }
- };
- class Monster : public Creature
- {
- public:
- enum Type
- {
- SLIME,
- GREMLIN,
- GOBLIN,
- ZOMBIE,
- TROLL,
- GHOST,
- ORC,
- SCORPION,
- REVENANT,
- DRYAD,
- BASILISK,
- GIANT_SPIDER,
- WRAITH,
- STONE_GOLEM,
- BANSHEE,
- GIANT_SLIME,
- GIANT_HORNET,
- OGRE,
- POLTERGEIST,
- WINDIGO,
- YOUNG_DRAGON,
- MAX_TYPES
- };
- struct MonsterData
- {
- const char* name;
- char symbol;
- int health;
- int damage;
- int gold;
- };
- static MonsterData monsterData[MAX_TYPES];
- Monster(Type type) :
- Creature(monsterData[type].name, monsterData[type].symbol, monsterData[type].health, monsterData[type].damage,
- monsterData[type].gold)
- {
- }
- static Monster getRandomMonster(Player &p)
- {
- if (p.getLevel() == 1 || p.getLevel() == 2 || p.getLevel() == 3)
- {
- int num = getRandomNumber(0, GOBLIN);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 4)
- {
- int num = getRandomNumber(GOBLIN, GHOST);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 5 || p.getLevel() == 6)
- {
- int num = getRandomNumber(ZOMBIE, GHOST);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 7)
- {
- int num = getRandomNumber(GHOST, REVENANT);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() >= 8 && p.getLevel() <=9)
- {
- int num = getRandomNumber(ORC, REVENANT);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 10)
- {
- int num = getRandomNumber(REVENANT, GIANT_SPIDER);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 11 || p.getLevel() == 12) //switched symbols as it's easier to understand
- {
- int num = getRandomNumber(DRYAD, GIANT_SPIDER);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 13)
- {
- int num = getRandomNumber(GIANT_SPIDER, BANSHEE);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 14 || p.getLevel() == 15)
- {
- int num = getRandomNumber(WRAITH, BANSHEE);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 16)
- {
- int num = getRandomNumber(GIANT_SLIME, GIANT_HORNET);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 17)
- {
- int num = getRandomNumber(OGRE, POLTERGEIST);
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 18)
- {
- int num = WINDIGO;
- return Monster(static_cast<Type>(num));
- }
- if (p.getLevel() == 19)
- {
- int num = YOUNG_DRAGON;
- return Monster(static_cast<Type>(num));
- }
- }
- };
- Monster::MonsterData Monster::monsterData[Monster::MAX_TYPES]
- {
- { "slime", 's', 1, 1, getRandomNumber(5,10) }, //level 1-3
- { "gremlin", 'G', getRandomNumber(1,2), getRandomNumber(1,2),getRandomNumber(10,15)}, //level 1-3
- { "goblin", 'g', getRandomNumber(2,4), getRandomNumber(1,2), getRandomNumber(15,20)}, //level 1-4
- { "zombie", 'z', getRandomNumber(4,6), getRandomNumber(2,3), getRandomNumber(20,25)}, //level 4-6
- { "troll", 't', getRandomNumber(4,6), getRandomNumber(2,4), getRandomNumber(15,25)}, //level 4-6
- { "ghost", 'h', 7, getRandomNumber(1,2), getRandomNumber(20,28)}, //level 4-7
- { "orc", 'o', getRandomNumber(10,11), getRandomNumber(4,5), getRandomNumber(28,35)}, //7-9
- { "scorpion", 's', getRandomNumber(9,10), getRandomNumber(5,6), getRandomNumber(30,36)}, //7-9
- { "revenant", 'r', getRandomNumber(9,11), getRandomNumber(4,4), getRandomNumber(33,35)}, //7-10
- { "dryad", 'd', getRandomNumber(13,15), getRandomNumber(5,6), getRandomNumber(34,40)}, //10-12
- { "basilisk", 'b', getRandomNumber(14,16), getRandomNumber(4,5), getRandomNumber(34,41)}, //10-12
- { "giant spider", 'S', getRandomNumber(16,17), getRandomNumber(5,6), getRandomNumber(35,45)}, //10-13
- { "wraith", 'W', getRandomNumber(20,24), getRandomNumber(6,7), getRandomNumber(40,50)}, //13-15
- { "stone golem", 'g', getRandomNumber(30,35), getRandomNumber(5,6) ,getRandomNumber(45,52)}, //13-15
- { "banshee", 'b', getRandomNumber(25,28), getRandomNumber(6,7), getRandomNumber(45,54)}, //13-15
- { "giant slime", 'G', getRandomNumber(30,32), getRandomNumber(7,8), 55}, //16
- { "giant hornet", 'H', getRandomNumber(30,32), getRandomNumber(7,8), 55}, //16
- { "ogre", 'O', getRandomNumber(32,34), getRandomNumber(8,10), getRandomNumber(56,58)}, //17
- { "poltergeist", 'P', getRandomNumber(33,35), getRandomNumber(8,10), getRandomNumber(56,59)}, //17
- { "windigo", 'W', getRandomNumber(40,42), getRandomNumber(12,13), getRandomNumber(80,85)}, //18
- { "young dragon", 'D', getRandomNumber(50,50), getRandomNumber(15,15), getRandomNumber(99,101)} //19
- };
- void otherLoot(Player &p, Monster &m)
- {
- if (m.getName() == "windigo")
- {
- std::cout << "The " << m.getName() << " dropped a greater healing potion!\n";
- p.reduceHealth(-3);
- std::cout << p.getName() << " healed 3 hitpoints and now has " << p.getHealth() << " health.\n";
- std::cout << "The " << m.getName() << " also dropped a damage potion!\n";
- p.increaseDamage(2);
- std::cout << p.getName() << " consumed the potion and now deals " << p.getDamage() << " damage.\n";
- return;
- }
- if (p.getLevel() <= 6)
- {
- int x = getRandomNumber(1, 3);
- switch (x)
- {
- case 1:
- {
- std::cout << "The " << m.getName() << " dropped a lesser healing potion!\n";
- p.reduceHealth(-1);
- std::cout << p.getName() << " healed 1 hitpoint and now has " << p.getHealth() << " health.\n";
- break;
- }
- case 2:
- {
- std::cout << "The " << m.getName() << " dropped a lesser damage potion!\n";
- p.increaseDamage(1);
- std::cout << p.getName() << " consumed the potion and now deals " << p.getDamage() << " damage.\n";
- break;
- }
- default:
- {
- std::cout << "The " << m.getName() << " dropped no additional loot.\n";
- break;
- }
- }
- }
- if (p.getLevel() > 6 && p.getLevel() <= 10)
- {
- int x = getRandomNumber(1, 4);
- switch (x)
- {
- case 1:
- {
- std::cout << "The " << m.getName() << " dropped a lesser healing potion!\n";
- p.reduceHealth(-1);
- std::cout << p.getName() << " healed 1 hitpoint and now has " << p.getHealth() << " health.\n";
- break;
- }
- case 2:
- {
- std::cout << "The " << m.getName() << " dropped a damage potion!\n";
- p.increaseDamage(2);
- std::cout << p.getName() << " consumed the potion and now deals " << p.getDamage() << " damage.\n";
- break;
- }
- default:
- {
- std::cout << "The " << m.getName() << " dropped no additional loot.\n";
- break;
- }
- }
- }
- if (p.getLevel() > 10 && p.getLevel() <= 18)
- {
- int x = getRandomNumber(1, 5);
- switch (x)
- {
- case 1:
- {
- std::cout << "The " << m.getName() << " dropped a healing potion!\n";
- p.reduceHealth(-2);
- std::cout << p.getName() << " healed 2 hitpoints and now has " << p.getHealth() << " health.\n";
- break;
- }
- case 2:
- {
- std::cout << "The " << m.getName() << " dropped a damage potion!\n";
- p.increaseDamage(2);
- std::cout << p.getName() << " consumed the potion and now deals " << p.getDamage() << " damage.\n";
- break;
- }
- case 3:
- {
- std::cout << "The " << m.getName() << " dropped a greater healing potion!\n";
- p.reduceHealth(-3);
- std::cout << p.getName() << " healed 3 hitpoints and now has " << p.getHealth() << " health.\n";
- break;
- }
- default:
- {
- std::cout << "The " << m.getName() << " dropped no additional loot.\n";
- break;
- }
- }
- }
- }
- void getEnemyDeathMessage(Player &p, Monster &m)
- {
- int x = getRandomNumber(1, 11);
- switch (x)
- {
- case 1:
- std::cout << "The " << m.getName() << "'s head was removed by " << p.getName() << ".\n";
- break;
- case 2:
- std::cout << "The " << m.getName() << " was impaled by " << p.getName() << ".\n";
- break;
- case 3:
- std::cout << "The " << m.getName() << " got rekt lol.\n";
- break;
- case 4:
- std::cout << "The " << m.getName() << " was decapitated by " << p.getName() << ".\n";
- break;
- case 5:
- std::cout << p.getName() << " brutally dissected the " << m.getName() << ".\n";
- break;
- case 6:
- std::cout << p.getName() << " cut the " << m.getName() << " in half.\n";
- break;
- case 7:
- std::cout << p.getName() << " eviscerated the " << m.getName() << ".\n";
- break;
- case 8:
- std::cout << "The " << m.getName() << " was torn in half by " << p.getName() << ".\n";
- break;
- case 9:
- std::cout << p.getName() << " murdered the " << m.getName() << ".\n";
- break;
- case 10:
- std::cout << "The " << m.getName() << " was turned into a pile of flesh by " << p.getName() << ".\n";
- break;
- case 11:
- std::cout << "The " << m.getName() << " has it's neck broken by " << p.getName() << ".\n";
- }
- }
- void attackMonster(Player &p, Monster &m)
- {
- if (p.isDead())
- return;
- std::cout << "You hit the " << m.getName() << " for " << p.getDamage() << " damage!\n";
- m.reduceHealth(p.getDamage());
- if (m.isDead())
- {
- getEnemyDeathMessage(p, m);
- p.levelUp();
- std::cout << "You are now level " << p.getLevel() << "!\n";
- std::cout << "You found " << m.getGold() << " gold!\n";
- p.addGold(m.getGold());
- otherLoot(p, m);
- }
- }
- void attackPlayer(Player &p, Monster &m)
- {
- if (m.isDead())
- return;
- p.reduceHealth(m.getDamage());
- std::cout << "The " << m.getName() << " hit you for " << m.getDamage() << " damage!\n";
- }
- void shop(Player &p)
- {
- std::cout << "You have located a shop!\n";
- std::cout << "You have " << p.getGold() << " gold to use.\n";
- buy:
- std::cout << "You can buy lesser (d)amage potions and (h)ealth potions for 30 gold. You can also (l)eave if you wish: ";
- char choice;
- std::cin >> choice;
- if (choice == 'd' || choice == 'D')
- {
- if (p.getGold() < 30)
- {
- std::cout << "You don't have enough gold!\n";
- goto buy;
- }
- else
- {
- std::cout << p.getName() << " bought the damage potion for 30 gold.\n";
- p.increaseDamage(1);
- p.addGold(-30);
- std::cout << p.getName() << " consumed the potion and now deals " << p.getDamage() << " damage.\n";
- std::cout << "You now have " << p.getGold() << " gold.\n";
- goto buy;
- }
- }
- if (choice == 'h' || choice == 'h')
- {
- if (p.getGold() < 30)
- {
- std::cout << "You don't have enough gold!\n";
- goto buy;
- }
- else
- {
- std::cout << p.getName() << " bought the health potion for 30 gold.\n";
- p.reduceHealth(-2);
- p.addGold(-30);
- std::cout << p.getName() << " healed 2 hitpoints and now has " << p.getHealth() << " health.\n";
- std::cout << "You now have " << p.getGold() << " gold.\n";
- goto buy;
- }
- }
- if (choice == 'l' || choice == 'L')
- {
- std::cout << p.getName() << " left the store with " << p.getHealth() << " health, the ability to deal " <<
- p.getDamage() << " damage, and " << p.getGold() << " gold remaining.\n";
- return;
- }
- goto buy;
- }
- void fightMonster(Player &p)
- {
- if (p.getLevel() == 5 || p.getLevel() == 10 || p.getLevel() == 15 || p.getLevel() == 18)
- shop(p);
- Monster m = Monster::getRandomMonster(p);
- std::cout << "You have encountered a " << m.getName() << " (" << m.getSymbol() << ")\n";
- while (!m.isDead() && !p.isDead())
- {
- health:
- std::cout << "(R)un, (F)ight, check your (S)tatus or your (E)nemy's status: ";
- char input;
- std::cin >> input;
- if (input == 'S' || input == 's')
- {
- std::cout << p.getName() << " currently has " << p.getHealth() << " health, does " << p.getDamage() << " damage and has " << p.getGold() << " gold.\n";
- goto health;
- }
- if (input == 'E' || input == 'e')
- {
- std::cout << "The " << m.getName() << " currently has " << m.getHealth() << " health, does " << m.getDamage() << " damage and has " << m.getGold() << " gold.\n";
- goto health;
- }
- if (input == 'R' || input == 'r')
- {
- if (p.getLevel() == 18 || p.getLevel() == 19)
- {
- std::cout << "You cannot flee from this enemy!\n";
- goto health;
- }
- if (getRandomNumber(1, 2) == 1)
- {
- std::cout << "You successfully fled the " << m.getName() << ".\n";
- return;
- }
- else
- {
- std::cout << "You failed to flee the " << m.getName() << "!\n";
- attackPlayer(p, m);
- continue;
- }
- }
- if (input == 'F' || input == 'f')
- {
- attackMonster(p, m);
- attackPlayer(p, m);
- }
- if (std::cin.fail())
- {
- std::cin.clear();
- std::cin.ignore(32767, '\n');
- input = 'm';
- }
- }
- }
- std::string deathMessage()
- {
- int x = getRandomNumber(1, 15);
- switch (x)
- {
- case 1:
- return "had their face ripped off";
- case 2:
- return "was impaled";
- case 3:
- return "got rekt lol";
- case 4:
- return "was crushed";
- case 5:
- return "is someone's dinner";
- case 6:
- return "forgot how to fight";
- case 7:
- return "was slain";
- case 8:
- return "was eviscerated";
- case 9:
- return "was murdered";
- case 10:
- return "was brutally dissected";
- case 11:
- return "was decapitated";
- case 12:
- return "was torn in half";
- case 13:
- return "was turned into a pile of flesh";
- case 14:
- return "died. Simple as that";
- case 15:
- return "was torn in half";
- }
- }
- std::string winMessage()
- {
- int x = getRandomNumber(1, 5);
- switch (x)
- {
- case 1:
- return "rekt all the scrubs";
- case 2:
- return "proved the haters wrong";
- case 3:
- return "murdered all the slimes and dragons and crap";
- case 4:
- return "is going a bit insane";
- case 5:
- return "stands undefeated";
- }
- }
- int main()
- {
- srand(static_cast<unsigned int>(time(0))); // set initial seed value to system clock
- rand(); // get rid of first result
- std::string name;
- std::cout << "Enter your name: ";
- std::cin >> name;
- Player p(name);
- std::cout << "Welcome, " << p.getName() << "." << std::endl;
- while (!p.isDead() && !p.hasWon())
- fightMonster(p);
- if (p.isDead())
- {
- std::cout << p.getName() << " " << deathMessage() << ".\n";
- std::cout << p.getName() << " died at level " << p.getLevel() << " with " << p.getGold() << " gold.\n";
- }
- else
- {
- std::cout << p.getName() << " " << winMessage() << " and has won!\n";
- std::cout << p.getName() << " has won the game with " << p.getGold() << " gold! Congrats!\n";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement