Advertisement
Guest User

Simple Text-based C++ Adventure Program

a guest
Oct 18th, 2018
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.17 KB | None | 0 0
  1.  
  2. #include <iostream>
  3. #include <cmath>
  4. #include <string>
  5. #include <cstdlib>
  6. #include <ctime>
  7. #include <algorithm>
  8. #include <utility>
  9. #include <array>
  10. #include <vector>
  11. #include <cassert>
  12. #include <cstdint>
  13. #include <initializer_list>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <time.h>
  17.  
  18.  
  19. //another update to the game. Makes the game a bit easier as the previous version had some enemies that did too much damage.
  20. int getRandomNumber(int min, int max)
  21. {
  22. static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0); // static used for efficiency, so we only calculate this value once
  23. // evenly distribute the random number across our range
  24. return static_cast<int>(rand() * fraction * (max - min + 1) + min);
  25. }
  26.  
  27. class Creature
  28. {
  29. protected: //note that the members are protected, meaning derived classes can access them.
  30. std::string m_name;
  31. char m_symbol;
  32. int m_health;
  33. int m_damage;
  34. int m_gold;
  35. public:
  36. Creature(std::string name, char symbol, int health, int damage, int gold) :
  37. m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold) {}
  38. std::string getName() { return m_name; }
  39. char getSymbol() { return m_symbol; }
  40. int getHealth() { return m_health; }
  41. int getDamage() { return m_damage; }
  42. int getGold() { return m_gold; }
  43.  
  44. void reduceHealth(int healthLost) { m_health -= healthLost; }
  45. bool isDead() { return m_health <= 0; }
  46. void addGold(int goldGained) { m_gold += goldGained; }
  47. };
  48.  
  49. class Player : public Creature
  50. {
  51. int m_level = 1;
  52. public:
  53. Player(std::string name) : Creature(name, '@', 10, 1, 0) {}
  54. int getLevel() { return m_level; }
  55. void increaseDamage(int x) { m_damage += x; }
  56. void levelUp()
  57. {
  58. ++m_level;
  59. ++m_damage;
  60. }
  61. bool hasWon() { return m_level >= 20; }
  62. };
  63.  
  64. class Monster : public Creature
  65. {
  66. public:
  67. enum Type
  68. {
  69. SLIME,
  70. GREMLIN,
  71. GOBLIN,
  72. ZOMBIE,
  73. TROLL,
  74. GHOST,
  75. ORC,
  76. SCORPION,
  77. REVENANT,
  78. DRYAD,
  79. BASILISK,
  80. GIANT_SPIDER,
  81. WRAITH,
  82. STONE_GOLEM,
  83. BANSHEE,
  84. GIANT_SLIME,
  85. GIANT_HORNET,
  86. OGRE,
  87. POLTERGEIST,
  88. WINDIGO,
  89. YOUNG_DRAGON,
  90. MAX_TYPES
  91. };
  92.  
  93. struct MonsterData
  94. {
  95. const char* name;
  96. char symbol;
  97. int health;
  98. int damage;
  99. int gold;
  100. };
  101.  
  102. static MonsterData monsterData[MAX_TYPES];
  103. Monster(Type type) :
  104. Creature(monsterData[type].name, monsterData[type].symbol, monsterData[type].health, monsterData[type].damage,
  105. monsterData[type].gold)
  106. {
  107. }
  108.  
  109. static Monster getRandomMonster(Player &p)
  110. {
  111. if (p.getLevel() == 1 || p.getLevel() == 2 || p.getLevel() == 3)
  112. {
  113. int num = getRandomNumber(0, GOBLIN);
  114. return Monster(static_cast<Type>(num));
  115. }
  116. if (p.getLevel() == 4)
  117. {
  118. int num = getRandomNumber(GOBLIN, GHOST);
  119. return Monster(static_cast<Type>(num));
  120. }
  121. if (p.getLevel() == 5 || p.getLevel() == 6)
  122. {
  123. int num = getRandomNumber(ZOMBIE, GHOST);
  124. return Monster(static_cast<Type>(num));
  125. }
  126. if (p.getLevel() == 7)
  127. {
  128. int num = getRandomNumber(GHOST, REVENANT);
  129. return Monster(static_cast<Type>(num));
  130. }
  131. if (p.getLevel() >= 8 && p.getLevel() <=9)
  132. {
  133. int num = getRandomNumber(ORC, REVENANT);
  134. return Monster(static_cast<Type>(num));
  135. }
  136. if (p.getLevel() == 10)
  137. {
  138. int num = getRandomNumber(REVENANT, GIANT_SPIDER);
  139. return Monster(static_cast<Type>(num));
  140. }
  141. if (p.getLevel() == 11 || p.getLevel() == 12) //switched symbols as it's easier to understand
  142. {
  143. int num = getRandomNumber(DRYAD, GIANT_SPIDER);
  144. return Monster(static_cast<Type>(num));
  145. }
  146. if (p.getLevel() == 13)
  147. {
  148. int num = getRandomNumber(GIANT_SPIDER, BANSHEE);
  149. return Monster(static_cast<Type>(num));
  150. }
  151. if (p.getLevel() == 14 || p.getLevel() == 15)
  152. {
  153. int num = getRandomNumber(WRAITH, BANSHEE);
  154. return Monster(static_cast<Type>(num));
  155. }
  156. if (p.getLevel() == 16)
  157. {
  158. int num = getRandomNumber(GIANT_SLIME, GIANT_HORNET);
  159. return Monster(static_cast<Type>(num));
  160. }
  161. if (p.getLevel() == 17)
  162. {
  163. int num = getRandomNumber(OGRE, POLTERGEIST);
  164. return Monster(static_cast<Type>(num));
  165. }
  166. if (p.getLevel() == 18)
  167. {
  168. int num = WINDIGO;
  169. return Monster(static_cast<Type>(num));
  170. }
  171. if (p.getLevel() == 19)
  172. {
  173. int num = YOUNG_DRAGON;
  174. return Monster(static_cast<Type>(num));
  175. }
  176. }
  177.  
  178. };
  179.  
  180. Monster::MonsterData Monster::monsterData[Monster::MAX_TYPES]
  181. {
  182. { "slime", 's', 1, 1, getRandomNumber(5,10) }, //level 1-3
  183. { "gremlin", 'G', getRandomNumber(1,2), getRandomNumber(1,2),getRandomNumber(10,15)}, //level 1-3
  184. { "goblin", 'g', getRandomNumber(2,4), getRandomNumber(1,2), getRandomNumber(15,20)}, //level 1-4
  185. { "zombie", 'z', getRandomNumber(4,6), getRandomNumber(2,3), getRandomNumber(20,25)}, //level 4-6
  186. { "troll", 't', getRandomNumber(4,6), getRandomNumber(2,4), getRandomNumber(15,25)}, //level 4-6
  187. { "ghost", 'h', 7, getRandomNumber(1,2), getRandomNumber(20,28)}, //level 4-7
  188. { "orc", 'o', getRandomNumber(10,11), getRandomNumber(4,5), getRandomNumber(28,35)}, //7-9
  189. { "scorpion", 's', getRandomNumber(9,10), getRandomNumber(5,6), getRandomNumber(30,36)}, //7-9
  190. { "revenant", 'r', getRandomNumber(9,11), getRandomNumber(4,4), getRandomNumber(33,35)}, //7-10
  191. { "dryad", 'd', getRandomNumber(13,15), getRandomNumber(5,6), getRandomNumber(34,40)}, //10-12
  192. { "basilisk", 'b', getRandomNumber(14,16), getRandomNumber(4,5), getRandomNumber(34,41)}, //10-12
  193. { "giant spider", 'S', getRandomNumber(16,17), getRandomNumber(5,6), getRandomNumber(35,45)}, //10-13
  194. { "wraith", 'W', getRandomNumber(20,24), getRandomNumber(6,7), getRandomNumber(40,50)}, //13-15
  195. { "stone golem", 'g', getRandomNumber(30,35), getRandomNumber(5,6) ,getRandomNumber(45,52)}, //13-15
  196. { "banshee", 'b', getRandomNumber(25,28), getRandomNumber(6,7), getRandomNumber(45,54)}, //13-15
  197. { "giant slime", 'G', getRandomNumber(30,32), getRandomNumber(7,8), 55}, //16
  198. { "giant hornet", 'H', getRandomNumber(30,32), getRandomNumber(7,8), 55}, //16
  199. { "ogre", 'O', getRandomNumber(32,34), getRandomNumber(8,10), getRandomNumber(56,58)}, //17
  200. { "poltergeist", 'P', getRandomNumber(33,35), getRandomNumber(8,10), getRandomNumber(56,59)}, //17
  201. { "windigo", 'W', getRandomNumber(40,42), getRandomNumber(12,13), getRandomNumber(80,85)}, //18
  202. { "young dragon", 'D', getRandomNumber(50,50), getRandomNumber(15,15), getRandomNumber(99,101)} //19
  203. };
  204.  
  205. void otherLoot(Player &p, Monster &m)
  206. {
  207. if (m.getName() == "windigo")
  208. {
  209. std::cout << "The " << m.getName() << " dropped a greater healing potion!\n";
  210. p.reduceHealth(-3);
  211. std::cout << p.getName() << " healed 3 hitpoints and now has " << p.getHealth() << " health.\n";
  212. std::cout << "The " << m.getName() << " also dropped a damage potion!\n";
  213. p.increaseDamage(2);
  214. std::cout << p.getName() << " consumed the potion and now deals " << p.getDamage() << " damage.\n";
  215. return;
  216. }
  217.  
  218. if (p.getLevel() <= 6)
  219. {
  220. int x = getRandomNumber(1, 3);
  221. switch (x)
  222. {
  223. case 1:
  224. {
  225. std::cout << "The " << m.getName() << " dropped a lesser healing potion!\n";
  226. p.reduceHealth(-1);
  227. std::cout << p.getName() << " healed 1 hitpoint and now has " << p.getHealth() << " health.\n";
  228. break;
  229. }
  230. case 2:
  231. {
  232. std::cout << "The " << m.getName() << " dropped a lesser damage potion!\n";
  233. p.increaseDamage(1);
  234. std::cout << p.getName() << " consumed the potion and now deals " << p.getDamage() << " damage.\n";
  235. break;
  236. }
  237. default:
  238. {
  239. std::cout << "The " << m.getName() << " dropped no additional loot.\n";
  240. break;
  241. }
  242. }
  243. }
  244.  
  245. if (p.getLevel() > 6 && p.getLevel() <= 10)
  246. {
  247. int x = getRandomNumber(1, 4);
  248. switch (x)
  249. {
  250. case 1:
  251. {
  252. std::cout << "The " << m.getName() << " dropped a lesser healing potion!\n";
  253. p.reduceHealth(-1);
  254. std::cout << p.getName() << " healed 1 hitpoint and now has " << p.getHealth() << " health.\n";
  255. break;
  256. }
  257. case 2:
  258. {
  259. std::cout << "The " << m.getName() << " dropped a damage potion!\n";
  260. p.increaseDamage(2);
  261. std::cout << p.getName() << " consumed the potion and now deals " << p.getDamage() << " damage.\n";
  262. break;
  263. }
  264. default:
  265. {
  266. std::cout << "The " << m.getName() << " dropped no additional loot.\n";
  267. break;
  268. }
  269. }
  270. }
  271.  
  272. if (p.getLevel() > 10 && p.getLevel() <= 18)
  273. {
  274. int x = getRandomNumber(1, 5);
  275. switch (x)
  276. {
  277. case 1:
  278. {
  279. std::cout << "The " << m.getName() << " dropped a healing potion!\n";
  280. p.reduceHealth(-2);
  281. std::cout << p.getName() << " healed 2 hitpoints and now has " << p.getHealth() << " health.\n";
  282. break;
  283. }
  284. case 2:
  285. {
  286. std::cout << "The " << m.getName() << " dropped a damage potion!\n";
  287. p.increaseDamage(2);
  288. std::cout << p.getName() << " consumed the potion and now deals " << p.getDamage() << " damage.\n";
  289. break;
  290. }
  291. case 3:
  292. {
  293. std::cout << "The " << m.getName() << " dropped a greater healing potion!\n";
  294. p.reduceHealth(-3);
  295. std::cout << p.getName() << " healed 3 hitpoints and now has " << p.getHealth() << " health.\n";
  296. break;
  297. }
  298.  
  299. default:
  300. {
  301. std::cout << "The " << m.getName() << " dropped no additional loot.\n";
  302. break;
  303. }
  304. }
  305. }
  306. }
  307.  
  308. void getEnemyDeathMessage(Player &p, Monster &m)
  309. {
  310. int x = getRandomNumber(1, 11);
  311. switch (x)
  312. {
  313. case 1:
  314. std::cout << "The " << m.getName() << "'s head was removed by " << p.getName() << ".\n";
  315. break;
  316. case 2:
  317. std::cout << "The " << m.getName() << " was impaled by " << p.getName() << ".\n";
  318. break;
  319. case 3:
  320. std::cout << "The " << m.getName() << " got rekt lol.\n";
  321. break;
  322. case 4:
  323. std::cout << "The " << m.getName() << " was decapitated by " << p.getName() << ".\n";
  324. break;
  325. case 5:
  326. std::cout << p.getName() << " brutally dissected the " << m.getName() << ".\n";
  327. break;
  328. case 6:
  329. std::cout << p.getName() << " cut the " << m.getName() << " in half.\n";
  330. break;
  331. case 7:
  332. std::cout << p.getName() << " eviscerated the " << m.getName() << ".\n";
  333. break;
  334. case 8:
  335. std::cout << "The " << m.getName() << " was torn in half by " << p.getName() << ".\n";
  336. break;
  337. case 9:
  338. std::cout << p.getName() << " murdered the " << m.getName() << ".\n";
  339. break;
  340. case 10:
  341. std::cout << "The " << m.getName() << " was turned into a pile of flesh by " << p.getName() << ".\n";
  342. break;
  343. case 11:
  344. std::cout << "The " << m.getName() << " has it's neck broken by " << p.getName() << ".\n";
  345. }
  346. }
  347.  
  348. void attackMonster(Player &p, Monster &m)
  349. {
  350. if (p.isDead())
  351. return;
  352.  
  353. std::cout << "You hit the " << m.getName() << " for " << p.getDamage() << " damage!\n";
  354. m.reduceHealth(p.getDamage());
  355. if (m.isDead())
  356. {
  357. getEnemyDeathMessage(p, m);
  358. p.levelUp();
  359. std::cout << "You are now level " << p.getLevel() << "!\n";
  360. std::cout << "You found " << m.getGold() << " gold!\n";
  361. p.addGold(m.getGold());
  362. otherLoot(p, m);
  363. }
  364. }
  365.  
  366. void attackPlayer(Player &p, Monster &m)
  367. {
  368. if (m.isDead())
  369. return;
  370. p.reduceHealth(m.getDamage());
  371. std::cout << "The " << m.getName() << " hit you for " << m.getDamage() << " damage!\n";
  372.  
  373. }
  374.  
  375. void shop(Player &p)
  376. {
  377. std::cout << "You have located a shop!\n";
  378. std::cout << "You have " << p.getGold() << " gold to use.\n";
  379. buy:
  380. std::cout << "You can buy lesser (d)amage potions and (h)ealth potions for 30 gold. You can also (l)eave if you wish: ";
  381. char choice;
  382. std::cin >> choice;
  383. if (choice == 'd' || choice == 'D')
  384. {
  385. if (p.getGold() < 30)
  386. {
  387. std::cout << "You don't have enough gold!\n";
  388. goto buy;
  389. }
  390. else
  391. {
  392. std::cout << p.getName() << " bought the damage potion for 30 gold.\n";
  393. p.increaseDamage(1);
  394. p.addGold(-30);
  395. std::cout << p.getName() << " consumed the potion and now deals " << p.getDamage() << " damage.\n";
  396. std::cout << "You now have " << p.getGold() << " gold.\n";
  397. goto buy;
  398. }
  399. }
  400. if (choice == 'h' || choice == 'h')
  401. {
  402. if (p.getGold() < 30)
  403. {
  404. std::cout << "You don't have enough gold!\n";
  405. goto buy;
  406. }
  407. else
  408. {
  409. std::cout << p.getName() << " bought the health potion for 30 gold.\n";
  410. p.reduceHealth(-2);
  411. p.addGold(-30);
  412. std::cout << p.getName() << " healed 2 hitpoints and now has " << p.getHealth() << " health.\n";
  413. std::cout << "You now have " << p.getGold() << " gold.\n";
  414. goto buy;
  415. }
  416. }
  417. if (choice == 'l' || choice == 'L')
  418. {
  419. std::cout << p.getName() << " left the store with " << p.getHealth() << " health, the ability to deal " <<
  420. p.getDamage() << " damage, and " << p.getGold() << " gold remaining.\n";
  421. return;
  422. }
  423. goto buy;
  424. }
  425.  
  426. void fightMonster(Player &p)
  427. {
  428. if (p.getLevel() == 5 || p.getLevel() == 10 || p.getLevel() == 15 || p.getLevel() == 18)
  429. shop(p);
  430. Monster m = Monster::getRandomMonster(p);
  431. std::cout << "You have encountered a " << m.getName() << " (" << m.getSymbol() << ")\n";
  432.  
  433. while (!m.isDead() && !p.isDead())
  434. {
  435. health:
  436. std::cout << "(R)un, (F)ight, check your (S)tatus or your (E)nemy's status: ";
  437. char input;
  438. std::cin >> input;
  439. if (input == 'S' || input == 's')
  440. {
  441. std::cout << p.getName() << " currently has " << p.getHealth() << " health, does " << p.getDamage() << " damage and has " << p.getGold() << " gold.\n";
  442. goto health;
  443. }
  444. if (input == 'E' || input == 'e')
  445. {
  446. std::cout << "The " << m.getName() << " currently has " << m.getHealth() << " health, does " << m.getDamage() << " damage and has " << m.getGold() << " gold.\n";
  447. goto health;
  448. }
  449. if (input == 'R' || input == 'r')
  450. {
  451. if (p.getLevel() == 18 || p.getLevel() == 19)
  452. {
  453. std::cout << "You cannot flee from this enemy!\n";
  454. goto health;
  455. }
  456. if (getRandomNumber(1, 2) == 1)
  457. {
  458. std::cout << "You successfully fled the " << m.getName() << ".\n";
  459. return;
  460. }
  461. else
  462. {
  463. std::cout << "You failed to flee the " << m.getName() << "!\n";
  464. attackPlayer(p, m);
  465. continue;
  466. }
  467. }
  468. if (input == 'F' || input == 'f')
  469. {
  470. attackMonster(p, m);
  471. attackPlayer(p, m);
  472. }
  473. if (std::cin.fail())
  474. {
  475. std::cin.clear();
  476. std::cin.ignore(32767, '\n');
  477. input = 'm';
  478. }
  479. }
  480.  
  481. }
  482.  
  483. std::string deathMessage()
  484. {
  485. int x = getRandomNumber(1, 15);
  486. switch (x)
  487. {
  488. case 1:
  489. return "had their face ripped off";
  490. case 2:
  491. return "was impaled";
  492. case 3:
  493. return "got rekt lol";
  494. case 4:
  495. return "was crushed";
  496. case 5:
  497. return "is someone's dinner";
  498. case 6:
  499. return "forgot how to fight";
  500. case 7:
  501. return "was slain";
  502. case 8:
  503. return "was eviscerated";
  504. case 9:
  505. return "was murdered";
  506. case 10:
  507. return "was brutally dissected";
  508. case 11:
  509. return "was decapitated";
  510. case 12:
  511. return "was torn in half";
  512. case 13:
  513. return "was turned into a pile of flesh";
  514. case 14:
  515. return "died. Simple as that";
  516. case 15:
  517. return "was torn in half";
  518. }
  519. }
  520.  
  521. std::string winMessage()
  522. {
  523. int x = getRandomNumber(1, 5);
  524. switch (x)
  525. {
  526. case 1:
  527. return "rekt all the scrubs";
  528. case 2:
  529. return "proved the haters wrong";
  530. case 3:
  531. return "murdered all the slimes and dragons and crap";
  532. case 4:
  533. return "is going a bit insane";
  534. case 5:
  535. return "stands undefeated";
  536. }
  537.  
  538. }
  539.  
  540. int main()
  541. {
  542. srand(static_cast<unsigned int>(time(0))); // set initial seed value to system clock
  543. rand(); // get rid of first result
  544. std::string name;
  545. std::cout << "Enter your name: ";
  546. std::cin >> name;
  547. Player p(name);
  548. std::cout << "Welcome, " << p.getName() << "." << std::endl;
  549. while (!p.isDead() && !p.hasWon())
  550. fightMonster(p);
  551.  
  552. if (p.isDead())
  553. {
  554. std::cout << p.getName() << " " << deathMessage() << ".\n";
  555. std::cout << p.getName() << " died at level " << p.getLevel() << " with " << p.getGold() << " gold.\n";
  556. }
  557. else
  558. {
  559. std::cout << p.getName() << " " << winMessage() << " and has won!\n";
  560. std::cout << p.getName() << " has won the game with " << p.getGold() << " gold! Congrats!\n";
  561. }
  562. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement