diff --git a/Makefile b/Makefile index 6c5a358..dff9023 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ COMPILER=g++ -#FLAGS=-g -I. -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused +FLAGS=-g -I. -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused #FLAGS=-g -I. -FLAGS=-I. +#FLAGS=-I. O_DIR=obj CLASS_DIR=src/class @@ -12,14 +12,15 @@ OBJ_CMD=$(COMPILER) $(FLAGS) -c $< -o $@ .PHONY : clean -version001 : main001.o character.o player.o monster.o creation.o info.o betatest.o +version002 : main002.o character.o player.o monster.o battle.o creation.o info.o betatest.o memory.o flag.o base64.o $(COMPILER) $(FLAGS) -o $@ \ - main001.o \ - character.o player.o monster.o \ - info.o creation.o \ - betatest.o + main002.o \ + character.o player.o monster.o \ + info.o creation.o battle.o \ + betatest.o flag.o memory.o \ + base64.o -main001.o : main001.cpp $(CLASS_DIR)/player.hpp $(INTER_DIR)/creation.hpp $(INTER_DIR)/info.hpp $(SYS_DIR)/betatest.hpp +main002.o : main002.cpp $(CLASS_DIR)/player.hpp $(INTER_DIR)/creation.hpp $(INTER_DIR)/info.hpp $(SYS_DIR)/betatest.hpp $(OBJ_CMD) character.o : $(CLASS_DIR)/character.cpp $(CLASS_DIR)/character.hpp @@ -31,6 +32,9 @@ player.o : $(CLASS_DIR)/player.cpp $(CLASS_DIR)/player.hpp $(CLASS_DIR)/characte monster.o : $(CLASS_DIR)/monster.cpp $(CLASS_DIR)/monster.hpp $(CLASS_DIR)/character.hpp $(OBJ_CMD) +battle.o : $(INTER_DIR)/battle.cpp $(INTER_DIR)/battle.hpp $(CLASS_DIR)/monster.hpp $(CLASS_DIR)/character.hpp + $(OBJ_CMD) + creation.o : $(INTER_DIR)/creation.cpp $(INTER_DIR)/creation.hpp $(CLASS_DIR)/player.hpp $(INTER_DIR)/info.hpp $(OBJ_CMD) @@ -40,5 +44,14 @@ info.o : $(INTER_DIR)/info.cpp $(INTER_DIR)/info.hpp $(CLASS_DIR)/player.hpp $(C betatest.o : $(SYS_DIR)/betatest.cpp $(SYS_DIR)/betatest.hpp $(OBJ_CMD) +flag.o : $(SYS_DIR)/flag.cpp $(SYS_DIR)/flag.hpp + $(OBJ_CMD) + +memory.o : $(SYS_DIR)/memory.cpp $(SYS_DIR)/memory.hpp $(CLASS_DIR)/player.hpp cpp-base64/base64.h + $(OBJ_CMD) + +base64.o : cpp-base64/base64.cpp cpp-base64/base64.h + $(COMPILER) -I. -c $< -o $@ + clean : rm -f *.o diff --git a/flag.txt b/flag.txt new file mode 100644 index 0000000..21d4c30 --- /dev/null +++ b/flag.txt @@ -0,0 +1 @@ +GKSK{H0w_d1d_I_n0t_real1ze_such_4_s7up1d_m1sT4k3} diff --git a/main001.cpp b/main001.cpp deleted file mode 100644 index 2db5e6f..0000000 --- a/main001.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "src/class/player.hpp" -#include "src/interface/creation.hpp" -#include "src/interface/info.hpp" -#include "src/system/betatest.hpp" - -#include - -int main(int argc, char const *argv[]) -{ - Player *player = nullptr; - - if (checkBetaTest()) - { - int choice; - - do - { - printf("===== HackTheGame v0.0.1 (Beta) =====\n"); - printf("[1] Create new Character\n"); - printf("[2] Character Info\n"); - printf("[9] Credits\n"); - printf("[0] Exit\n"); - printf(">"); - - scanf("%d", &choice); - - switch (choice) - { - case 1: - player = createCharacter(); - break; - case 2: - if (player == nullptr) - { - std::cout << "Please create a character first!" << std::endl; - } - else - { - Info::ofPlayer(player); - } - break; - case 9: - Info::ofApplication(); - break; - case 0: - break; - default: - printf("Not Implemented...\n"); - } - - } while (choice != 0); - } - else - { - printf("Please get a beta.test key from one of our developer to get access to beta test...\n"); - return 0; - } -} \ No newline at end of file diff --git a/main002.cpp b/main002.cpp new file mode 100644 index 0000000..8e718f3 --- /dev/null +++ b/main002.cpp @@ -0,0 +1,135 @@ +#include "src/class/player.hpp" +#include "src/class/monster.hpp" +#include "src/interface/battle.hpp" +#include "src/interface/creation.hpp" +#include "src/interface/info.hpp" +#include "src/system/betatest.hpp" +#include "src/system/memory.hpp" +#include "src/system/flag.hpp" + +#include + +void printMenu(); + +void printMenu() +{ + printf("===== HackTheGame v0.0.1 (Beta) =====\n"); + printf("[1] Create new Character\n"); + printf("[2] Character Info\n"); + printf("[9] Credits\n"); + printf("[0] Exit\n"); + printf(">"); +} + +int main(int argc, char const *argv[]) +{ + Player *player; + Monster *enemy; + std::cout << "This game is still in closed beta\n" + << "Please input your beta test code\n" + << ">" << std::flush; + + std::string betaCode; + std::cin >> betaCode; + + if (BetaTest::check(betaCode)) + { + std::cout << "Welcome back tester!\n" + << "do you have your character backup code?\n" + << "[y/N] " << std::flush; + + char choice = 'n'; + std::cin >> choice; + + if (choice == 'Y' || choice == 'y') + { + std::cout << "Please input your backup code\n" + << "> " << std::flush; + + std::string code; + std::cin >> code; + + player = Memory::loadFromCode(code); + if (player == nullptr) + { + std::cout << "Your backup code is invalid, please try again..." << std::endl; + return 1; + } + } + else + { + player = Creation::ofPlayer(); + } + + do + { + std::cout << "====== HackTheGame v0.0.2 (Closed Beta) =====\n" + << "[1] Character Info\n" + << "[2] Hunt Monster\n" + << "[3] Fight Boss\n" + << "[4] Rest\n" + << "[9] Credits\n" + << "[0] Exit\n" + << ">" << std::flush; + + choice = '0'; + std::cin >> choice; + switch (choice) + { + case '1': + Info::ofPlayer(player); + break; + case '2': + enemy = Creation::ofMonster(); + if (enemy != nullptr) + { + Battle::Start(player, enemy); + if (Battle::Lose()) + { + std::cout << "GAME OVER !!!!" << std::endl; + return 0; + } + } + break; + case '3': + enemy = Creation::ofBoss(); + if (enemy != nullptr) + { + Battle::Start(player, enemy); + if (Battle::Won()) + { + Flag::Print(); + } + else + { + std::cout << "GAME OVER !!!!" << std::endl; + return 0; + } + } + break; + case '4': + std::cout << "You take a rest at nearby Inn...\n" + << "You wrote your journey to a diary in some cryptic language...\n" + << Memory::saveToCode(player) << "\n" + << "You woke up feeling resfreshed...\n" + << std::flush; + player->restoreHP(); + break; + case '9': + Info::ofApplication(); + break; + case '0': + return 0; + break; + default: + printf("Not Implemented...\n"); + } + + } while (choice != 0); + } + else + { + std::cout << "Invalid code, exiting..." << std::endl; + return 0; + } +} \ No newline at end of file diff --git a/src/class/player.cpp b/src/class/player.cpp index 6aa509c..2bdc9c2 100644 --- a/src/class/player.cpp +++ b/src/class/player.cpp @@ -40,32 +40,15 @@ int Player::expToLevelUp() bool Player::checkLevelup() { - return expToLevelUp() < 0; + return (expToLevelUp() <= 0 && level < PLAYER_MAX_LEVEL); } -bool Player::levelUp(int stat) +void Player::levelUp() { - if (checkLevelup()) - { - switch (stat) - { - case 1: - maxHP += 10; - restoreHP(); - break; - case 2: - atk += 2; - break; - case 3: - def += 1; - break; - } - return true; - } - else - { - return false; - } + level += 1; + maxHP += 10; + atk += 2; + def += 1; } int Player::takeExperience(int bounty) diff --git a/src/class/player.hpp b/src/class/player.hpp index 41ed9a4..8aa3441 100644 --- a/src/class/player.hpp +++ b/src/class/player.hpp @@ -22,7 +22,7 @@ class Player : public Character int takeExperience(int drop); bool checkLevelup(); - bool levelUp(int stat); + void levelUp(); }; #endif \ No newline at end of file diff --git a/src/interface/battle.cpp b/src/interface/battle.cpp new file mode 100644 index 0000000..f9b88d2 --- /dev/null +++ b/src/interface/battle.cpp @@ -0,0 +1,89 @@ +#include "src/interface/battle.hpp" + +#include +#include + +bool Battle::win = false; + +bool Battle::Won() +{ + return win; +} + +bool Battle::Lose() +{ + return !win; +} + +void Battle::Start(Player *player, Monster *monster) +{ + std::cout << " ===== BATTLE INFO ===== \n" + << player->getName() << " Lv." << player->getLevel() << ":\n" + << " HP : " << player->getCurrentHP() << "/" << player->getMaxHP() << "\n" + << " Atk : " << player->getAtk() << "\n" + << " Def : " << player->getDef() << "\n" + << " VS \n" + << monster->getName() << "\n" + << " HP : " << monster->getCurrentHP() << "/" << monster->getMaxHP() << "\n" + << " Atk : " << monster->getAtk() << "\n" + << " Def : " << monster->getDef() << "\n" + << " Drop: " << monster->getBounty() << "\n" + << std::endl; + + std::cout << " ===== BATTLE START ===== " << std::endl; + while (player->isAlive() && monster->isAlive()) + { + std::cout << player->getName() << " attacked " << monster->getName() << "!" << std::endl; + usleep(200000); + int monsterDmg = monster->defend(player->getAtk()); + if (monsterDmg > 0) + { + std::cout << monster->getName() << " got hit by " << monsterDmg << " points!" << std::endl; + } + else + { + std::cout << monster->getName() << " blocked the attack!" << std::endl; + } + usleep(200000); + + if (monster->isAlive()) + { + std::cout << monster->getName() << " attacked " << player->getName() << "!" << std::endl; + usleep(200000); + int playerDmg = player->defend(monster->getAtk()); + if (playerDmg > 0) + { + std::cout << player->getName() << " got hit by " << playerDmg << " points!" << std::endl; + } + else + { + std::cout << player->getName() << " blocked the attack!" << std::endl; + } + usleep(200000); + } + } + + if (player->isAlive()) + { + std::cout << "YOU WIN !!!\n" + << "Got " << monster->getBounty() << " points of experience.\n" + << std::flush; + player->takeExperience(monster->getBounty()); + if (player->checkLevelup()) + { + std::cout << "You leveled up!" << std::endl; + player->levelUp(); + } + else + { + std::cout << player->expToLevelUp() << " points left to level up.\n" + << std::flush; + } + win = true; + } + else + { + std::cout << "YOU LOSE !!!!!" << std::endl; + win = false; + } +} \ No newline at end of file diff --git a/src/interface/battle.hpp b/src/interface/battle.hpp new file mode 100644 index 0000000..0cd2d9d --- /dev/null +++ b/src/interface/battle.hpp @@ -0,0 +1,18 @@ +#ifndef HACKTHEGAME_BATTLESYSTEM_VERSION_000_HPP +#define HACKTHEGAME_BATTLESYSTEM_VERSION_000_HPP + +#include "src/class/monster.hpp" +#include "src/class/player.hpp" + +class Battle +{ + private: + static bool win; + + public: + static bool Won(); + static bool Lose(); + static void Start(Player *player, Monster *monster); +}; + +#endif \ No newline at end of file diff --git a/src/interface/battle0.cpp b/src/interface/battle0.cpp deleted file mode 100644 index d2383a9..0000000 --- a/src/interface/battle0.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "src/interface/battle0.hpp" - -int startBattle(Player *player, Monster *monster) -{ - printf(" ===== BATTLE INFO ===== \n"); - - printf("%15s (Lv.%n):\n", player->getName(), player->getLevel()); - printf(" HP : %n/%n\n", player->getCurrentHP(), player->getMaxHP()); - printf(" Att: %n\n", player->getAtt()); - printf(" Def: %n\n", player->getDef()); - - printf("%15s:\n", monster->getName()); - printf(" HP : %n/%n\n", monster->getCurrentHP(), monster->getMaxHP()); - printf(" Att: %n\n", monster->getAtt()); - printf(" Def: %n\n", monster->getDef()); - - printf(" ===== BATTLE START ===== \n"); - while (player->isAlive() && monster->isAlive()) - { - printf("%15s and %15s attacked each other !!!\n", player->getName(), monster->getName()); - printf("%15s lose %d HP...\n", player->getName(), player->defend(monster->getAtt())); - printf("%15s lose %d HP...\n", monster->getName(), monster->defend(player->getAtt())); - } - - printf(" ===== BATTLE END ===== \n"); - if (player->isAlive()) - { - player->restoreHP(); - printf("YOU WIN !!!\n"); - return 1; - } - else - { - printf("YOU LOSE !!!\n"); - return 0; - } -} \ No newline at end of file diff --git a/src/interface/battle0.hpp b/src/interface/battle0.hpp deleted file mode 100644 index 11f3007..0000000 --- a/src/interface/battle0.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef HACKTHEGAME_BATTLESYSTEM_VERSION_000_HPP -#define HACKTHEGAME_BATTLESYSTEM_VERSION_000_HPP - -#include "src/class/monster.hpp" -#include "src/class/player.hpp" - -#include - -int startBattle(Player *player, Monster *monster); - -#endif \ No newline at end of file diff --git a/src/interface/creation.cpp b/src/interface/creation.cpp index bd7ca8b..26b79f8 100644 --- a/src/interface/creation.cpp +++ b/src/interface/creation.cpp @@ -3,41 +3,121 @@ #include -Player *createCharacter() +Player *Creation::ofPlayer() { - std::string name; + std::cout << "=== Welcome to Character Creation ===\n" + << std::flush; - char choice; - - Player *newPlayer = new Player("HackTheGame"); - - std::cout << "Welcome to character creation !!!" << std::endl; - - do + while (true) { - std::cout << "Please enter your character name: (Max 15 letters)\n" - << "> " << std::flush; + std::cout << "Please enter your character name below\n" + << ">" << std::flush; + std::string name; std::cin >> name; + if (name.size() > 15) { - std::cout << "Your name is too long!" << std::endl; + std::cout << "Your character name is too long!\n" + << std::flush; continue; } + else + { + std::cout << "Creating your character...\n" + << std::flush; + + Player *newPlayer = new Player(name); + Info::ofPlayer(newPlayer); + + std::cout << "Accept? [Y/n] \n" + << ">" << std::flush; + char choice = 'Y'; + std::cin >> choice; + + if (choice == 'Y' || choice == 'y') + { + return newPlayer; + } + } + } +} - std::cout << "Creating your character..." << std::endl; +Monster *Creation::ofMonster() +{ - delete newPlayer; - newPlayer = new Player(name); + const Monster monsterDen[] = { + Monster("Slime", 10, 1, 0, 1), + Monster("Goblin", 30, 2, 1, 2), + Monster("Wolf", 50, 3, 1, 3), + Monster("Zombie", 100, 4, 0, 4), + Monster("Zombie Knight", 200, 10, 7, 5), + Monster("Baby Dragon", 500, 20, 15, 10), + Monster("Dragon", 1000, 50, 20, 20)}; + while (true) + { + int count = 0; + std::cout << "=== Welcome to Hunting Ground ===\n" + << std::flush; - std::cout << "Done...\n" - << "Character Info: " << std::endl; + for (Monster monster : monsterDen) + { + std::cout << "[" << ++count << "] " << monster.getName() << std::endl; + } - Info::ofCharacter(newPlayer); + std::cout << "[0] Exit\n" + << ">" << std::flush; - std::cout << "Accept (y/N)?: " << std::flush; - std::cin >> choice; - } while (choice != 'Y' && choice != 'y'); + char input; + std::cin >> input; - return newPlayer; + if (input <= ('0' + count) && input > '0') + { + char decision = 'Y'; + Monster *summoned = new Monster(monsterDen[input - '1']); + Info::ofMonster(summoned); + std::cout << "Fight this monster? [Y/n]" << std::endl; + std::cout << ">" << std::flush; + std::cin >> decision; + + if (decision == 'y' || decision == 'Y') + { + return summoned; + } + else + { + continue; + } + } + else if (input == '0') + { + return nullptr; + } + else + { + std::cout << "Monster not found!" << std::endl; + continue; + } + } +} + +Monster *Creation::ofBoss() +{ + Monster *boss = new Monster("Flag Guardian", 987654321, 123456789, 123456789, 0); + std::cout << "You are gonna fight the final boss:\n" << std::flush; + Info::ofMonster(boss); + std::cout << "Are you sure? [Y/n]\n" + << "> " << std::flush; + + char choice = 'Y'; + std::cin >> choice; + + if (choice == 'Y' || choice == 'y') + { + return boss; + } + else + { + return nullptr; + } } \ No newline at end of file diff --git a/src/interface/creation.hpp b/src/interface/creation.hpp index fc8cf37..30579aa 100644 --- a/src/interface/creation.hpp +++ b/src/interface/creation.hpp @@ -4,6 +4,12 @@ #include "src/class/player.hpp" #include "src/class/monster.hpp" -Player *createCharacter(); +class Creation +{ +public: + static Player *ofPlayer(); + static Monster *ofMonster(); + static Monster *ofBoss(); +}; #endif \ No newline at end of file diff --git a/src/interface/info.cpp b/src/interface/info.cpp index 07abaea..7aa7f83 100644 --- a/src/interface/info.cpp +++ b/src/interface/info.cpp @@ -24,10 +24,10 @@ void Info::ofPlayer(Player *player) void Info::ofMonster(Monster *monster) { std::cout << "Name: " << monster->getName() << "\n" - << " HP : " << monster->getCurrentHP() << "/" << monster->getMaxHP() << "\n" - << " Atk: " << monster->getAtk() << "\n" - << " Def: " << monster->getDef() << "\n" - << " Lvl: " << monster->getBounty() << std::endl; + << " HP : " << monster->getCurrentHP() << "/" << monster->getMaxHP() << "\n" + << " Atk : " << monster->getAtk() << "\n" + << " Def : " << monster->getDef() << "\n" + << " Drop: " << monster->getBounty() << std::endl; } void Info::ofApplication() diff --git a/src/system/betatest.cpp b/src/system/betatest.cpp index 1e1cf4a..b8f8ef5 100644 --- a/src/system/betatest.cpp +++ b/src/system/betatest.cpp @@ -1,29 +1,9 @@ #include "src/system/betatest.hpp" -#include -#include -bool checkBetaTest() -{ - std::string betaFlag = "4re_Y0u_53ri0usly_checking_f0r_b3t4_t3sT?"; - std::string tmp; - - int result = -1; - - try - { - std::fstream betaFile("beta.test"); - - if (betaFile) { - betaFile >> tmp; +std::string BetaTest::betaFlag = "4re_Y0u_53ri0usly_checking_f0r_b3t4_t3sT?"; - result = tmp.compare("GKSK{" + betaFlag + "}"); - } - } - catch(...) - { - return false; - } - - return result == 0; +bool BetaTest::check(std::string input) +{ + return input.compare("GKSK{" + betaFlag + "}") == 0; } \ No newline at end of file diff --git a/src/system/betatest.hpp b/src/system/betatest.hpp index b8b42b4..095817d 100644 --- a/src/system/betatest.hpp +++ b/src/system/betatest.hpp @@ -1,6 +1,15 @@ #ifndef HACKTHEGAME_BETATEST_HPP #define HACKTHEGAME_BETATEST_HPP -bool checkBetaTest(); +#include + +class BetaTest +{ + private: + static std::string betaFlag; + + public: + static bool check(std::string input); +}; #endif \ No newline at end of file diff --git a/src/system/flag.cpp b/src/system/flag.cpp new file mode 100644 index 0000000..a247b05 --- /dev/null +++ b/src/system/flag.cpp @@ -0,0 +1,34 @@ +#include "flag.hpp" + +#include +#include + +std::string Flag::flag = ""; + +bool Flag::Load() +{ + std::ifstream file("flag.txt"); + if (file.good()) + { + file >> flag; + return true; + } + else + { + return false; + } +} + +void Flag::Print() +{ + if (Load()) + { + std::cout << flag << std::endl; + } + else + { + std::cout << "Something went wrong on the server\n" + << "Please contact the administrator...\n" + << std::endl; + } +} \ No newline at end of file diff --git a/src/system/flag.hpp b/src/system/flag.hpp new file mode 100644 index 0000000..b20ba14 --- /dev/null +++ b/src/system/flag.hpp @@ -0,0 +1,16 @@ +#ifndef FLAG_HACKTHEGAME_HPP +#define FLAG_HACKTHEGAME_HPP + +#include + +class Flag +{ + private: + static std::string flag; + static bool Load(); + + public: + static void Print(); +}; + +#endif \ No newline at end of file diff --git a/src/system/memory.cpp b/src/system/memory.cpp new file mode 100644 index 0000000..aca2d8d --- /dev/null +++ b/src/system/memory.cpp @@ -0,0 +1,53 @@ +#include "memory.hpp" + +#include "cpp-base64/base64.h" + +#include +#include + +Player *Memory::loadFromCode(std::string code) +{ + code = base64_decode(code); + char playerName[16] = {0}; + int playerHP = 0; + int playerAtk = 0; + int playerDef = 0; + int playerLevel = 0; + int playerExp = 0; + + int result = sscanf(code.c_str(), + "PlayerLevel=%d;PlayerExp=%d;PlayerHP=%d;PlayerAtk=%d;PlayerDef=%d;PlayerName=%15s", + &playerLevel, + &playerExp, + &playerHP, + &playerAtk, + &playerDef, + playerName); + + std::string playerTrueName = playerName; + + if (result == 6) + { + return new Player(playerTrueName, playerHP, playerAtk, playerDef, playerLevel, playerExp); + } + else + { + return nullptr; + } +} + +std::string Memory::saveToCode(Player *player) +{ + char code[256]; + snprintf(code, sizeof(code), + "PlayerLevel=%d;PlayerExp=%d;PlayerHP=%d;PlayerAtk=%d;PlayerDef=%d;PlayerName=%s", + player->getLevel(), + player->getExp(), + player->getMaxHP(), + player->getAtk(), + player->getDef(), + player->getName().c_str()); + + return base64_encode(reinterpret_cast(code), + strlen(code)); +} \ No newline at end of file diff --git a/src/system/memory.hpp b/src/system/memory.hpp new file mode 100644 index 0000000..bd7b376 --- /dev/null +++ b/src/system/memory.hpp @@ -0,0 +1,14 @@ +#ifndef HACKTHEGAME_SAVELOAD_HPP +#define HACKTHEGAME_SAVELOAD_HPP + +#include "src/class/player.hpp" +#include + +class Memory +{ +public: + static Player *loadFromCode(std::string); + static std::string saveToCode(Player *); +}; + +#endif \ No newline at end of file diff --git a/version002 b/version002 new file mode 100755 index 0000000..e369aca Binary files /dev/null and b/version002 differ