Browse Source

finger crossed

master
myitinos 4 years ago
parent
commit
663c0602ac
11 changed files with 319 additions and 50 deletions
  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 View File

@ -12,13 +12,13 @@ Spell.o: lib/Spell.cpp lib/Spell.hpp
Character.o: lib/Character.cpp lib/Character.hpp Character.o: lib/Character.cpp lib/Character.hpp
g++ -c lib/Character.cpp -o Character.o 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 all: Spell.o Character.o main

+ 107
- 0
lib/BattleInterface.cpp View File

@ -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 View File

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

+ 32
- 6
lib/Character.cpp View File

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

+ 6
- 4
lib/Character.hpp View File

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

+ 11
- 11
lib/Spell.cpp View File

@ -28,15 +28,15 @@ std::string Spell::getName()
return this->name; 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 View File

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

+ 40
- 11
lib/UserInterface.cpp View File

@ -1,7 +1,7 @@
#include "UserInterface.hpp" #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::maxDay = 28;
const int UserInterface::maxMonth = 4; const int UserInterface::maxMonth = 4;
const int UserInterface::maxYear = 100; const int UserInterface::maxYear = 100;
@ -24,7 +24,7 @@ std::vector UserInterface::dayName = {
std::vector<std::string> UserInterface::monthName = { std::vector<std::string> UserInterface::monthName = {
"Morning Star", "Morning Star",
"Sun's Dawn'",
"Sun's Dawn",
"First Seed", "First Seed",
"Rain's Hand", "Rain's Hand",
"Second Seed", "Second Seed",
@ -93,9 +93,9 @@ void UserInterface::epilogue()
{ {
UserInterface::printByChar( UserInterface::printByChar(
"You are just a young mage in a mage school,\n" "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" "You thought to yourself: \"What the f*ck is a CTF?\"\n"
"Nevertheless, you want that scroll, you want that flag!\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" "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( 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) + date + " of " + UserInterface::monthName.at(UserInterface::month - 1) +
", Year " + std::to_string(UserInterface::year)); ", Year " + std::to_string(UserInterface::year));
} }
void UserInterface::menu() void UserInterface::menu()
{ {
std::cout << UserInterface::dateString() << "\n"
std::cout << "=======================================\n"
<< UserInterface::dateString() << "\n"
<< "=======================================\n"
<< "Available action:\n" << "Available action:\n"
<< "[1] Take a rest\n" << "[1] Take a rest\n"
<< "[2] Practice magic\n" << "[2] Practice magic\n"
@ -163,14 +165,27 @@ void UserInterface::menu()
<< std::flush; << 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 UserInterface::getNumber(std::string msg, int min, int max)
{ {
int buffer = max + 1; int buffer = max + 1;
while (!(buffer <= max && buffer >= min))
do
{ {
std::cout << msg << std::flush; 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; return buffer;
} }
@ -184,11 +199,25 @@ void UserInterface::nextDay()
{ {
UserInterface::gameOver = true; UserInterface::gameOver = true;
} }
month = 1;
} }
day = 1;
} }
} }
bool UserInterface::isGameOver() bool UserInterface::isGameOver()
{ {
return gameOver; 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 View File

@ -40,10 +40,13 @@ public:
static void epilogue(); static void epilogue();
static void menu(); static void menu();
static void nextDay(); static void nextDay();
static void characterInfo(Character *);
static void enemiesInfo(std::vector<Character *> &);
static std::string dateString(); static std::string dateString();
static int getNumber(std::string, int, int); static int getNumber(std::string, int, int);
static Character *characterCreation(); static Character *characterCreation();
static bool isGameOver(); static bool isGameOver();
}; };

BIN
main View File


+ 103
- 7
main.cpp View File

@ -4,11 +4,12 @@
#include <chrono> #include <chrono>
#include <random> #include <random>
#include <fstream> #include <fstream>
#include <unistd.h>
#include "lib/Character.hpp" #include "lib/Character.hpp"
#include "lib/Spell.hpp" #include "lib/Spell.hpp"
#include "lib/UserInterface.hpp" #include "lib/UserInterface.hpp"
1">// #include "lib/BattleInterface.hpp"
p">#include "lib/BattleInterface.hpp"
std::string loadFlag() std::string loadFlag()
{ {
@ -19,31 +20,126 @@ int main()
{ {
std::string flag; std::string flag;
Character *player; Character *player;
Character *archMage;
Character *enemy;
BattleInterface battle;
std::vector<Character *> enemies;
flag = loadFlag(); flag = loadFlag();
srand(time(0)); srand(time(0));
alarm(600);
UserInterface::welcomeMessage(); UserInterface::welcomeMessage();
UserInterface::epilogue(); UserInterface::epilogue();
player = UserInterface::characterCreation(); 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()) while (player->isAlive() && !UserInterface::isGameOver())
{ {
int choice;
int choiceInt = -1;
char choiceChar = -1;
UserInterface::menu(); UserInterface::menu();
choice = UserInterface::getNumber(
choiceInt = UserInterface::getNumber(
"What are you gonna do today?\n>", "What are you gonna do today?\n>",
0, 0);
switch (choice)
0, 6);
switch (choiceInt)
{ {
case 0: case 0:
UserInterface::print("You commit sudoku...\n"); UserInterface::print("You commit sudoku...\n");
UserInterface::print("Was it supposed to be seppuku?\n"); UserInterface::print("Was it supposed to be seppuku?\n");
UserInterface::print("Nevermind, you killed yourself.\n"); UserInterface::print("Nevermind, you killed yourself.\n");
player->suicide();
player->kill();
break; 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; break;
} }
UserInterface::nextDay();
} }
} }

Loading…
Cancel
Save