问题标题: MINER.cpp

0
0
高驰宇
高驰宇
新手天翼
新手天翼

#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;
}

注意:本帖拒绝水


0
0
0
0
我要回答