CCCPaste

aa1aafb75e7e6

#include <algorithm>
#include <chrono>
#include <iostream>
#include <random>
#include <string>
#include <vector>

template <typename T>
inline T clampv(T v, T lo, T hi) { return std::max(lo, std::min(v, hi)); }

struct Enemy { std::string name; int hp; int atk; };
struct BattleState { int playerHP = 100; int playerATK = 20; Enemy enemy; };

struct RNG {
std::mt19937_64 eng;
RNG() {
std::random_device rd;
auto seed = (static_cast<uint64_t>(rd()) << 32) ^ static_cast<uint64_t>(rd());
eng.seed(seed ^ static_cast<uint64_t>(std::chrono::high_resolution_clock::now().time_since_epoch().count()));
}
int uniformInt(int lo, int hi) { std::uniform_int_distribution<int> d(lo, hi); return d(eng); }
bool chance(double p) { std::bernoulli_distribution d(clampv(p, 0.0, 1.0)); return d(eng); }
};

static const std::vector<Enemy> ENEMIES = {
{"knight", 50, 15},
{"soldier", 30, 10},
{"attacker", 40, 20},
{"npc", 20, 5},
{"rogue", 35, 18},
{"brute", 60, 12},
{"shade", 25, 25},
{"reaper", 1, 1},
{"dragon", 1, 1},
{"lich", 1, 1}
};
static const std::vector<std::string> SURRENDER_LINES = {
"I surrender!", "This is too much!", "Have mercy!", "You're too strong!", "I yield!", "No more!"
};
static const std::vector<std::string> ENEMY_TAUNTS = {
"Take this!", "Die!", "For glory!", "You're finished!", "Your end is near!"
};
static const std::vector<std::string> PLAYER_TAUNTS = {
"Taste my steel!", "For honor!", "You won't survive!", "This ends now!"
};

int rollDamage(RNG& rng, int baseMax) {
int a = rng.uniformInt(0, baseMax);
int b = rng.uniformInt(0, baseMax);
int biased = a > b ? a : b;
return clampv(biased, 0, baseMax);
}

int main() {
RNG rng;
int idx = rng.uniformInt(0, (int)ENEMIES.size() - 1);
const Enemy& picked = ENEMIES[idx];
BattleState st{100, 20, picked};
std::cout << "You encountered the " << picked.name << "!\n";
int oneBased = idx + 1;
if (oneBased >= 8) {
std::cout << "\nInstant death.\n";
std::cout << "\nYou were slain by the " << picked.name << "!\n";
return 0;
}
if (oneBased == 6 || oneBased == 7) {
if (rng.chance(0.5)) {
std::cout << "\nCoin flip: loss.\n";
std::cout << "\nYou were slain by the " << picked.name << "!\n";
return 0;
} else {
std::cout << "Coin flip: survive.\n";
}
}
int pre = rng.uniformInt(1, 3);
if (pre == 1) { int buff = rng.uniformInt(5, 15); st.enemy.hp += buff; std::cout << "Enemy found extra health! (+" << buff << ")\n"; }
else if (pre == 2) { int buff = rng.uniformInt(10, 20); st.playerHP += buff; std::cout << "You found a health potion! (+" << buff << ")\n"; }
int turn = 1;
while (st.playerHP > 0 && st.enemy.hp > 0) {
std::cout << "\n--- Turn " << turn++ << " ---\n";
if (rng.chance(0.3)) std::cout << PLAYER_TAUNTS[rng.uniformInt(0, (int)PLAYER_TAUNTS.size() - 1)] << "\n";
bool enemyFirst = rng.chance(0.5);
if (enemyFirst) {
int enemyHit = rollDamage(rng, st.enemy.atk);
st.playerHP = clampv(st.playerHP - enemyHit, 0, 10000);
if (rng.chance(0.4)) std::cout << ENEMY_TAUNTS[rng.uniformInt(0, (int)ENEMY_TAUNTS.size() - 1)] << "\n";
std::cout << "Enemy attacks first! Damage: " << enemyHit << "\n";
std::cout << "Player HP: " << st.playerHP << "\n";
if (st.playerHP == 0) break;
}
int playerHit = rollDamage(rng, st.playerATK);
st.enemy.hp = clampv(st.enemy.hp - playerHit, 0, 10000);
std::cout << "Player attacks! Damage: " << playerHit << "\n";
std::cout << "Enemy HP: " << st.enemy.hp << "\n";
if (st.enemy.hp == 0) break;
if (!enemyFirst) {
int enemyHit = rollDamage(rng, st.enemy.atk);
st.playerHP = clampv(st.playerHP - enemyHit, 0, 10000);
if (rng.chance(0.4)) std::cout << ENEMY_TAUNTS[rng.uniformInt(0, (int)ENEMY_TAUNTS.size() - 1)] << "\n";
std::cout << "Enemy retaliates! Damage: " << enemyHit << "\n";
std::cout << "Player HP: " << st.playerHP << "\n";
if (st.playerHP == 0) break;
}
if (st.enemy.hp < 30 && rng.chance(0.5)) std::cout << SURRENDER_LINES[rng.uniformInt(0, (int)SURRENDER_LINES.size() - 1)] << "\n";
}
std::cout << (st.playerHP > 0 ? "\nYou defeated the " : "\nYou were slain by the ") << st.enemy.name << "!\n";
return 0;
}