ソースを参照

finger crossed

master
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. バイナリ
      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();
}
}

読み込み中…
キャンセル
保存