use std::io;
use rand::Rng;
use std::collections::HashMap;

// 装备类型枚举
#[derive(Debug, Clone, Copy)]
enum EquipmentType {
    Weapon,  // 武器:增加攻击力
    Armor,   // 防具:增加防御力
}

// 装备结构体
#[derive(Debug, Clone)]
struct Equipment {
    name: String,
    eq_type: EquipmentType,
    level: u32,
    bonus: u32,  // 武器加攻击,防具加防御
    price: u32,
}

// 玩家结构体
struct Player {
    level: u32,
    hp: u32,
    max_hp: u32,
    attack: u32,
    defense: u32,
    exp: u32,
    exp_to_next: u32,
    gold: u32,
    inventory: Vec<Equipment>,
}

// 怪物结构体
struct Monster {
    name: String,
    level: u32,
    hp: u32,
    attack: u32,
    defense: u32,
    exp_reward: u32,
    gold_reward: u32,
}

impl Player {
    // 创建新玩家
    fn new() -> Self {
        Player {
            level: 1,
            hp: 100,
            max_hp: 100,
            attack: 10,
            defense: 5,
            exp: 0,
            exp_to_next: 50,
            gold: 0,
            inventory: Vec::new(),
        }
    }

    // 显示玩家状态
    fn show_status(&self) {
        println!("\n===== 玩家状态 =====");
        println!("等级: Lv.{}", self.level);
        println!("生命值: {}/{}", self.hp, self.max_hp);
        println!("攻击力: {}", self.attack);
        println!("防御力: {}", self.defense);
        println!("当前经验: {}/{}", self.exp, self.exp_to_next);
        println!("金币: {}G", self.gold);
        println!("背包装备数量: {}\n", self.inventory.len());
    }

    // 升级处理
    fn level_up(&mut self) {
        self.level += 1;
        self.max_hp += 30;
        self.hp = self.max_hp;
        self.attack += 5;
        self.defense += 3;
        self.exp -= self.exp_to_next;
        self.exp_to_next = (self.exp_to_next as f64 * 1.5) as u32;
        println!("\n恭喜升级!当前等级: Lv.{}", self.level);
        println!("属性提升:生命值+30,攻击力+5,防御力+3");
    }

    // 检查是否可以升级
    fn check_level_up(&mut self) {
        while self.exp >= self.exp_to_next {
            self.level_up();
        }
    }

    // 添加装备到背包
    fn add_equipment(&mut self, eq: Equipment) {
        self.inventory.push(eq);
        println!("获得装备: {}", eq.name);
    }

    // 出售装备
    fn sell_equipment(&mut self, index: usize) -> Option<u32> {
        if index < self.inventory.len() {
            let eq = self.inventory.remove(index);
            println!("成功出售 [{}],获得 {}G", eq.name, eq.price);
            Some(eq.price)
        } else {
            None
        }
    }
}

impl Monster {
    // 根据玩家等级生成怪物
    fn generate(player_level: u32) -> Self {
        let rng = rand::thread_rng().gen_range(0..3);
        let level = player_level + rand::thread_rng().gen_range(0..2);
        
        // 怪物模板
        let monsters = HashMap::from([
            (0, ("史莱姆", 80, 8, 2, 30, 15)),
            (1, ("哥布林", 120, 12, 4, 45, 25)),
            (2, ("骷髅兵", 150, 15, 6, 60, 35)),
        ]);

        let (name, hp, attack, defense, exp, gold) = monsters[&rng];
        Monster {
            name: name.to_string(),
            level,
            hp: hp + (level - 1) as u32 * 20,
            attack: attack + (level - 1) as u32 * 3,
            defense: defense + (level - 1) as u32 * 2,
            exp_reward: exp + (level - 1) as u32 * 10,
            gold_reward: gold + (level - 1) as u32 * 5,
        }
    }
}

// 生成随机装备
fn generate_equipment(level: u32) -> Equipment {
    let rng = rand::thread_rng().gen_range(0..2);
    let eq_type = if rng == 0 { EquipmentType::Weapon } else { EquipmentType::Armor };
    
    let (base_name, base_bonus, base_price) = match eq_type {
        EquipmentType::Weapon => ("铁剑", 10, 50),
        EquipmentType::Armor => ("皮甲", 5, 40),
    };

    let level_bonus = level as u32 * 3;
    let name = format!("{}+{}", base_name, level);
    
    Equipment {
        name,
        eq_type,
        level,
        bonus: base_bonus + level_bonus,
        price: base_price + level_bonus * 5,
    }
}

// 战斗逻辑
fn fight(player: &mut Player) {
    let monster = Monster::generate(player.level);
    println!("\n===== 遭遇怪物 =====");
    println!("Lv.{} {} 出现了!", monster.level, monster.name);
    println!("怪物属性:生命值{},攻击力{},防御力{}", monster.hp, monster.attack, monster.defense);

    let mut player_hp = player.hp;
    let mut monster_hp = monster.hp;
    let mut round = 1;

    loop {
        println!("\n----- 第{}回合 -----", round);
        
        // 玩家攻击
        let player_damage = if player.attack > monster.defense {
            player.attack - monster.defense
        } else {
            1 // 保底伤害
        };
        monster_hp = monster_hp.saturating_sub(player_damage);
        println!("你对{}造成了{}点伤害!", monster.name, player_damage);

        if monster_hp == 0 {
            println!("成功击败{}!", monster.name);
            // 奖励处理
            player.exp += monster.exp_reward;
            player.gold += monster.gold_reward;
            println!("获得 {} 经验值和 {}G", monster.exp_reward, monster.gold_reward);
            
            // 随机掉落装备(30%概率)
            if rand::thread_rng().gen_range(0..10) < 3 {
                let eq = generate_equipment(monster.level);
                player.add_equipment(eq);
            }
            
            // 检查升级
            player.check_level_up();
            // 恢复生命值
            player.hp = player.max_hp;
            break;
        }

        // 怪物攻击
        let monster_damage = if monster.attack > player.defense {
            monster.attack - player.defense
        } else {
            1
        };
        player_hp = player_hp.saturating_sub(monster_damage);
        println!("{}对你造成了{}点伤害!你的生命值:{}", monster.name, monster_damage, player_hp);

        if player_hp == 0 {
            println!("\n很遗憾,你被{}击败了...", monster.name);
            // 失败惩罚:少量经验和金币
            player.exp = player.exp.saturating_sub(monster.exp_reward / 3);
            player.gold = player.gold.saturating_sub(monster.gold_reward / 3);
            // 恢复部分生命值
            player.hp = player.max_hp / 2;
            break;
        }

        round += 1;
    }
}

// 市场系统
fn market(player: &mut Player) {
    if player.inventory.is_empty() {
        println!("\n背包空空如也,没有可出售的装备!");
        return;
    }

    loop {
        println!("\n===== 市场 =====");
        println!("你的金币:{}G", player.gold);
        println!("0. 退出市场");
        
        // 展示背包装备
        for (i, eq) in player.inventory.iter().enumerate() {
            let bonus_info = match eq.eq_type {
                EquipmentType::Weapon => format!("攻击力+{}", eq.bonus),
                EquipmentType::Armor => format!("防御力+{}", eq.bonus),
            };
            println!("{}. {} (Lv.{},{},售价:{}G)", i+1, eq.name, eq.level, bonus_info, eq.price);
        }

        // 输入选择
        let mut input = String::new();
        io::stdin().read_line(&mut input).expect("输入错误");
        let choice: usize = match input.trim().parse() {
            Ok(num) => num,
            Err(_) => {
                println!("请输入有效数字!");
                continue;
            }
        };

        if choice == 0 {
            println!("离开市场");
            break;
        } else if choice <= player.inventory.len() {
            // 出售装备(索引转换:选择1对应索引0)
            if let Some(price) = player.sell_equipment(choice - 1) {
                player.gold += price;
            }
            // 如果背包空了,自动退出市场
            if player.inventory.is_empty() {
                println!("背包已空,自动离开市场");
                break;
            }
        } else {
            println!("选择无效!");
        }
    }
}

// 主游戏逻辑
fn main() {
    let mut player = Player::new();
    println!("===== 打怪升级爆装备游戏 =====");
    println!("欢迎来到冒险世界!通过打怪获取经验升级,收集装备并在市场出售吧!");

    loop {
        println!("\n===== 主菜单 =====");
        println!("1. 查看状态");
        println!("2. 挑战怪物");
        println!("3. 前往市场");
        println!("4. 退出游戏");
        print!("请选择操作:");

        let mut input = String::new();
        io::stdin().read_line(&mut input).expect("输入错误");
        let choice: u8 = match input.trim().parse() {
            Ok(num) => num,
            Err(_) => {
                println!("请输入1-4之间的数字!");
                continue;
            }
        };

        match choice {
            1 => player.show_status(),
            2 => fight(&mut player),
            3 => market(&mut player),
            4 => {
                println!("感谢游玩!再见~");
                break;
            }
            _ => println!("请输入1-4之间的数字!"),
        }
    }
}
一、游戏介绍

这是一款基于 Rust 语言开发的控制台小游戏,核心玩法包括角色成长、怪物战斗、装备掉落与市场交易。玩家将从初始状态开始,通过挑战不同等级的怪物获取经验值升级,同时有概率获得各类装备,可将闲置装备在市场出售换取金币,不断提升自身战力。游戏操作简单,通过控制台输入指令即可完成所有交互,适合作为 Rust 初学者的实战练习项目。

二、核心功能设计
  1. 角色系统:玩家角色包含等级、生命值、攻击力、经验值、金币和背包(存储装备)属性,升级时会提升基础属性
  2. 怪物系统:不同等级的怪物拥有不同战力,等级与玩家等级挂钩(略高于或等于玩家等级)
  3. 战斗系统:回合制战斗,计算双方伤害,胜者获得经验和金币,有概率获得装备
  4. 装备系统:装备包含类型(武器 / 防具)、等级、攻击力 / 防御力加成和售价
  5. 市场系统:展示背包中的装备,支持选择出售并获取金币
    、代码解析
  6. 数据结构设计

    • 使用 Player 结构体存储玩家核心属性,包括等级、生命值、攻防属性、经验值、金币和装备背包
    • Monster 结构体定义怪物属性,通过 generate 方法根据玩家等级动态生成适配难度的怪物
    • Equipment 结构体与 EquipmentType 枚举配合,区分武器(加攻击)和防具(加防御),包含等级、属性加成和售价信息
  7. 核心逻辑实现

    • 战斗系统:采用回合制计算,攻击方伤害 = 自身攻击 - 敌方防御(最低 1 点伤害),胜利后获得经验、金币和概率掉落装备
    • 升级系统:经验值达到阈值后自动升级,提升生命值、攻防属性,并提高下一等级所需经验
    • 市场系统:遍历玩家背包展示可售装备,支持选择出售并实时更新金币数量
  8. 交互设计

    • 通过控制台输入指令实现菜单导航,使用 io::stdin 处理用户输入
    • 战斗过程中实时显示双方状态和伤害数值,增强游戏反馈感
    • 这款游戏虽然简单,但涵盖了 Rust 的核心语法特性:结构体与枚举的使用、所有权与借用机制、流程控制、随机数生成和标准输入输出处理。通过开发此类小游戏,能有效加深对 Rust 内存安全模型和类型系统的理解,同时体验从 0 到 1 实现游戏逻辑的乐趣。对于初学者来说,这是一个兼顾实用性与趣味性的练手项目。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐