#include <iostream>
#include <ostream>
#include <random>
#include <vector>
namespace
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> attack_dist(20, 50);
}
class LifeForm
{
protected:
int level;
int exp;
int req_EXP;
int max_health;
int health;
LifeForm(int level, int exp, int req_EXP, int max_health)
: level(level)
, exp(exp)
, req_EXP(req_EXP)
, max_health(max_health)
, health(max_health)
{}
void level_up()
{
level++;
exp = 0;
req_EXP += level * 100;
max_health += 50 * level;
health = max_health;
}
public:
bool health_depleted() const { return health <= 0; }
void attack(LifeForm& attacked_lifeform)
{
attacked_lifeform.health -= level * attack_dist(gen);
}
void add_EXP(LifeForm const& life_form)
{
exp += life_form.level * 50;
if (exp >= req_EXP)
{
level_up();
}
}
friend std::ostream& operator<<(std::ostream& out, LifeForm const& lifeform)
{
out << "Level: " << lifeform.level;
out << "\nHP : (" << lifeform.health << '/' << lifeform.max_health << ')';
out << "\nEXP : (" << lifeform.exp << '/' << lifeform.req_EXP << ')';
return out;
}
};
class Player : public LifeForm
{
public:
Player() : LifeForm(1, 0, 100, 200) {}
};
class Monster : public LifeForm
{
public:
Monster() : LifeForm(1, 50, 0, 100) {}
};
class Game
{
private:
Player player;
std::vector<Monster> monsters;
void battle();
Monster current_monster() { return monsters.back(); }
bool all_monsters_dead() const { return monsters.empty(); }
public:
Game();
void play();
};
Game::Game() : monsters(50) {}
void Game::play()
{
std::cout << "Number of monsters: " << monsters.size() << "\n\n";
while (!player.health_depleted() && !monsters.empty())
{
std::cout << "\nPlayer\n" << player;
battle();
if (all_monsters_dead())
{
std::cout << "\n\n> All monsters killed!!!";
}
if (player.health_depleted())
{
std::cout << "> Player dead...\n\n";
}
}
}
void Game::battle()
{
std::cout << "\n\n> Player attacks!\n";
player.attack(monsters.back());
if (current_monster().health_depleted())
{
std::cout << "> Monster killed!\n";
player.add_EXP(current_monster());
monsters.pop_back();
}
std::cout << "\nMonster " << monsters.size() << "\n" << current_monster();
std::cout << "\n\n> Monster attacks!\n";
current_monster().attack(player);
}
int main()
{
Game game;
game.play();
}