myitinos 5 роки тому
джерело
коміт
663c0602ac
11 змінених файлів з 319 додано та 50 видалено
  1. +6
    -6
      Makefile
  2. +107
    -0
      lib/BattleInterface.cpp
  3. +10
    -4
      lib/BattleInterface.hpp
  4. +32
    -6
      lib/Character.cpp
  5. +6
    -4
      lib/Character.hpp
  6. +11
    -11
      lib/Spell.cpp
  7. +1
    -1
      lib/Spell.hpp
  8. +40
    -11
      lib/UserInterface.cpp
  9. +3
    -0
      lib/UserInterface.hpp
  10. BIN
      main
  11. +103
    -7
      main.cpp

+ 6
- 6
Makefile Переглянути файл

@ -12,13 +12,13 @@ Spell.o: lib/Spell.cpp lib/Spell.hpp
Character.o: lib/Character.cpp lib/Character.hpp
g++ -c lib/Character.cpp -o Character.o
main: Spell.o Character.o UserInterface.o main.cpp
g++ main.cpp -o main Spell.o Character.o UserInterface.o
main: Spell.o Character.o UserInterface.o BattleInterface.o main.cpp
g++ main.cpp -o main Spell.o Character.o UserInterface.o BattleInterface.o
clean: Spell.o Character.o UserInterface.o
rm Spell.o Character.o UserInterface.o
clean: Spell.o Character.o UserInterface.o BattleInterface.o
rm Spell.o Character.o UserInterface.o BattleInterface.o
striped: Spell.o Character.o main.cpp
g++ -s main.cpp -o main Spell.o Character.o UserInterface.o
striped: Spell.o Character.o UserInterface.o BattleInterface.o main.cpp
g++ -s main.cpp -o main Spell.o Character.o UserInterface.o BattleInterface.o
all: Spell.o Character.o main

+ 107
- 0
lib/BattleInterface.cpp Переглянути файл

@ -0,0 +1,107 @@
#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";
}
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());
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();
}

+ 10
- 4
lib/BattleInterface.hpp Переглянути файл

@ -12,18 +12,24 @@
class BattleInterface
{
protected:
static const int maxTurn = 100;
">static int turn;
static const int maxTurn;
int turn;
Character *player1;
Character *player2;
Character *winner;
Character *loser;
public:
void battleStartAnnounce();
void battleEndAnnouce();
void clearBuff();
public:
BattleInterface();
BattleInterface(Character *p1, Character *p2);
void start();
Character *getWinner();
Character *getLoser();
};
#endif

+ 32
- 6
lib/Character.cpp Переглянути файл

@ -3,7 +3,20 @@
Character::Character(char *n, int l, int e, int h, int m, int a, int d)
{
this->level = l;
this->experience = e;
this->maxHP = h;
this->curHP = maxHP;
this->maxMP = m;
this->curMP = maxMP;
this->atk = a;
this->def = d;
strcpy(this->name, n);
this->name[15] = 0;
}
Character::Character(const char *n, int l, int e, int h, int m, int a, int d)
{
this->level = l;
this->experience = e;
this->maxHP = h;
@ -12,6 +25,7 @@ Character::Character(char *n, int l, int e, int h, int m, int a, int d)
this->curMP = maxMP;
this->atk = a;
this->def = d;
strcpy(this->name, n);
}
char *Character::getName()
@ -63,13 +77,13 @@ 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;
}
this->curHP = this->maxHP;
this->curMP = this->maxMP;
}
void Character::restoreHP(int n)
@ -107,12 +121,12 @@ bool Character::isAlive()
int Character::toNextLevel()
{
return (this->level <= maxLevel) ? ((this->level + 1) * (this->level + 1)) - this->getExperience() : 999999;
return (this->level + 1) * (this->level + 1);
}
bool Character::readytoLevelUp()
{
return (this->toNextLevel() <= 0);
return (this->toNextLevel() <= this->experience);
}
void Character::increaseExperience(int n)
@ -122,6 +136,10 @@ void Character::increaseExperience(int n)
{
this->experience = maxEperience;
}
while (this->readytoLevelUp())
{
this->levelUp();
}
}
bool Character::canCastSpell(Spell *s)
@ -141,7 +159,15 @@ void Character::rest()
this->curMP = this->maxMP;
}
void Character::suicide()
void Character::kill()
{
this->curHP = 0;
}
void Character::revive()
{
if (this->curHP <= 0)
{
this->curHP = 1;
}
}

+ 6
- 4
lib/Character.hpp Переглянути файл

@ -27,10 +27,11 @@ protected:
void reduceMP(int);
public:
Character(char *, int, int, int, int, int, int);
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 *, Character *);
bool canCastSpell(Spell *);
void castSpell(Spell *src, Character *dst);
bool canCastSpell(Spell *src);
char *getName();
int getLevel();
@ -46,8 +47,9 @@ public:
bool readytoLevelUp();
bool isAlive();
void levelUp();
void suicide();
void kill();
void rest();
void revive();
void increaseExperience(int n);
};

+ 11
- 11
lib/Spell.cpp Переглянути файл

@ -28,15 +28,15 @@ std::string Spell::getName()
return this->name;
}
std::vector<Spell *> Spell::Book = {
new Spell("Napalm Beat", 1, 4, 1),
new Spell("Fire Ball", 1, 6, 2),
new Spell("Cold Bolt", 1, 8, 3),
new Spell("Stone curse", 1, 10, 4),
new Spell("Lightning Bolt", 1, 12, 5),
new Spell("Soul Strike", 1, 14, 6),
new Spell("Fire Wall", 1, 16, 7),
new Spell("Frost Diver", 1, 18, 8),
new Spell("Lighting Storm", 1, 20, 9),
new Spell("Asura's Strike", 1, 50, 10),
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),
};

+ 1
- 1
lib/Spell.hpp Переглянути файл

@ -16,7 +16,7 @@ protected:
public:
int TYPE_RESTORATION = 0;
int TYPE_DESTRUCTION = 1;
static std::vector<Spell *> Book;
static std::vector<Spell> Book;
Spell(std::string, int, int, int);
int getType();

+ 40
- 11
lib/UserInterface.cpp Переглянути файл

@ -1,7 +1,7 @@
#include "UserInterface.hpp"
const int UserInterface::interval = 1000; // in ms
const int UserInterface::miniInterval = 50; // in ms
const int UserInterface::interval = 0; // in ms
const int UserInterface::miniInterval = 0; // in ms
const int UserInterface::maxDay = 28;
const int UserInterface::maxMonth = 4;
const int UserInterface::maxYear = 100;
@ -24,7 +24,7 @@ std::vector UserInterface::dayName = {
std::vector<std::string> UserInterface::monthName = {
"Morning Star",
"Sun's Dawn'",
"Sun's Dawn",
"First Seed",
"Rain's Hand",
"Second Seed",
@ -93,9 +93,9 @@ void UserInterface::epilogue()
{
UserInterface::printByChar(
"You are just a young mage in a mage school,\n"
"When you witnessed your arch-mage got killed by your senior...\n"
"The killer was mumbling about some flag inside a scroll,\n"
"he constantly mentioned something about a competition called CTF...\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"
@ -144,14 +144,16 @@ std::string UserInterface::dateString()
}
return std::string(
UserInterface::dayName.at((UserInterface::day % 7) - 1) + ", " +
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 << UserInterface::dateString() << "\n"
std::cout << "=======================================\n"
<< UserInterface::dateString() << "\n"
<< "=======================================\n"
<< "Available action:\n"
<< "[1] Take a rest\n"
<< "[2] Practice magic\n"
@ -163,14 +165,27 @@ void UserInterface::menu()
<< 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;
while (!(buffer <= max && buffer >= min))
do
{
std::cout << msg << std::flush;
std::cin >> buffer;
}
if (std::cin.failbit || std::cin.eofbit)
{
std::cin.clear();
std::cin.ignore(1);
}
} while (std::cin >> buffer && !(buffer <= max && buffer >= min));
return buffer;
}
@ -184,11 +199,25 @@ void UserInterface::nextDay()
{
UserInterface::gameOver = true;
}
month = 1;
}
day = 1;
}
}
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;
}

+ 3
- 0
lib/UserInterface.hpp Переглянути файл

@ -40,10 +40,13 @@ public:
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();
};


+ 103
- 7
main.cpp Переглянути файл

@ -4,11 +4,12 @@
#include <chrono>
#include <random>
#include <fstream>
#include <unistd.h>
#include "lib/Character.hpp"
#include "lib/Spell.hpp"
#include "lib/UserInterface.hpp"
1">// #include "lib/BattleInterface.hpp"
p">#include "lib/BattleInterface.hpp"
std::string loadFlag()
{
@ -19,31 +20,126 @@ 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", 100, 0, 100000, 100000, 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 choice;
int choiceInt = -1;
char choiceChar = -1;
UserInterface::menu();
choice = UserInterface::getNumber(
choiceInt = UserInterface::getNumber(
"What are you gonna do today?\n>",
0, 0);
switch (choice)
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->suicide();
player->kill();
break;
default:
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)");
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)");
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);
}
else
{
UserInterface::print("You lose, but you still get some experience...\n");
player->revive();
player->increaseExperience(enemies.at(choiceInt)->getLevel() / 2);
}
}
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();
}
}

Завантаження…
Відмінити
Зберегти