综合java案例,两回合制首回合如何部署?

wen java案例 3

Java 两回合制游戏:首回合部署方案

下面以一个 回合制战棋/卡牌对战 的通用 Java 案例,讲解首回合部署的设计与实现,你可以按需裁剪。

综合java案例,两回合制首回合如何部署?


核心设计思路

首回合部署通常需要解决三件事:

  1. 先手判定(谁先部署)
  2. 部署资源限制(首回合可上场的单位数/费用)
  3. 部署合法区域(己方半场、指定格子等)

设计原则:首回合特殊规则用"独立的部署阶段策略"封装,避免污染后续回合逻辑。


领域模型

// 单位
public class Unit {
    private final String id;
    private final int cost;        // 部署费用
    private final int hp;
    private final int atk;
    private int x, y;              // 棋盘坐标
    private boolean deployed;
    // 构造、getter/setter 省略
}
// 玩家
public class Player {
    private final String name;
    private int resource;          // 资源/费用
    private final List<Unit> hand = new ArrayList<>();   // 手牌
    private final List<Unit> field = new ArrayList<>();  // 场上单位
    // ...
}
// 棋盘
public class Board {
    public static final int WIDTH = 8, HEIGHT = 8;
    private final Unit[][] grid = new Unit[HEIGHT][WIDTH];
    public boolean inOwnHalf(int playerIndex, int x, int y) {
        // 玩家0占下半场(y>=4),玩家1占上半场(y<4)
        return playerIndex == 0 ? y >= HEIGHT / 2 : y < HEIGHT / 2;
    }
    public boolean isEmpty(int x, int y) { return grid[y][x] == null; }
    public void place(Unit u, int x, int y) { grid[y][x] = u; u.setX(x); u.setY(y); }
}

部署阶段策略(核心)

用策略模式区分"首回合部署"与"常规部署":

public interface DeployStrategy {
    /** 本回合允许部署的最大单位数 */
    int maxUnitsThisTurn(int turnNo);
    /** 校验一次部署是否合法 */
    boolean canDeploy(Player p, Board b, Unit u, int x, int y, int turnNo);
}

首回合部署策略

public class FirstTurnDeployStrategy implements DeployStrategy {
    private static final int FIRST_TURN_MAX_UNITS = 2;   // 首回合最多上 2 个单位
    @Override
    public int maxUnitsThisTurn(int turnNo) {
        return turnNo == 1 ? FIRST_TURN_MAX_UNITS : Integer.MAX_VALUE;
    }
    @Override
    public boolean canDeploy(Player p, Board b, Unit u, int x, int y, int turnNo) {
        // 1. 资源足够
        if (u.getCost() > p.getResource()) return false;
        // 2. 格子空闲且在己方半场
        if (!b.isEmpty(x, y) || !b.inOwnHalf(playerIndex(p), x, y)) return false;
        // 3. 首回合单位数上限
        if (p.getField().size() >= maxUnitsThisTurn(turnNo)) return false;
        return true;
    }
    private int playerIndex(Player p) { /* 由 Game 注入或查询 */ return 0; }
}

常规回合策略

public class NormalDeployStrategy implements DeployStrategy {
    @Override public int maxUnitsThisTurn(int t) { return 1; } // 每回合 1 个
    @Override
    public boolean canDeploy(Player p, Board b, Unit u, int x, int y, int t) {
        return u.getCost() <= p.getResource()
            && b.isEmpty(x, y)
            && b.inOwnHalf(0, x, y);
    }
}

游戏主循环

public class Game {
    private final Board board = new Board();
    private final Player[] players = new Player[2];
    private int turnNo = 1;
    private int currentPlayer = 0;
    private DeployStrategy strategy = new FirstTurnDeployStrategy();
    private final Map<Integer, Integer> deployedThisTurn = new HashMap<>();
    public void start() {
        // 先手判定:可随机 / 掷骰 / 固定
        currentPlayer = decideFirstPlayer();
        runTurn();
    }
    private void runTurn() {
        Player p = players[currentPlayer];
        deployedThisTurn.put(currentPlayer, 0);
        // ===== 部署阶段(首回合重点)=====
        deployPhase(p);
        // ===== 战斗阶段 =====
        battlePhase(p);
        // ===== 回合结束,切换 =====
        endTurn();
    }
    private void deployPhase(Player p) {
        int limit = strategy.maxUnitsThisTurn(turnNo);
        for (Unit u : new ArrayList<>(p.getHand())) {
            if (deployedThisTurn.get(currentPlayer) >= limit) break;
            // 这里可改为等待玩家输入坐标;示例自动选己方空格
            int[] pos = findFreeSlot(p);
            if (pos != null && strategy.canDeploy(p, board, u, pos[0], pos[1], turnNo)) {
                board.place(u, pos[0], pos[1]);
                p.getHand().remove(u);
                p.getField().add(u);
                p.setResource(p.getResource() - u.getCost());
                deployedThisTurn.merge(currentPlayer, 1, Integer::sum);
            }
        }
    }
    private void endTurn() {
        currentPlayer = 1 - currentPlayer;
        if (currentPlayer == 0) {
            turnNo++;
            strategy = new NormalDeployStrategy(); // 首回合后切换策略
        }
    }
}

首回合部署的关键规则(可按游戏自定义)

规则项 常见做法 代码位置
先手判定 随机/掷骰/固定玩家0 decideFirstPlayer()
首回合可上场数 1~2 个(比常规少) maxUnitsThisTurn(1)
初始资源 通常给较少费用,防止一波铺场 Player.resource 初始化
部署区域 仅己方半场 / 后排 2 行 Board.inOwnHalf()
是否可攻击 首回合通常只能部署,不能攻击 战斗阶段加 if (turnNo>1)
手牌抽牌 首回合可能少抽或不抽 抽牌阶段判断 turnNo==1

首回合"只部署不攻击"的写法

private void battlePhase(Player p) {
    if (turnNo == 1) {
        System.out.println("首回合仅部署,跳过战斗阶段");
        return;   // 关键:首回合无战斗
    }
    // 正常攻击逻辑...
}

可扩展点

  • 把策略注入 Game:Game.setStrategy(new FirstTurnDeployStrategy()),方便测试。
  • 部署校验链:把"资源、区域、数量、冷却"拆成多个 DeployRule,用责任链组合,首回合只需增删规则。
  • 回放/日志:记录首回合部署快照,便于复盘。

小结

首回合部署 = 独立的 DeployStrategy + 回合数判断 + 跳过战斗阶段 + 区域/资源/数量三重校验。

这样首回合的特殊性被封装在策略里,后续回合走常规逻辑,代码清晰、易扩展、易测试,需要我把它补成可运行的完整单文件 Demo(含 main 方法)吗?

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

友情链接攻略窝 · 礼包窝 · 配置窝 · 换算窝 · 算法窝 · 查文窝 · 手册窝 · 问答窝 · 全文搜 · 手册库
相关站点礼包窝 · 查文窝