You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX井字棋:MinMax算法作为先手时无法主动落子

井字棋AI先手无法主动落子的Bug修复

我的MinMax算法在其他场景测试都能用,但用JavaFX做的井字棋里,当电脑(player2,用MinMax算法)当先手时,它不会主动落子,必须等用户点击一下,游戏才能正常推进;如果用户以player1身份先手就完全没问题,明显是代码有Bug。相关代码如下:

pane.setOnMouseClicked(event -> {
    if (currentPlayer.equals(player1)) {
        if (label.getText().isEmpty() && !isEndOfGame) {
            label.setText(currentPlayer.getSymbol());
            changePlayerTurn();
            verifyResultOfTheDuel();

            if (mode.equals(SINGLE_PLAYER) && !isEndOfGame && currentPlayer.equals(player2)) {
                makeComputerMove(difficulty);
                changePlayerTurn();
                verifyResultOfTheDuel();
            }
        }
    } else if (currentPlayer.equals(player2)) {
        if (label.getText().isEmpty() && !isEndOfGame) {
            if (mode.equals(SINGLE_PLAYER)) {
                makeComputerMove(difficulty);
                changePlayerTurn();
                verifyResultOfTheDuel();
            } else if (mode.equals(MULTI_PLAYER)) {
                label.setText(currentPlayer.getSymbol());
                changePlayerTurn();
                verifyResultOfTheDuel();
            }
        }
    }
});

问题根源

电脑先手的逻辑完全被绑在了鼠标点击事件上,但游戏刚启动时没人会触发点击,所以电脑永远不会执行makeComputerMove。只有用户点击后,才会进入事件处理,但此时当前玩家是player2的话,用户点击的格子逻辑也不对,等于卡死在初始状态。

修复方案

  1. 初始化时主动触发电脑落子:在游戏加载完成、初始化逻辑结束后,判断如果是单人模式且当前玩家是电脑(player2),直接调用电脑落子的方法。
  2. 简化点击事件逻辑:点击事件只处理玩家1的操作,电脑的回合不需要依赖用户点击,玩家走完后自动触发电脑落子。

修改后的代码

首先在游戏初始化的地方(比如start()方法末尾,或者场景加载完成的回调里)加这段代码:

// 游戏初始化后检查是否电脑先手,是的话直接落子
if (mode.equals(SINGLE_PLAYER) && currentPlayer.equals(player2) && !isEndOfGame) {
    makeComputerMove(difficulty);
    changePlayerTurn();
    verifyResultOfTheDuel();
}

然后把原点击事件代码改成这样:

pane.setOnMouseClicked(event -> {
    // 只处理玩家1的点击操作,确保游戏未结束且当前格子为空
    if (currentPlayer.equals(player1) && label.getText().isEmpty() && !isEndOfGame) {
        label.setText(currentPlayer.getSymbol());
        changePlayerTurn();
        verifyResultOfTheDuel();

        // 玩家走完后,轮到电脑就自动触发落子
        if (mode.equals(SINGLE_PLAYER) && !isEndOfGame && currentPlayer.equals(player2)) {
            makeComputerMove(difficulty);
            changePlayerTurn();
            verifyResultOfTheDuel();
        }
    }
});

说明

删掉了原代码里针对player2的点击分支,因为电脑不需要点击操作。初始化时主动触发电脑落子,解决了先手时的无响应问题;玩家点击后自动触发电脑回合,保持原有正常流程。

内容的提问来源于stack exchange,提问作者reizorwins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 18:32:57