You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

401 lines
12 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. #include <iostream>
  2. #include <thread>
  3. #include <chrono>
  4. #include <random>
  5. #include <fstream>
  6. #include "lib/Character.hpp"
  7. #include "lib/Spell.hpp"
  8. #define INTERVAL 1000
  9. #define FLAG_INTERVAL 250
  10. Spell spellBook[] = {
  11. Spell("Spanish Inquisition", 1, 111111, 0),
  12. Spell("Mana Bolt", 1, 5, 1),
  13. Spell("Flame Bolt", 1, 8, 2),
  14. Spell("Mana Flare", 1, 10, 3),
  15. Spell("Ice Spear", 1, 13, 4),
  16. Spell("Mana Misile", 1, 15, 5),
  17. Spell("Thunder Strike", 1, 18, 6),
  18. Spell("Mana Blast", 1, 20, 7),
  19. };
  20. void sleep(int ms)
  21. {
  22. std::this_thread::sleep_for(std::chrono::milliseconds(ms));
  23. }
  24. int strlen(const char *msg)
  25. {
  26. int i = 0;
  27. while (msg[i] != '\x00')
  28. {
  29. i++;
  30. }
  31. return i;
  32. }
  33. int getLowest(int a, int b)
  34. {
  35. return (a < b) ? a : b;
  36. }
  37. int getHighest(int a, int b)
  38. {
  39. return (a > b) ? a : b;
  40. }
  41. void intervalPrint(const char *msg, int interval = 1000, int len = 0)
  42. {
  43. if (len <= 0)
  44. {
  45. len = strlen(msg);
  46. }
  47. for (int i = 0; i < len; i++)
  48. {
  49. std::cout << msg[i] << std::flush;
  50. std::this_thread::sleep_for(std::chrono::milliseconds(interval));
  51. }
  52. std::cout << std::endl;
  53. }
  54. void intervalPrint(std::string &msg, int interval = 1000, int len = 0)
  55. {
  56. if (len <= 0)
  57. {
  58. len = msg.length();
  59. }
  60. for (int i = 0; i < len; i++)
  61. {
  62. std::cout << msg.at(i) << std::flush;
  63. std::this_thread::sleep_for(std::chrono::milliseconds(interval));
  64. }
  65. std::cout << std::endl;
  66. }
  67. int getNumber(const char *prompt, int min, int max)
  68. {
  69. int tmp = 0;
  70. std::cout << prompt;
  71. while (!(std::cin >> tmp) && (tmp >= min && tmp <= max))
  72. {
  73. if (std::cin.eofbit)
  74. {
  75. exit(1);
  76. }
  77. std::cin.get();
  78. std::cin.clear();
  79. std::cin.ignore(4096, '\x00');
  80. // std::cin.ignore(4096, '\n');
  81. std::cout << prompt;
  82. }
  83. return tmp;
  84. }
  85. Character *chooseEnemy()
  86. {
  87. Character Enemies[] = {
  88. Character("Red Mage", 1, 1, 10, 5, 1, 1),
  89. Character("Green Mage", 2, 3, 20, 10, 1, 1),
  90. Character("Blue Mage", 3, 7, 40, 25, 1, 1),
  91. Character("White Mage", 4, 11, 80, 40, 1, 1),
  92. Character("Black Mage", 5, 16, 160, 80, 1, 1),
  93. };
  94. std::cout << "List of challenger:" << std::endl;
  95. for (int i = 0; i < 5; i++)
  96. {
  97. std::cout << "[" << i << "] " << Enemies[i].getName() << std::endl;
  98. }
  99. int choice = 0;
  100. choice = getNumber("Choose your enemy: ", 0, 4);
  101. return new Character(Enemies[choice]);
  102. }
  103. Character *generatePlayer()
  104. {
  105. const char *playerNames[] = {
  106. "Abby",
  107. "John",
  108. "Adam",
  109. "Johny",
  110. "Christo",
  111. "Greg",
  112. };
  113. Character *tmp = new Character(
  114. playerNames[std::rand() % 6],
  115. 1,
  116. 1,
  117. 100,
  118. 50,
  119. 1,
  120. 1);
  121. return tmp;
  122. }
  123. std::string loadFlag()
  124. {
  125. std::string tmp;
  126. std::ifstream flagFile("flag.txt");
  127. if (flagFile.is_open())
  128. {
  129. flagFile >> tmp;
  130. }
  131. return tmp;
  132. }
  133. void printCharacterInfo(Character *c)
  134. {
  135. std::cout << "Name : " << c->getName() << std::endl
  136. << "HP : " << c->getCurHP() << "/" << c->getMaxHP() << std::endl
  137. << "MP : " << c->getCurMP() << "/" << c->getMaxMP() << std::endl;
  138. }
  139. void printCharacterFullInfo(Character *c)
  140. {
  141. std::cout << "Name : " << c->getName() << std::endl
  142. << "Level: " << c->getLevel() << std::endl
  143. << "Exp : " << c->getExperience() << " | next: " << c->toNextLevel() << std::endl
  144. << "HP : " << c->getCurHP() << "/" << c->getMaxHP() << std::endl
  145. << "MP : " << c->getCurMP() << "/" << c->getMaxMP() << std::endl;
  146. }
  147. Character *startBattle(Character *p1, Character *p2)
  148. {
  149. int maxTurn = 1000;
  150. int turn = 0;
  151. std::cout << "===== BATTLE START ======" << std::endl;
  152. while ((p1->isAlive() && p2->isAlive()) && (++turn <= maxTurn))
  153. {
  154. std::cout << "== Turn " << turn << " ==" << std::endl;
  155. std::cout << "Player =====" << std::endl;
  156. printCharacterInfo(p1);
  157. std::cout << "Enemy ======" << std::endl;
  158. printCharacterInfo(p2);
  159. std::cout << "===== Spell Books =====" << std::endl;
  160. for (int i = 1; i <= p1->getLevel() && i < 8; i++)
  161. {
  162. std::cout << "[" << i << "] " << spellBook[i].getName() << std::endl;
  163. }
  164. int p1Choice = getNumber("Choose your spell: ", 0, getLowest(p1->getLevel(), 8 - 1));
  165. int p2Choice = (std::rand() % getLowest(p2->getLevel(), 8 - 1)) + 1;
  166. Spell *p1Spell = &spellBook[p1Choice];
  167. Spell *p2Spell = &spellBook[p2Choice];
  168. if (p1->canCastSpell(p1Spell))
  169. {
  170. p1->castSpell(p1Spell, p2);
  171. std::cout << p1->getName() << " cast " << p1Spell->getName() << std::endl;
  172. sleep(INTERVAL);
  173. std::cout << p2->getName() << " took " << p1Spell->getAmount() << " damage" << std::endl;
  174. sleep(INTERVAL);
  175. }
  176. else
  177. {
  178. std::cout << p1->getName() << " failed to cast " << p1Spell->getName() << std::endl;
  179. sleep(INTERVAL);
  180. std::cout << p1->getName() << " does not have enough MP to cast it!" << std::endl;
  181. sleep(INTERVAL);
  182. }
  183. if (p2->canCastSpell(p2Spell))
  184. {
  185. p2->castSpell(p2Spell, p1);
  186. std::cout << p2->getName() << " cast " << p2Spell->getName() << std::endl;
  187. sleep(INTERVAL);
  188. std::cout << p1->getName() << " took " << p2Spell->getAmount() << " damage" << std::endl;
  189. sleep(INTERVAL);
  190. }
  191. else
  192. {
  193. std::cout << p2->getName() << " failed to cast " << p2Spell->getName() << std::endl;
  194. sleep(INTERVAL);
  195. std::cout << p2->getName() << " does not have enough MP to cast it!" << std::endl;
  196. sleep(INTERVAL);
  197. }
  198. }
  199. Character *winner;
  200. if (turn >= maxTurn)
  201. {
  202. std::cout << "The battle took too long, a winner has to be decided." << std::endl;
  203. winner = (p1->getCurHP() > p2->getCurHP()) ? p1 : p2;
  204. }
  205. else
  206. {
  207. winner = (p1->isAlive()) ? p1 : p2;
  208. }
  209. return winner;
  210. }
  211. int main()
  212. {
  213. std::srand(std::time(0));
  214. std::string flag = loadFlag();
  215. Character *player = generatePlayer();
  216. Character *archMage = new Character("Arch-Mage", 999, 999999, 999999, 999999, 1, 1);
  217. std::cout << "Welcome to SpellWarz!" << std::endl;
  218. sleep(INTERVAL);
  219. std::cout << "You are a young mage named '" << player->getName() << "'" << std::endl;
  220. sleep(INTERVAL);
  221. std::cout << "Here's your flag: ";
  222. intervalPrint(flag, FLAG_INTERVAL, 10);
  223. std::cout << "Oh no!" << std::endl;
  224. sleep(INTERVAL);
  225. std::cout << "The Arch-Mage took your flag!" << std::endl;
  226. sleep(INTERVAL);
  227. std::cout << "He said you are not worthy of it," << std::endl;
  228. sleep(INTERVAL);
  229. std::cout << "defeat him to get it back!" << std::endl;
  230. sleep(INTERVAL);
  231. while (player->isAlive())
  232. {
  233. std::cout << "========================================" << std::endl;
  234. printCharacterFullInfo(player);
  235. std::cout << "========================================" << std::endl
  236. << "[1] Sleep" << std::endl
  237. << "[2] Meditate" << std::endl
  238. << "[3] Spar with other mages" << std::endl
  239. << "[4] Search info about Arch-Mage" << std::endl
  240. << "[5] Challenge the Arch-Mage" << std::endl
  241. << "[0] Give up on life" << std::endl;
  242. int choice = getNumber("Choose your action: ", 0, 5);
  243. std::cout << "========================================" << std::endl;
  244. if (choice == 0)
  245. {
  246. std::cout << "Farewell young mage, see you in the afterlife..." << std::endl;
  247. player->reduceHP(player->getMaxHP());
  248. }
  249. if (choice == 1)
  250. {
  251. std::cout << "You take a rest in your dormitory..." << std::endl;
  252. sleep(INTERVAL);
  253. std::cout << "You recovered to full HP and MP" << std::endl;
  254. sleep(INTERVAL);
  255. player->restoreHP(player->getMaxHP());
  256. player->restoreMP(player->getMaxMP());
  257. }
  258. if (choice == 2)
  259. {
  260. int tmp;
  261. tmp = (rand() % 10) + 1;
  262. std::cout << "You meditate on your mana..." << std::endl;
  263. sleep(INTERVAL);
  264. std::cout << "And got " << tmp << " experience!" << std::endl;
  265. sleep(INTERVAL);
  266. player->increaseExperience(tmp);
  267. if (player->readytoLevelUp())
  268. {
  269. std::cout << "Congratulations, you leveled up!" << std::endl;
  270. while (player->readytoLevelUp())
  271. {
  272. player->levelUp();
  273. }
  274. sleep(200);
  275. }
  276. }
  277. if (choice == 3)
  278. {
  279. Character *enemy = new Character(*chooseEnemy());
  280. Character *winner = startBattle(player, enemy);
  281. if (winner == player)
  282. {
  283. std::cout << "You win! You got " << enemy->getExperience() << "exp" << std::endl;
  284. sleep(INTERVAL);
  285. player->increaseExperience(enemy->getExperience());
  286. if (player->readytoLevelUp())
  287. {
  288. std::cout << "Congratulations, you leveled up!" << std::endl;
  289. while (player->readytoLevelUp())
  290. {
  291. player->levelUp();
  292. }
  293. sleep(200);
  294. }
  295. }
  296. else
  297. {
  298. while (!player->isAlive())
  299. {
  300. player->restoreHP(1);
  301. }
  302. std::cout << "You lose the fight, it was a fair fight." << std::endl;
  303. sleep(INTERVAL);
  304. }
  305. }
  306. if (choice == 4)
  307. {
  308. std::cout << "You are searching info about the Arch-Mage..." << std::endl;
  309. sleep(INTERVAL);
  310. std::cout << "Here's some info about the Arch-Mage:" << std::endl;
  311. printCharacterFullInfo(archMage);
  312. }
  313. if (choice == 5)
  314. {
  315. if (archMage->isAlive())
  316. {
  317. std::cout << "You are challenging the Arch-Mage" << std::endl;
  318. sleep(INTERVAL);
  319. std::cout << "Arch-Mage: ";
  320. sleep(INTERVAL);
  321. intervalPrint("so you have come to challenge me. Prepare to die!", 200);
  322. Character *winner = startBattle(player, archMage);
  323. if (winner == player)
  324. {
  325. std::cout << "You win! You got " << archMage->getExperience() << "exp" << std::endl;
  326. player->increaseExperience(archMage->getExperience());
  327. sleep(INTERVAL);
  328. if (player->readytoLevelUp())
  329. {
  330. std::cout << "Congratulations, you leveled up!" << std::endl;
  331. while (player->readytoLevelUp())
  332. {
  333. player->levelUp();
  334. }
  335. sleep(200);
  336. }
  337. std::cout << "You did a good job! Now you are the Arch-Mage!" << std::endl;
  338. sleep(INTERVAL);
  339. std::cout << "Here's the flag the previous Arch-Mage took from you: " << std::endl;
  340. sleep(INTERVAL);
  341. intervalPrint(flag, FLAG_INTERVAL);
  342. }
  343. else
  344. {
  345. std::cout << "You lose the fight..." << std::endl;
  346. sleep(INTERVAL);
  347. std::cout << "Unfortunately, the Arch-Mage was serious about this fight..." << std::endl;
  348. sleep(INTERVAL);
  349. std::cout << "You were killed in battle..." << std::endl;
  350. intervalPrint("GAME OVER", 250);
  351. }
  352. }
  353. else
  354. {
  355. std::cout << "You are the Arch-Mage now." << std::endl;
  356. sleep(INTERVAL);
  357. std::cout << "Here's your flag:";
  358. sleep(INTERVAL);
  359. intervalPrint(flag, FLAG_INTERVAL);
  360. }
  361. }
  362. }
  363. }