Java骨牌游戏如何实现玩家与CPU轮流操作机制

来源:Nodejs社区作者:冷风头衔:草根站长
导读:本期聚焦于小伙伴创作的《Java骨牌游戏如何实现玩家与CPU轮流操作机制》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java骨牌游戏如何实现玩家与CPU轮流操作机制》有用,将其分享出去将是对创作者最好的鼓励。

在Java骨牌游戏开发中,玩家与CPU轮流操作机制的核心是通过状态管理明确当前操作主体,配合循环逻辑实现回合自动切换,同时保证操作合法性校验与流程可控性。

Java骨牌游戏如何实现玩家与CPU轮流操作机制

核心设计思路

首先需要定义游戏状态枚举,区分当前是玩家回合还是CPU回合,同时维护骨牌牌堆、玩家手牌、桌面骨牌序列等核心数据。回合切换时只需要修改状态枚举值,配合主循环判断当前操作主体即可。

状态枚举定义

通过枚举明确所有可能的游戏状态,避免硬编码字符串带来的维护问题:

// 定义游戏状态枚举
public enum GameState {
    PLAYER_TURN,  // 玩家回合
    CPU_TURN,     // CPU回合
    GAME_OVER     // 游戏结束
}

核心数据类设计

封装骨牌、玩家、游戏管理器三个核心类,分别管理单张骨牌信息、玩家手牌、整体游戏流程:

// 骨牌类,存储骨牌两端的数字
public class Domino {
    private int left;
    private int right;

    public Domino(int left, int right) {
        this.left = left;
        this.right = right;
    }

    // 判断骨牌是否能接在桌面序列的左侧
    public boolean canConnectLeft(int target) {
        return left == target || right == target;
    }

    // 判断骨牌是否能接在桌面序列的右侧
    public boolean canConnectRight(int target) {
        return left == target || right == target;
    }

    // 获取骨牌左侧数字
    public int getLeft() {
        return left;
    }

    // 获取骨牌右侧数字
    public int getRight() {
        return right;
    }
}

// 玩家类,管理玩家手牌
public class Player {
    private List<Domino> handCards;

    public Player() {
        handCards = new ArrayList<>();
    }

    // 添加手牌
    public void addCard(Domino domino) {
        handCards.add(domino);
    }

    // 移除指定手牌
    public boolean removeCard(Domino domino) {
        return handCards.remove(domino);
    }

    // 获取当前手牌
    public List<Domino> getHandCards() {
        return handCards;
    }
}

// 游戏管理器类,控制整体流程
public class DominoGameManager {
    private GameState currentState;
    private Player humanPlayer;
    private Player cpuPlayer;
    private List<Domino> desktopDominos;  // 桌面骨牌序列
    private List<Domino> dominoPool;      // 剩余骨牌池

    public DominoGameManager() {
        currentState = GameState.PLAYER_TURN;
        humanPlayer = new Player();
        cpuPlayer = new Player();
        desktopDominos = new ArrayList<>();
        dominoPool = new ArrayList<>();
        initDominoPool();
        dealCards();
    }

    // 初始化骨牌池,生成所有0-6的骨牌组合
    private void initDominoPool() {
        for (int i = 0; i <= 6; i++) {
            for (int j = i; j <= 6; j++) {
                dominoPool.add(new Domino(i, j));
            }
        }
        // 打乱骨牌顺序
        Collections.shuffle(dominoPool);
    }

    // 发牌,玩家和CPU各拿7张
    private void dealCards() {
        for (int i = 0; i < 7; i++) {
            humanPlayer.addCard(dominoPool.remove(0));
            cpuPlayer.addCard(dominoPool.remove(0));
        }
        // 第一张骨牌放到桌面
        desktopDominos.add(dominoPool.remove(0));
    }
}

玩家回合实现逻辑

玩家回合需要等待用户输入操作,校验操作合法性后更新桌面骨牌序列,再切换到CPU回合。这里通过控制台输入模拟玩家操作,实际GUI开发可替换为事件监听逻辑。

// 游戏管理器中添加玩家回合处理方法
public void handlePlayerTurn() {
    if (currentState != GameState.PLAYER_TURN) {
        return;
    }
    System.out.println("当前是你的回合,你的手牌为:");
    List<Domino> playerCards = humanPlayer.getHandCards();
    for (int i = 0; i < playerCards.size(); i++) {
        Domino d = playerCards.get(i);
        System.out.println(i + ": [" + d.getLeft() + "|" + d.getRight() + "]");
    }
    System.out.println("请输入要出的骨牌序号,以及要接在左侧(l)还是右侧(r),格式如 0 l:");
    Scanner scanner = new Scanner(System.in);
    String input = scanner.nextLine();
    String[] parts = input.split(" ");
    if (parts.length != 2) {
        System.out.println("输入格式错误,请重新输入");
        return;
    }
    int cardIndex = Integer.parseInt(parts[0]);
    String position = parts[1];
    if (cardIndex < 0 || cardIndex >= playerCards.size()) {
        System.out.println("骨牌序号错误,请重新输入");
        return;
    }
    Domino selectedDomino = playerCards.get(cardIndex);
    // 校验是否能接在指定位置
    boolean isValid = false;
    if ("l".equals(position)) {
        int leftTarget = desktopDominos.get(0).getLeft();
        isValid = selectedDomino.canConnectLeft(leftTarget);
        if (isValid) {
            // 调整骨牌方向后添加到左侧
            if (selectedDomino.getRight() == leftTarget) {
                desktopDominos.add(0, selectedDomino);
            } else {
                desktopDominos.add(0, new Domino(selectedDomino.getRight(), selectedDomino.getLeft()));
            }
            humanPlayer.removeCard(selectedDomino);
        }
    } else if ("r".equals(position)) {
        int rightTarget = desktopDominos.get(desktopDominos.size() - 1).getRight();
        isValid = selectedDomino.canConnectRight(rightTarget);
        if (isValid) {
            // 调整骨牌方向后添加到右侧
            if (selectedDomino.getLeft() == rightTarget) {
                desktopDominos.add(selectedDomino);
            } else {
                desktopDominos.add(new Domino(selectedDomino.getRight(), selectedDomino.getLeft()));
            }
            humanPlayer.removeCard(selectedDomino);
        }
    }
    if (!isValid) {
        System.out.println("该骨牌无法接在指定位置,请重新选择");
        return;
    }
    // 检查玩家是否出完手牌,出完则游戏结束
    if (humanPlayer.getHandCards().isEmpty()) {
        currentState = GameState.GAME_OVER;
        System.out.println("恭喜你,你赢了!");
        return;
    }
    // 切换到CPU回合
    currentState = GameState.CPU_TURN;
}

CPU回合实现逻辑

CPU回合需要实现自动决策逻辑,优先遍历手牌找到可出的骨牌,没有可出骨牌时从骨牌池抽牌,抽牌后仍无法出牌则跳过回合,最后切换到玩家回合。

// 游戏管理器中添加CPU回合处理方法
public void handleCPUTurn() {
    if (currentState != GameState.CPU_TURN) {
        return;
    }
    System.out.println("CPU的回合,正在思考...");
    List<Domino> cpuCards = cpuPlayer.getHandCards();
    Domino selectedDomino = null;
    String position = null;
    int leftTarget = desktopDominos.get(0).getLeft();
    int rightTarget = desktopDominos.get(desktopDominos.size() - 1).getRight();
    // 遍历CPU手牌,找可出的骨牌
    for (Domino d : cpuCards) {
        if (d.canConnectLeft(leftTarget)) {
            selectedDomino = d;
            position = "l";
            break;
        }
        if (d.canConnectRight(rightTarget)) {
            selectedDomino = d;
            position = "r";
            break;
        }
    }
    // 没有可出的骨牌,从池里抽牌
    if (selectedDomino == null) {
        if (!dominoPool.isEmpty()) {
            Domino drawDomino = dominoPool.remove(0);
            cpuPlayer.addCard(drawDomino);
            System.out.println("CPU从牌池抽了一张牌");
            // 抽牌后再次检查是否能出
            if (drawDomino.canConnectLeft(leftTarget)) {
                selectedDomino = drawDomino;
                position = "l";
            } else if (drawDomino.canConnectRight(rightTarget)) {
                selectedDomino = drawDomino;
                position = "r";
            }
        }
    }
    // 仍然无法出牌,跳过回合
    if (selectedDomino == null) {
        System.out.println("CPU无法出牌,跳过回合");
        currentState = GameState.PLAYER_TURN;
        return;
    }
    // 执行出牌操作
    if ("l".equals(position)) {
        if (selectedDomino.getRight() == leftTarget) {
            desktopDominos.add(0, selectedDomino);
        } else {
            desktopDominos.add(0, new Domino(selectedDomino.getRight(), selectedDomino.getLeft()));
        }
        cpuPlayer.removeCard(selectedDomino);
        System.out.println("CPU出了骨牌 [" + selectedDomino.getLeft() + "|" + selectedDomino.getRight() + "] 接在左侧");
    } else {
        if (selectedDomino.getLeft() == rightTarget) {
            desktopDominos.add(selectedDomino);
        } else {
            desktopDominos.add(new Domino(selectedDomino.getRight(), selectedDomino.getLeft()));
        }
        cpuPlayer.removeCard(selectedDomino);
        System.out.println("CPU出了骨牌 [" + selectedDomino.getLeft() + "|" + selectedDomino.getRight() + "] 接在右侧");
    }
    // 检查CPU是否出完手牌
    if (cpuPlayer.getHandCards().isEmpty()) {
        currentState = GameState.GAME_OVER;
        System.out.println("CPU出完了所有手牌,你输了!");
        return;
    }
    // 切换到玩家回合
    currentState = GameState.PLAYER_TURN;
}

主循环整合

最后通过主循环驱动整个游戏流程,根据当前状态调用对应的回合处理方法,直到游戏结束。

// 游戏管理器添加启动方法
public void startGame() {
    while (currentState != GameState.GAME_OVER) {
        switch (currentState) {
            case PLAYER_TURN:
                handlePlayerTurn();
                break;
            case CPU_TURN:
                handleCPUTurn();
                break;
        }
    }
}

// 主函数入口
public static void main(String[] args) {
    DominoGameManager gameManager = new DominoGameManager();
    gameManager.startGame();
}

注意事项

  • 操作合法性校验需要覆盖所有边界情况,比如骨牌池为空时无法抽牌、输入序号越界等,避免程序异常崩溃。
  • CPU决策逻辑可以根据需求优化,比如优先出数字大的骨牌、优先接右侧等,提升游戏趣味性。
  • 如果是GUI版本开发,需要将控制台输入替换为按钮点击、拖拽等事件监听,回合切换时更新界面显示即可,核心状态逻辑不需要修改。

Java骨牌游戏轮流机制CPU逻辑修改时间:2026-06-19 08:18:40

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。