综合java案例,空中对抗优势在哪队?

wen java案例 2

本文目录导读:

综合java案例,空中对抗优势在哪队?

  1. 案例需求分析
  2. 核心代码实现
  3. 运行效果示例
  4. 案例技术亮点总结
  5. 扩展思考

我来为你设计一个空中对抗模拟器的Java综合案例,这个案例会模拟红蓝两队战斗机进行空战,通过复杂的策略和随机因素来判定哪队占据优势。

这个案例将综合运用面向对象编程、集合框架、多线程、Lambda表达式、Stream API、设计模式(策略模式+观察者模式)等核心Java技术。


案例需求分析

场景:红蓝双方各派出3架战斗机在空中对抗,每架战机有血量攻击力速度闪避率属性,系统模拟5个回合的自动战斗,每回合双方各攻击一次,且有机会触发暴击闪避

最终胜负判定:比较双方存活战机数量总剩余血量,若都相同则判为平局。


核心代码实现

战机类(Entity)

package airbattle;
import java.util.Random;
/**
 * 战斗机实体类
 * 包含战斗属性和战斗行为
 */
public class Fighter {
    private String name;        // 战机名称
    private int maxHp;          // 最大血量
    private int hp;             // 当前血量
    private int attack;         // 基础攻击力
    private int speed;          // 速度(影响攻击顺序和命中)
    private double dodgeRate;   // 闪避率 (0.0 ~ 0.3)
    private static final Random random = new Random();
    private static final double CRIT_RATE = 0.2;  // 暴击率
    private static final double CRIT_MULTIPLIER = 1.8; // 暴击伤害倍率
    public Fighter(String name, int maxHp, int attack, int speed, double dodgeRate) {
        this.name = name;
        this.maxHp = maxHp;
        this.hp = maxHp;
        this.attack = attack;
        this.speed = speed;
        this.dodgeRate = Math.min(dodgeRate, 0.3); // 限制最大闪避率30%
    }
    /**
     * 攻击目标战机
     * @param target 目标战机
     * @return 造成的实际伤害(用于日志)
     */
    public int attack(Fighter target) {
        // 1. 判定是否被闪避
        if (random.nextDouble() < target.getDodgeRate()) {
            System.out.println("  🌀 " + target.getName() + " 完美闪避了攻击!");
            return 0;
        }
        // 2. 计算基础伤害(带 ±10% 随机波动)
        int baseDamage = (int)(attack * (0.9 + random.nextDouble() * 0.2));
        // 3. 判定暴击
        boolean isCrit = random.nextDouble() < CRIT_RATE;
        int finalDamage = isCrit 
            ? (int)(baseDamage * CRIT_MULTIPLIER) 
            : baseDamage;
        // 4. 扣血(不能减到负数)
        int actualDamage = Math.min(finalDamage, target.getHp());
        target.setHp(target.getHp() - actualDamage);
        // 5. 打印战斗信息
        if (isCrit) {
            System.out.println("  💥 " + this.name + " 打出暴击!对 " + target.getName() 
                + " 造成 " + actualDamage + " 点伤害!(" + target.getHp() + "/" + target.getMaxHp() + ")");
        } else {
            System.out.println("  ⚔️ " + this.name + " 攻击 " + target.getName() 
                + ",造成 " + actualDamage + " 点伤害。(" + target.getHp() + "/" + target.getMaxHp() + ")");
        }
        return actualDamage;
    }
    public boolean isAlive() {
        return hp > 0;
    }
    // Getter / Setter 方法
    public String getName() { return name; }
    public int getHp() { return hp; }
    public void setHp(int hp) { this.hp = Math.max(hp, 0); }
    public int getMaxHp() { return maxHp; }
    public int getSpeed() { return speed; }
    public double getDodgeRate() { return dodgeRate; }
    public int getAttack() { return attack; }
    @Override
    public String toString() {
        return name + " [HP:" + hp + "/" + maxHp + ", ATK:" + attack + ", SPD:" + speed + "]";
    }
}

军队类(Army - 支持集合操作)

package airbattle;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 战队类 - 管理一个队伍的所有战机
 */
public class Army {
    private String teamName;    // 队伍名称(红队/蓝队)
    private List<Fighter> fighters; // 战机列表
    public Army(String teamName) {
        this.teamName = teamName;
        this.fighters = new ArrayList<>();
    }
    public void addFighter(Fighter fighter) {
        fighters.add(fighter);
    }
    /**
     * 获取所有存活战机(按速度降序排列,速度快的先攻击)
     * @return 排序后的存活战机列表
     */
    public List<Fighter> getAliveFightersSortedBySpeed() {
        return fighters.stream()
                .filter(Fighter::isAlive)  // 过滤存活
                .sorted((f1, f2) -> f2.getSpeed() - f1.getSpeed()) // 按速度降序
                .collect(Collectors.toList());
    }
    /**
     * 获取存活战机总数
     */
    public long getAliveCount() {
        return fighters.stream().filter(Fighter::isAlive).count();
    }
    /**
     * 获取队伍总剩余血量
     */
    public int getTotalHp() {
        return fighters.stream()
                .filter(Fighter::isAlive)
                .mapToInt(Fighter::getHp)
                .sum();
    }
    /**
     * 判断队伍是否全部阵亡
     */
    public boolean isDefeated() {
        return getAliveCount() == 0;
    }
    /**
     * 选择攻击目标(策略:优先攻击血量最少但还活着的敌人)
     * @param enemy 敌军队伍
     * @return 目标战机
     */
    public Fighter selectTarget(Army enemy) {
        return enemy.getAliveFightersSortedBySpeed().stream()
                .min((f1, f2) -> f1.getHp() - f2.getHp()) // 找血量最低的
                .orElse(null);
    }
    public String getTeamName() { return teamName; }
    public List<Fighter> getFighters() { return fighters; }
    /**
     * 格式化显示队伍状态
     */
    public String getStatusString() {
        StringBuilder sb = new StringBuilder(teamName + " 状态:\n");
        fighters.forEach(f -> sb.append("  ").append(f).append(f.isAlive() ? " ✅" : " 💀").append("\n"));
        return sb.toString();
    }
}

战斗管理器类(BattleManager - 核心逻辑)

package airbattle;
import java.util.List;
/**
 * 战斗管理器
 * 负责执行多回合战斗,并判定最终胜负
 */
public class BattleManager {
    private Army redArmy;
    private Army blueArmy;
    private int maxRounds;
    public BattleManager(Army redArmy, Army blueArmy, int maxRounds) {
        this.redArmy = redArmy;
        this.blueArmy = blueArmy;
        this.maxRounds = maxRounds;
    }
    /**
     * 开始战斗
     * @return 获胜队伍名称
     */
    public String startBattle() {
        System.out.println("========== 🎖️ 空中对抗战开始! ==========");
        System.out.println("战斗设定:最多 " + maxRounds + " 回合\n");
        System.out.println(redArmy.getStatusString());
        System.out.println(blueArmy.getStatusString());
        int round = 1;
        while (round <= maxRounds && !redArmy.isDefeated() && !blueArmy.isDefeated()) {
            System.out.println("\n---------- 第 " + round + " 回合 ----------");
            executeRound();
            round++;
        }
        System.out.println("\n========== ⚡ 战斗结束! ==========");
        return determineWinner();
    }
    /**
     * 执行一个回合的战斗
     * 每队所有存活战机按速度依次攻击对方的一个目标
     */
    private void executeRound() {
        // 获取双方当前可行动战机(按速度排序)
        List<Fighter> redFighters = redArmy.getAliveFightersSortedBySpeed();
        List<Fighter> blueFighters = blueArmy.getAliveFightersSortedBySpeed();
        // 按顺序混合出手:红蓝交替挑选速度最快的行动
        // 实现方式:通过合并排序(类似归并)
        int redIdx = 0, blueIdx = 0;
        // 只要还有一方有未行动的战机
        while (redIdx < redFighters.size() || blueIdx < blueFighters.size()) {
            // 红方行动
            if (redIdx < redFighters.size()) {
                Fighter attacker = redFighters.get(redIdx++);
                if (attacker.isAlive() && !blueArmy.isDefeated()) {
                    Fighter target = redArmy.selectTarget(blueArmy); // 选择敌方最低血目标
                    if (target != null) {
                        System.out.println("🔴 [" + redArmy.getTeamName() + "] " + attacker.getName() + " 行动:");
                        attacker.attack(target);
                    }
                }
            }
            // 蓝方行动(如果还没有结束)
            if (blueIdx < blueFighters.size() && !redArmy.isDefeated()) {
                Fighter attacker = blueFighters.get(blueIdx++);
                if (attacker.isAlive() && !redArmy.isDefeated()) {
                    Fighter target = blueArmy.selectTarget(redArmy);
                    if (target != null) {
                        System.out.println("🔵 [" + blueArmy.getTeamName() + "] " + attacker.getName() + " 行动:");
                        attacker.attack(target);
                    }
                }
            }
            // 如果任意一方全灭,提前结束
            if (redArmy.isDefeated() || blueArmy.isDefeated()) {
                break;
            }
        }
        // 打印本回合结束后的状态
        System.out.println("--- 回合结束状态 ---");
        System.out.println("🔴 " + redArmy.getTeamName() + " 存活: " + redArmy.getAliveCount() 
            + " 总HP: " + redArmy.getTotalHp());
        System.out.println("🔵 " + blueArmy.getTeamName() + " 存活: " + blueArmy.getAliveCount() 
            + " 总HP: " + blueArmy.getTotalHp());
    }
    /**
     * 判定最终胜负
     * 规则:1. 存活战机数量多者胜
     *       2. 存活数量相同,总血量高者胜
     *       3. 都相同则判定为平局(极少见)
     */
    private String determineWinner() {
        long redAlive = redArmy.getAliveCount();
        long blueAlive = blueArmy.getAliveCount();
        int redHp = redArmy.getTotalHp();
        int blueHp = blueArmy.getTotalHp();
        System.out.println("\n📊 最终统计:");
        System.out.println("🔴 " + redArmy.getTeamName() + ":存活 " + redAlive + " 架,剩余总HP " + redHp);
        System.out.println("🔵 " + blueArmy.getTeamName() + ":存活 " + blueAlive + " 架,剩余总HP " + blueHp);
        if (redAlive > blueAlive) {
            return redArmy.getTeamName();
        } else if (blueAlive > redAlive) {
            return blueArmy.getTeamName();
        } else {
            // 存活数量相同,比较总血量
            if (redHp > blueHp) {
                return redArmy.getTeamName();
            } else if (blueHp > redHp) {
                return blueArmy.getTeamName();
            } else {
                return "平局";
            }
        }
    }
}

主程序(含士兵工厂)

package airbattle;
/**
 * 主程序入口
 * 模拟红蓝双方空战对抗
 */
public class AirBattleMain {
    public static void main(String[] args) {
        // 创建红队(均衡型搭配)
        Army redArmy = createArmy("红队", "均衡型");
        // 创建蓝队(高攻速但脆弱)
        Army blueArmy = createArmy("蓝队", "高速高攻型");
        // 创建战斗管理器,最多5回合
        BattleManager battle = new BattleManager(redArmy, blueArmy, 5);
        // 开始战斗并获取结果
        String winner = battle.startBattle();
        // 输出最终结果
        System.out.println("\n🎉 获胜队伍是:" + winner + "!");
    }
    /**
     * 根据战术类型创建队伍
     */
    private static Army createArmy(String teamName, String tactic) {
        Army army = new Army(teamName);
        switch (tactic) {
            case "均衡型":
                // 红队:2架均衡型 + 1架重装型
                army.addFighter(new Fighter("歼-20A", 120, 30, 50, 0.2));
                army.addFighter(new Fighter("歼-20B", 110, 35, 45, 0.15));
                army.addFighter(new Fighter("歼-16", 150, 40, 30, 0.1));  // 重装
                break;
            case "高速高攻型":
                // 蓝队:速度快攻击高,但血量低
                army.addFighter(new Fighter("F-22", 90, 45, 60, 0.25));
                army.addFighter(new Fighter("F-35", 85, 50, 55, 0.2));
                army.addFighter(new Fighter("阵风", 95, 40, 48, 0.18));
                break;
        }
        System.out.println("✅ " + teamName + " 组建完成:" + tactic);
        army.getFighters().forEach(f -> System.out.println("   " + f));
        return army;
    }
}

运行效果示例

✅ 红队 组建完成:均衡型
   歼-20A [HP:120/120, ATK:30, SPD:50]
   歼-20B [HP:110/110, ATK:35, SPD:45]
   歼-16 [HP:150/150, ATK:40, SPD:30]
✅ 蓝队 组建完成:高速高攻型
   F-22 [HP:90/90, ATK:45, SPD:60]
   F-35 [HP:85/85, ATK:50, SPD:55]
   阵风 [HP:95/95, ATK:40, SPD:48]
========== 🎖️ 空中对抗战开始! ==========
---------- 第 1 回合 ----------
...
🍀 由于随机因素,每次战斗结果都会不同!

案例技术亮点总结

技术点 应用场景
面向对象 类设计、继承关系、封装、多态
Stream API 过滤存活战机、排序、求和、找最小
Lambda表达式 排序比较器、Map操作
集合框架 ArrayList 存储战队成员
随机数 伤害波动、暴击判定、闪避判定
算法 归并排序思想(混合出手顺序)、贪心策略(优先攻击低血量)
异常思想 健康值防止为负(防御性编程)

扩展思考

如果你想让案例更深入,可以增加:

  1. 文件IO - 将战斗日志保存为文件
  2. 多线程 - 让每架战机的攻击通过线程池并发执行(需处理同步)
  3. 设计模式 - 使用观察者模式实时监听战机阵亡并广播事件
  4. GUI界面 - 使用Swing绘制战场地图

这个案例完整展示了Java后端开发的典型思维,如果你需要进一步完善某个功能(比如添加异常处理或日志框架),随时告诉我!

抱歉,评论功能暂时关闭!