#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <iomanip>
#include <algorithm>
#include <fstream>
#include <sstream>
#include <map>
#include <cmath>
using namespace std;
// ========== 食物结构体 ==========
struct Food {
string name;
int price;
int energyRestore;
int healthRestore;
string symbol;
int quantity;
Food(string n = "", int p = 0, int e = 0, int h = 0, string s = "", int q = 0)
: name(n), price(p), energyRestore(e), healthRestore(h), symbol(s), quantity(q) {}
string serialize() const {
return name + "," + to_string(price) + "," + to_string(energyRestore) + "," +
to_string(healthRestore) + "," + symbol + "," + to_string(quantity);
}
static Food deserialize(const string& data) {
Food f;
stringstream ss(data);
string token;
getline(ss, f.name, ',');
getline(ss, token, ',');
f.price = stoi(token);
getline(ss, token, ',');
f.energyRestore = stoi(token);
getline(ss, token, ',');
f.healthRestore = stoi(token);
getline(ss, token, ',');
f.symbol = token;
getline(ss, token, ',');
f.quantity = stoi(token);
return f;
}
};
// ========== 怪物结构体 ==========
struct Monster {
string name;
int health;
int damage;
int reward;
string symbol;
int rarity;
Monster(string n = "", int h = 0, int d = 0, int r = 0, string s = "", int ra = 1)
: name(n), health(h), damage(d), reward(r), symbol(s), rarity(ra) {}
string serialize() const {
return name + "," + to_string(health) + "," + to_string(damage) + "," +
to_string(reward) + "," + symbol + "," + to_string(rarity);
}
static Monster deserialize(const string& data) {
Monster m;
stringstream ss(data);
string token;
getline(ss, m.name, ',');
getline(ss, token, ',');
m.health = stoi(token);
getline(ss, token, ',');
m.damage = stoi(token);
getline(ss, token, ',');
m.reward = stoi(token);
getline(ss, token, ',');
m.symbol = token;
getline(ss, token, ',');
m.rarity = stoi(token);
return m;
}
};
// ========== 矿物结构体 ==========
struct Mineral {
string name;
int value;
int rarity;
string symbol;
Mineral(string n = "", int v = 0, int r = 0, string s = "")
: name(n), value(v), rarity(r), symbol(s) {}
string serialize() const {
return name + "," + to_string(value) + "," + to_string(rarity) + "," + symbol;
}
static Mineral deserialize(const string& data) {
Mineral m;
stringstream ss(data);
string token;
getline(ss, m.name, ',');
getline(ss, token, ',');
m.value = stoi(token);
getline(ss, token, ',');
m.rarity = stoi(token);
getline(ss, token, ',');
m.symbol = token;
return m;
}
};
// ========== 玩家类 ==========
class Player {
private:
string name;
int gold;
int energy;
int maxEnergy;
int health;
int maxHealth;
int level;
int exp;
int maxExp;
vector<Mineral> inventory;
vector<Food> foods;
int pickaxeLevel;
int totalMined;
int totalGoldEarned;
int monstersKilled;
int deaths;
int currentDepth;
bool isDead;
int energyDrainTimer;
public:
Player(string n = "Miner") : name(n), gold(100), energy(100), maxEnergy(100),
health(100), maxHealth(100), level(1), exp(0),
maxExp(100), pickaxeLevel(1), totalMined(0),
totalGoldEarned(0), monstersKilled(0), deaths(0),
currentDepth(0), isDead(false), energyDrainTimer(0) {
foods.push_back(Food("Cookie", 15, 20, 5, "[C]", 3));
foods.push_back(Food("Bread", 30, 40, 10, "[B]", 2));
foods.push_back(Food("Cake", 50, 70, 15, "[K]", 0));
foods.push_back(Food("Pizza", 80, 100, 20, "[P]", 0));
foods.push_back(Food("Steak", 120, 150, 30, "[S]", 0));
foods.push_back(Food("EnergyDrink", 200, 200, 40, "[E]", 0));
}
// ========== 辅助函数 ==========
int maxInt(int a, int b) {
return (a > b) ? a : b;
}
// ========== 实时显示 ==========
void displayHUD() {
system("cls");
cout << "\n+================================================+\n";
cout << "| [M] " << name;
int nameLen = name.length();
for (int i = nameLen; i < 35; i++) cout << " ";
cout << "|\n";
// 血量条
cout << "| HP: ";
int healthBars = (health * 20) / maxHealth;
for (int i = 0; i < 20; i++) {
if (i < healthBars) cout << "#";
else cout << ".";
}
cout << " " << health << "/" << maxHealth;
int hpLen = to_string(health).length();
for (int i = hpLen; i < 5; i++) cout << " ";
cout << "|\n";
// 能量条
cout << "| EN: ";
int energyBars = (energy * 20) / maxEnergy;
for (int i = 0; i < 20; i++) {
if (i < energyBars) cout << "#";
else cout << ".";
}
cout << " " << energy << "/" << maxEnergy;
int enLen = to_string(energy).length();
for (int i = enLen; i < 5; i++) cout << " ";
cout << "|\n";
// 经验条
cout << "| EXP: ";
int expBars = (exp * 20) / maxExp;
for (int i = 0; i < 20; i++) {
if (i < expBars) cout << "#";
else cout << ".";
}
cout << " " << exp << "/" << maxExp << " (Lv." << level << ")";
int lvLen = to_string(level).length();
for (int i = lvLen; i < 4; i++) cout << " ";
cout << "|\n";
// 金币和镐子
cout << "| Gold: " << gold;
int goldLen = to_string(gold).length();
for (int i = goldLen; i < 15; i++) cout << " ";
cout << "Pickaxe: " << pickaxeLevel << "/5";
int pkLen = to_string(pickaxeLevel).length();
for (int i = pkLen; i < 8; i++) cout << " ";
cout << "|\n";
// 深度
cout << "| Depth: " << currentDepth << "m";
int depthLen = to_string(currentDepth).length();
for (int i = depthLen; i < 30; i++) cout << " ";
cout << "|\n";
// 物品统计
cout << "| Items: " << inventory.size() << " ";
cout << "Foods: " << getTotalFoodCount();
int itemLen = to_string(inventory.size()).length();
int foodLen = to_string(getTotalFoodCount()).length();
int totalLen = itemLen + foodLen;
for (int i = totalLen; i < 15; i++) cout << " ";
cout << "|\n";
cout << "+------------------------------------------------+\n";
// 显示矿物背包(前5个)
if (!inventory.empty()) {
cout << "| Minerals: ";
int displayCount = (inventory.size() < 5) ? inventory.size() : 5;
for (int i = 0; i < displayCount; i++) {
cout << inventory[i].symbol << inventory[i].name;
if (i < displayCount - 1) cout << ", ";
}
if (inventory.size() > 5) cout << "... (+" << inventory.size() - 5 << ")";
int invLen = inventory.size();
for (int i = invLen; i < 30; i++) cout << " ";
cout << "|\n";
}
// 显示食物(前3个)
if (!foods.empty()) {
cout << "| Foods: ";
int displayCount = (foods.size() < 3) ? foods.size() : 3;
int printed = 0;
for (int i = 0; i < displayCount; i++) {
if (foods[i].quantity > 0) {
if (printed > 0) cout << ", ";
cout << foods[i].symbol << foods[i].name << "x" << foods[i].quantity;
printed++;
}
}
if (foods.size() > 3) cout << "... (+" << foods.size() - 3 << ")";
int foodLen2 = foods.size();
for (int i = foodLen2; i < 30; i++) cout << " ";
cout << "|\n";
}
cout << "+================================================+\n";
cout << "1.Mine 2.Bag 3.Sell 4.Upgrade 5.Eat 6.Shop 7.Rest 8.Status 9.Save 0.Exit\n";
cout << "> ";
}
// ========== 能量消耗** ==========
void updateEnergyAndHealth() {
if (isDead) return;
energyDrainTimer++;
// 每3秒消耗1点能量
if (energyDrainTimer >= 3) {
energyDrainTimer = 0;
if (energy > 0) {
energy--;
} else {
// 能量为0时消耗血量
health -= 2;
if (health <= 0) {
health = 0;
die("Energy Exhaustion");
return;
}
cout << "\n[WARNING] Energy depleted! Losing health...\n";
}
}
// 如果血量低于20%,显示警告
if (health < maxHealth * 0.2 && health > 0) {
cout << "\n[CRITICAL] Health is critically low!\n";
}
}
// ========== 挖矿** ==========
void mine() {
if (isDead) {
cout << "[DEAD] You are dead! Start a new game.\n";
return;
}
if (energy < 20) {
cout << "[WARNING] Not enough energy! Need 20 energy.\n";
cout << "[HINT] Eat some food to restore energy!\n";
return;
}
if (health < 10) {
cout << "[WARNING] Health too low! Cannot mine.\n";
return;
}
energy -= 20;
totalMined++;
currentDepth += rand() % 10 + 1;
cout << "\n[Mining] Digging deeper... Current depth: " << currentDepth << "m\n";
int event = rand() % 100;
if (event < 15) {
encounterMonster();
} else if (event < 25) {
encounterLava();
} else {
mineMineral();
}
}
void mineMineral() {
Mineral found = generateMineral();
inventory.push_back(found);
cout << "[FOUND] You mined " << found.name << "! Value: " << found.value << " gold\n";
int expGain = 10 + found.rarity * 2;
addExp(expGain);
}
Mineral generateMineral() {
vector<Mineral> minerals;
minerals.push_back(Mineral("Stone", 1, 1, "[S]"));
minerals.push_back(Mineral("Coal", 5, 2, "[C]"));
minerals.push_back(Mineral("Copper", 10, 3, "[P]"));
minerals.push_back(Mineral("Iron", 20, 4, "[I]"));
minerals.push_back(Mineral("Silver", 50, 6, "[V]"));
minerals.push_back(Mineral("Gold", 100, 7, "[G]"));
minerals.push_back(Mineral("Diamond", 500, 9, "[D]"));
minerals.push_back(Mineral("Emerald", 300, 8, "[E]"));
minerals.push_back(Mineral("Ruby", 250, 7, "[R]"));
minerals.push_back(Mineral("Amethyst", 150, 6, "[A]"));
int depthBonus = currentDepth / 50;
if (depthBonus > 20) depthBonus = 20;
int chance = rand() % 100 + pickaxeLevel * 2 + depthBonus;
Mineral result;
if (chance > 95 && pickaxeLevel >= 3) {
result = minerals[6];
} else if (chance > 85) {
result = minerals[7];
} else if (chance > 75) {
result = minerals[8];
} else if (chance > 65) {
result = minerals[9];
} else if (chance > 50) {
result = minerals[4];
} else if (chance > 40) {
result = minerals[5];
} else if (chance > 30) {
result = minerals[3];
} else if (chance > 20) {
result = minerals[2];
} else if (chance > 10) {
result = minerals[1];
} else {
result = minerals[0];
}
return result;
}
// ========== 怪物** ==========
void encounterMonster() {
Monster monster = generateMonster();
cout << "\n[WARNING] A " << monster.symbol << " " << monster.name << " appeared!\n";
cout << "HP: " << monster.health << " | ATK: " << monster.damage << "\n";
cout << "Reward: " << monster.reward << " gold\n\n";
int playerHealth = health;
int monsterHealth = monster.health;
while (playerHealth > 0 && monsterHealth > 0) {
cout << "1. Attack\n";
cout << "2. Flee (costs 30 energy)\n";
cout << "> ";
int choice;
cin >> choice;
if (choice == 1) {
int playerDamage = 20 + pickaxeLevel * 5 + rand() % 15;
monsterHealth -= playerDamage;
cout << "[ATTACK] You dealt " << playerDamage << " damage to " << monster.name << "!\n";
if (monsterHealth <= 0) {
cout << "[VICTORY] Defeated " << monster.symbol << " " << monster.name << "!\n";
gold += monster.reward;
totalGoldEarned += monster.reward;
monstersKilled++;
addExp(30 + monster.rarity * 20);
if (rand() % 100 < 20) {
cout << "[LOOT] " << monster.name << " dropped a special item!\n";
Mineral bonus = generateMineral();
inventory.push_back(bonus);
cout << "[LOOT] Obtained " << bonus.name << "!\n";
}
health = playerHealth;
return;
}
int monsterDamage = monster.damage + rand() % 10;
playerHealth -= monsterDamage;
cout << "[DAMAGE] " << monster.name << " dealt " << monsterDamage << " damage to you!\n";
cout << "HP remaining: " << playerHealth << "\n\n";
} else if (choice == 2) {
if (energy < 30) {
cout << "[ERROR] Not enough energy to flee!\n";
continue;
}
energy -= 30;
if (rand() % 100 < 60) {
cout << "[FLEE] Successfully escaped!\n";
health = playerHealth;
return;
} else {
cout << "[FLEE] Failed to escape!\n";
int monsterDamage = monster.damage + rand() % 10;
playerHealth -= monsterDamage;
cout << "[DAMAGE] " << monster.name << " dealt " << monsterDamage << " damage to you!\n";
cout << "HP remaining: " << playerHealth << "\n\n";
}
} else {
cout << "[ERROR] Invalid choice!\n";
}
}
health = playerHealth;
if (health <= 0) {
die("Killed by " + monster.name);
}
}
Monster generateMonster() {
vector<Monster> monsters;
monsters.push_back(Monster("Slime", 30, 8, 15, "[S]", 1));
monsters.push_back(Monster("Bat", 25, 12, 20, "[B]", 1));
monsters.push_back(Monster("Skeleton", 40, 15, 30, "[K]", 2));
monsters.push_back(Monster("Zombie", 50, 18, 40, "[Z]", 2));
monsters.push_back(Monster("Spider", 35, 20, 35, "[P]", 2));
monsters.push_back(Monster("Goblin", 60, 22, 50, "[G]", 3));
monsters.push_back(Monster("Golem", 100, 15, 70, "[L]", 3));
monsters.push_back(Monster("Wolf", 70, 28, 60, "[W]", 3));
monsters.push_back(Monster("Demon", 90, 35, 100, "[D]", 4));
monsters.push_back(Monster("Dragon", 120, 40, 150, "[R]", 5));
monsters.push_back(Monster("ShadowLord", 150, 45, 200, "[X]", 5));
int depthLevel = currentDepth / 30;
vector<Monster> availableMonsters;
for (int i = 0; i < monsters.size(); i++) {
if (monsters[i].rarity <= depthLevel + 1) {
availableMonsters.push_back(monsters[i]);
}
}
if (availableMonsters.empty()) {
availableMonsters = monsters;
}
int index = rand() % availableMonsters.size();
return availableMonsters[index];
}
// ========== 岩浆** ==========
void encounterLava() {
cout << "\n[LAVA] Warning! Lava flow detected!\n";
cout << "[LAVA] Molten lava is surging towards you!\n\n";
cout << "1. Flee quickly (costs 30 energy)\n";
cout << "2. Block with pickaxe (costs 20 energy)\n";
cout << "3. Eat food to restore before responding\n";
cout << "> ";
int choice;
cin >> choice;
switch (choice) {
case 1: {
if (energy < 30) {
cout << "[ERROR] Not enough energy!\n";
lavaDamage(true);
} else {
energy -= 30;
if (rand() % 100 < 70) {
cout << "[FLEE] Successfully escaped the lava!\n";
if (rand() % 100 < 30) {
Mineral found = generateMineral();
inventory.push_back(found);
cout << "[LOOT] Found " << found.name << " while escaping!\n";
}
} else {
cout << "[FLEE] Couldn't fully avoid the lava!\n";
lavaDamage(true);
}
}
break;
}
case 2: {
if (energy < 20) {
cout << "[ERROR] Not enough energy!\n";
lavaDamage(true);
} else {
energy -= 20;
int damage = 10 + rand() % 20;
health -= damage;
cout << "[BLOCK] Blocked part of the lava, took " << damage << " damage!\n";
if (health <= 0) {
die("Lava Burns");
return;
}
int repairCost = pickaxeLevel * 10;
cout << "[REPAIR] Pickaxe damaged, repair costs " << repairCost << " gold\n";
if (gold >= repairCost && rand() % 100 < 50) {
gold -= repairCost;
cout << "[REPAIR] Pickaxe automatically repaired!\n";
}
int lostGold = rand() % 20 + 5;
if (gold > lostGold) gold -= lostGold;
else gold = 0;
cout << "[LOSS] Lost " << lostGold << " gold\n";
}
break;
}
case 3: {
if (foods.empty()) {
cout << "[ERROR] No food!\n";
lavaDamage(true);
} else {
cout << "[FOOD] Choose food:\n";
int foodCount = 0;
for (int i = 0; i < foods.size(); i++) {
if (foods[i].quantity > 0) {
cout << ++foodCount << ". " << foods[i].symbol << " " << foods[i].name
<< " x" << foods[i].quantity << "\n";
}
}
cout << "> ";
int foodChoice;
cin >> foodChoice;
if (foodChoice >= 1 && foodChoice <= foodCount) {
int idx = 0;
int count = 0;
for (int i = 0; i < foods.size(); i++) {
if (foods[i].quantity > 0) {
count++;
if (count == foodChoice) {
idx = i;
break;
}
}
}
eatFood(idx);
cout << "[RESTORE] Restored energy, continuing to face lava!\n";
if (rand() % 100 < 80) {
cout << "[FLEE] With full energy, successfully escaped lava!\n";
} else {
cout << "[LAVA] Still affected somewhat...\n";
lavaDamage(true);
}
} else {
cout << "[ERROR] Invalid choice!\n";
lavaDamage(true);
}
}
break;
}
default:
cout << "[ERROR] Invalid choice!\n";
lavaDamage(true);
}
}
void lavaDamage(bool reduceHealth) {
if (reduceHealth) {
// 血量降低三分之一
int damage = maxHealth / 3;
health -= damage;
cout << "[LAVA] Took " << damage << " burn damage! (1/3 health lost)\n";
if (health <= 0) {
die("Lava Consumes You");
return;
}
}
int lostGold = rand() % 30 + 10;
if (gold > lostGold) gold -= lostGold;
else gold = 0;
cout << "[LOSS] Lost " << lostGold << " gold\n";
if (!inventory.empty() && rand() % 100 < 30) {
int index = rand() % inventory.size();
cout << "[LOSS] Lost " << inventory[index].name << " in panic\n";
inventory.erase(inventory.begin() + index);
}
energy -= 20;
if (energy < 0) energy = 0;
cout << "[ENERGY] Energy dropped to " << energy << "\n";
if (energy < 10) {
cout << "[WARNING] Energy critically low, returning to surface!\n";
currentDepth = 0;
energy = 30;
cout << "[ENERGY] Restored to " << energy << "\n";
}
}
// ========== **亡** ==========
void die(string cause) {
cout << "\n[DEATH] " << cause << "! You died!\n";
deaths++;
isDead = true;
// 被怪物杀**:矿物清零
if (cause.find("Killed") != string::npos) {
cout << "[LOSS] Killed by monster! All minerals lost!\n";
inventory.clear();
}
// 岩浆**亡:矿物和食物全部消失
else if (cause.find("Lava") != string::npos) {
cout << "[LOSS] Lava consumed everything! All minerals and food lost!\n";
inventory.clear();
foods.clear();
}
// 能量耗尽**亡:损失一半金币
else if (cause.find("Energy") != string::npos) {
cout << "[LOSS] Energy exhausted! Lost half of your gold!\n";
gold /= 2;
}
health = 0;
energy = 0;
cout << "\n[** OVER]\n";
cout << "Final Stats:\n";
cout << " Level: " << level << "\n";
cout << " Total Mined: " << totalMined << " times\n";
cout << " Monsters Killed: " << monstersKilled << "\n";
cout << " Total Gold Earned: " << totalGoldEarned << "\n";
cout << " Max Depth: " << currentDepth << "m\n";
}
// ========== 食物** ==========
void buyFood(int foodType, int quantity = 1) {
if (isDead) {
cout << "[DEAD] You are dead!\n";
return;
}
vector<Food> shopFoods = getShopFoods();
if (foodType < 0 || foodType >= shopFoods.size()) {
cout << "[ERROR] Invalid food choice!\n";
return;
}
Food selected = shopFoods[foodType];
int totalCost = selected.price * quantity;
if (gold < totalCost) {
cout << "[ERROR] Not enough gold! Need " << totalCost << " gold.\n";
return;
}
bool found = false;
for (int i = 0; i < foods.size(); i++) {
if (foods[i].name == selected.name) {
foods[i].quantity += quantity;
found = true;
break;
}
}
if (!found) {
selected.quantity = quantity;
foods.push_back(selected);
}
gold -= totalCost;
cout << "[PURCHASE] Bought " << quantity << " " << selected.symbol << selected.name << "!\n";
cout << "[PURCHASE] Spent " << totalCost << " gold\n";
}
vector<Food> getShopFoods() {
vector<Food> shopFoods;
shopFoods.push_back(Food("Cookie", 15, 20, 5, "[C]", 0));
shopFoods.push_back(Food("Bread", 30, 40, 10, "[B]", 0));
shopFoods.push_back(Food("Cake", 50, 70, 15, "[K]", 0));
shopFoods.push_back(Food("Pizza", 80, 100, 20, "[P]", 0));
shopFoods.push_back(Food("Steak", 120, 150, 30, "[S]", 0));
shopFoods.push_back(Food("EnergyDrink", 200, 200, 40, "[E]", 0));
return shopFoods;
}
void showShop() {
vector<Food> shopFoods = getShopFoods();
cout << "\n========== SHOP ==========\n";
cout << "Gold: " << gold << "\n";
cout << "HP: " << health << "/" << maxHealth << "\n";
cout << "Energy: " << energy << "/" << maxEnergy << "\n\n";
cout << "Select food to buy:\n";
for (int i = 0; i < shopFoods.size(); i++) {
cout << i + 1 << ". " << shopFoods[i].symbol << " "
<< shopFoods[i].name << " - " << shopFoods[i].price << " gold"
<< " (Restores " << shopFoods[i].energyRestore << " EN, "
<< shopFoods[i].healthRestore << " HP)\n";
}
cout << shopFoods.size() + 1 << ". Back\n";
cout << "> ";
}
void showFoodInventory() {
if (foods.empty()) {
cout << "[EMPTY] Food inventory is empty! Buy some food from the shop.\n";
return;
}
cout << "\n========== FOOD INVENTORY ==========\n";
int totalFoods = 0;
for (int i = 0; i < foods.size(); i++) {
if (foods[i].quantity > 0) {
cout << foods[i].symbol << " " << foods[i].name << " x" << foods[i].quantity
<< " (Restores " << foods[i].energyRestore << " EN, "
<< foods[i].healthRestore << " HP)\n";
totalFoods += foods[i].quantity;
}
}
cout << "Total: " << totalFoods << " food items\n";
cout << "====================================\n";
}
void eatFood(int foodIndex) {
if (foodIndex < 0 || foodIndex >= foods.size()) {
cout << "[ERROR] Invalid choice!\n";
return;
}
if (foods[foodIndex].quantity <= 0) {
cout << "[ERROR] No more " << foods[foodIndex].name << " left!\n";
return;
}
int healthRestore = foods[foodIndex].healthRestore;
int energyRestore = foods[foodIndex].energyRestore;
string foodName = foods[foodIndex].name;
bool healed = false;
bool energized = false;
// 恢复血量
if (health < maxHealth) {
health += healthRestore;
if (health > maxHealth) health = maxHealth;
healed = true;
}
// 恢复能量
if (energy < maxEnergy) {
energy += energyRestore;
if (energy > maxEnergy) energy = maxEnergy;
energized = true;
}
if (!healed && !energized) {
cout << "[FULL] HP and EN already full! No need to eat.\n";
return;
}
foods[foodIndex].quantity--;
if (foods[foodIndex].quantity == 0) {
foods.erase(foods.begin() + foodIndex);
}
cout << "[EAT] You ate " << foodName << "!\n";
if (healed) cout << "[HP] Restored " << healthRestore << " HP\n";
if (energized) cout << "[EN] Restored " << energyRestore << " EN\n";
cout << "Current: HP " << health << "/" << maxHealth << " | EN " << energy << "/" << maxEnergy << "\n";
}
void chooseFoodToEat() {
if (isDead) {
cout << "[DEAD] You are dead!\n";
return;
}
vector<Food> availableFoods;
for (int i = 0; i < foods.size(); i++) {
if (foods[i].quantity > 0) availableFoods.push_back(foods[i]);
}
if (availableFoods.empty()) {
cout << "[EMPTY] No food! Buy some from the shop.\n";
return;
}
cout << "\nSelect food to eat:\n";
for (int i = 0; i < availableFoods.size(); i++) {
cout << i + 1 << ". " << availableFoods[i].symbol << " " << availableFoods[i].name
<< " x" << availableFoods[i].quantity
<< " (Restores " << availableFoods[i].energyRestore << " EN, "
<< availableFoods[i].healthRestore << " HP)\n";
}
cout << availableFoods.size() + 1 << ". Cancel\n";
cout << "> ";
int choice;
cin >> choice;
if (choice >= 1 && choice <= availableFoods.size()) {
for (int i = 0; i < foods.size(); i++) {
if (foods[i].name == availableFoods[choice - 1].name) {
eatFood(i);
break;
}
}
} else if (choice == availableFoods.size() + 1) {
cout << "Cancelled.\n";
} else {
cout << "[ERROR] Invalid choice!\n";
}
}
// ========== 出售** ==========
void sellAll() {
if (isDead) {
cout << "[DEAD] You are dead!\n";
return;
}
if (inventory.empty()) {
cout << "[EMPTY] Inventory is empty!\n";
return;
}
int totalValue = 0;
for (int i = 0; i < inventory.size(); i++) {
totalValue += inventory[i].value;
}
gold += totalValue;
totalGoldEarned += totalValue;
cout << "[SOLD] Sold " << inventory.size() << " minerals for " << totalValue << " gold!\n";
inventory.clear();
}
// ========== 升级** ==========
void upgradePickaxe() {
if (isDead) {
cout << "[DEAD] You are dead!\n";
return;
}
int cost = pickaxeLevel * 100;
if (gold < cost) {
cout << "[ERROR] Not enough gold! Need " << cost << " gold.\n";
return;
}
if (pickaxeLevel >= 5) {
cout << "[MAX] Pickaxe is already max level!\n";
return;
}
gold -= cost;
pickaxeLevel++;
cout << "[UPGRADE] Pickaxe upgraded to level " << pickaxeLevel << "!\n";
}
void rest() {
if (isDead) {
cout << "[DEAD] You are dead!\n";
return;
}
health += 20;
if (health > maxHealth) health = maxHealth;
energy += 30;
if (energy > maxEnergy) energy = maxEnergy;
cout << "[REST] Rested and restored some stats!\n";
cout << "HP: " << health << "/" << maxHealth << "\n";
cout << "EN: " << energy << "/" << maxEnergy << "\n";
}
void addExp(int amount) {
exp += amount;
cout << "[EXP] Gained " << amount << " experience!\n";
while (exp >= maxExp) {
exp -= maxExp;
level++;
maxExp = level * 100;
maxHealth += 10;
health = maxHealth;
maxEnergy += 10;
energy = maxEnergy;
cout << "[LEVEL UP] Now level " << level << "!\n";
cout << "[STATS] Max HP increased to " << maxHealth << "\n";
cout << "[STATS] Max EN increased to " << maxEnergy << "\n";
}
}
// ========== 显示** ==========
void showStatus() {
cout << "\n========== PLAYER STATS ==========\n";
cout << "Name: " << name << "\n";
cout << "Level: " << level << "\n";
cout << "EXP: " << exp << "/" << maxExp << "\n";
cout << "Gold: " << gold << "\n";
cout << "HP: " << health << "/" << maxHealth << "\n";
cout << "Energy: " << energy << "/" << maxEnergy << "\n";
cout << "Pickaxe: " << pickaxeLevel << "/5\n";
cout << "Depth: " << currentDepth << "m\n";
cout << "Minerals: " << inventory.size() << "\n";
cout << "Food: " << getTotalFoodCount() << "\n";
cout << "Total Mined: " << totalMined << "\n";
cout << "Monsters Killed: " << monstersKilled << "\n";
cout << "Deaths: " << deaths << "\n";
cout << "Total Gold Earned: " << totalGoldEarned << "\n";
cout << "==================================\n";
}
void showInventory() {
if (inventory.empty()) {
cout << "[EMPTY] Inventory is empty!\n";
return;
}
cout << "\n========== INVENTORY ==========\n";
for (int i = 0; i < inventory.size(); i++) {
cout << i + 1 << ". " << inventory[i].symbol << " "
<< inventory[i].name << " - Value: " << inventory[i].value << " gold\n";
}
cout << "Total Value: " << getInventoryValue() << " gold\n";
cout << "================================\n";
}
int getTotalFoodCount() {
int total = 0;
for (int i = 0; i < foods.size(); i++) {
total += foods[i].quantity;
}
return total;
}
int getInventoryValue() {
int total = 0;
for (int i = 0; i < inventory.size(); i++) {
total += inventory[i].value;
}
return total;
}
// ========== 存档** ==========
bool saveGame(const string& filename = "savegame.txt") {
ofstream file(filename.c_str());
if (!file.is_open()) {
cout << "[ERROR] Cannot create save file!\n";
return false;
}
file << "PLAYER_DATA\n";
file << name << "\n";
file << gold << "\n";
file << energy << "\n";
file << maxEnergy << "\n";
file << health << "\n";
file << maxHealth << "\n";
file << level << "\n";
file << exp << "\n";
file << maxExp << "\n";
file << pickaxeLevel << "\n";
file << totalMined << "\n";
file << totalGoldEarned << "\n";
file << monstersKilled << "\n";
file << deaths << "\n";
file << currentDepth << "\n";
file << isDead << "\n";
file << "INVENTORY\n";
file << inventory.size() << "\n";
for (int i = 0; i < inventory.size(); i++) {
file << inventory[i].serialize() << "\n";
}
file << "FOODS\n";
file << foods.size() << "\n";
for (int i = 0; i < foods.size(); i++) {
file << foods[i].serialize() << "\n";
}
file << "END\n";
file.close();
cout << "[SAVE] Game saved successfully!\n";
return true;
}
bool loadGame(const string& filename = "savegame.txt") {
ifstream file(filename.c_str());
if (!file.is_open()) {
cout << "[ERROR] Cannot find save file!\n";
return false;
}
string line;
getline(file, line);
getline(file, name);
getline(file, line); gold = stoi(line);
getline(file, line); energy = stoi(line);
getline(file, line); maxEnergy = stoi(line);
getline(file, line); health = stoi(line);
getline(file, line); maxHealth = stoi(line);
getline(file, line); level = stoi(line);
getline(file, line); exp = stoi(line);
getline(file, line); maxExp = stoi(line);
getline(file, line); pickaxeLevel = stoi(line);
getline(file, line); totalMined = stoi(line);
getline(file, line); totalGoldEarned = stoi(line);
getline(file, line); monstersKilled = stoi(line);
getline(file, line); deaths = stoi(line);
getline(file, line); currentDepth = stoi(line);
getline(file, line); isDead = stoi(line) != 0;
getline(file, line);
getline(file, line);
int inventorySize = stoi(line);
inventory.clear();
for (int i = 0; i < inventorySize; i++) {
getline(file, line);
if (!line.empty()) {
inventory.push_back(Mineral::deserialize(line));
}
}
getline(file, line);
getline(file, line);
int foodSize = stoi(line);
foods.clear();
for (int i = 0; i < foodSize; i++) {
getline(file, line);
if (!line.empty()) {
foods.push_back(Food::deserialize(line));
}
}
file.close();
cout << "[LOAD] Game loaded successfully! Welcome back, " << name << "!\n";
return true;
}
// Getters
string getName() const { return name; }
int getGold() const { return gold; }
int getEnergy() const { return energy; }
int getHealth() const { return health; }
int getLevel() const { return level; }
int getPickaxeLevel() const { return pickaxeLevel; }
int getMaxEnergy() const { return maxEnergy; }
int getMaxHealth() const { return maxHealth; }
int getCurrentDepth() const { return currentDepth; }
int getMonstersKilled() const { return monstersKilled; }
int getDeaths() const { return deaths; }
bool getIsDead() const { return isDead; }
vector<Mineral>& getInventory() { return inventory; }
vector<Food>& getFoods() { return foods; }
};
// ========== 游戏类 ==========
class Game {
private:
Player player;
bool isRunning;
string saveFileName;
int gameTick;
public:
Game(string playerName = "") : player(playerName), isRunning(true),
saveFileName("savegame.txt"), gameTick(0) {
srand(time(NULL));
}
void run() {
cout << "\n=== MINING ** ===\n";
cout << "[WARNING] Dangerous monsters and lava in the deep!\n";
cout << "[HINT] Prepare well before digging deep!\n\n";
if (checkSaveExists()) {
cout << "[SAVE] Save file detected. Continue previous game?\n";
cout << "1. Continue\n";
cout << "2. New Game\n";
cout << "> ";
int choice;
cin >> choice;
if (choice == 1) {
player.loadGame(saveFileName);
} else {
cout << "Starting new game!\n";
if (player.getName().empty()) {
cout << "Enter your name: ";
string name;
cin >> name;
if (name.empty()) {
name = "Miner";
}
player = Player(name);
}
}
} else {
if (player.getName().empty()) {
cout << "Enter your name: ";
string name;
cin >> name;
if (name.empty()) {
name = "Miner";
}
player = Player(name);
}
}
cout << "\nPlayer: " << player.getName() << "\n";
cout << "Enter commands to begin!\n\n";
while (isRunning) {
player.displayHUD();
processInput();
gameTick++;
// 每5个游戏tick更新一次能量消耗
if (gameTick % 5 == 0) {
player.updateEnergyAndHealth();
if (player.getIsDead()) {
cout << "\n[** OVER] Press any key to exit...\n";
cin.ignore();
cin.get();
isRunning = false;
}
}
}
}
bool checkSaveExists() {
ifstream file(saveFileName.c_str());
return file.good();
}
void processInput() {
int choice;
cin >> choice;
switch (choice) {
case 1:
player.mine();
break;
case 2:
player.showInventory();
break;
case 3:
player.sellAll();
break;
case 4:
player.upgradePickaxe();
break;
case 5:
player.chooseFoodToEat();
break;
case 6:
shopMenu();
break;
case 7:
player.rest();
break;
case 8:
player.showStatus();
break;
case 9:
player.saveGame(saveFileName);
break;
case 0:
cout << "[SAVE] Saving game...\n";
player.saveGame(saveFileName);
cout << "[EXIT] Thanks for playing! Goodbye!\n";
isRunning = false;
break;
default:
cout << "[ERROR] Invalid input!\n";
}
}
void shopMenu() {
while (true) {
player.showShop();
int choice;
cin >> choice;
vector<Food> shopFoods = player.getShopFoods();
if (choice >= 1 && choice <= shopFoods.size()) {
cout << "Quantity (1-99): ";
int quantity;
cin >> quantity;
if (quantity < 1 || quantity > 99) {
cout << "[ERROR] Quantity must be between 1 and 99!\n";
continue;
}
player.buyFood(choice - 1, quantity);
break;
} else if (choice == shopFoods.size() + 1) {
cout << "Returning to main menu...\n";
break;
} else {
cout << "[ERROR] Invalid choice!\n";
}
}
}
};
int main() {
Game game;
game.run();
return 0;
}
注意:本帖拒绝水


