瀏覽代碼

finger crossed

master
myitinos 4 年之前
父節點
當前提交
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. 二進制
      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();
};

二進制
main 查看文件


+ 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();
}
}

Loading…
取消
儲存