极小极大与TictoeJava

极小极大与TictoeJava,java,Java,我试图用minimax算法创建一个AI tictactoe对手,问题是,AI只是将O放置在下一个自由空间,而不是一个实际的好位置。我哪里出了问题 public static double minimax(String[][] arr, int depth, boolean isMaximizing) { Map<String, Integer> map = new HashMap<>(); map.put("X", 1); ma

我试图用minimax算法创建一个AI tictactoe对手,问题是,AI只是将O放置在下一个自由空间,而不是一个实际的好位置。我哪里出了问题

public static double minimax(String[][] arr, int depth, boolean isMaximizing) {
    Map<String, Integer> map = new HashMap<>();
    map.put("X", 1);
    map.put("O", -1);
    map.put("Draw", 0);
    double bestScore = Double.NEGATIVE_INFINITY;

    String result = evaluateWinner(arr);
    if (!result.equals(" ")) {
        return map.get(result);
    }
    if (isMaximizing) {

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (arr[i][j].equals(" ")) {
                    arr[i][j] = "X";
                    double score = minimax(arr, depth + 1, false);
                    arr[i][j] = " ";
                    bestScore = Math.max(bestScore, score);
                }
            }
        }
    } else {
        bestScore = Double.POSITIVE_INFINITY;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (arr[i][j].equals(" ")) {
                    arr[i][j] = "0";
                    double score = minimax(arr, depth + 1, true);
                    arr[i][j] = " ";
                    bestScore = Math.min(score, bestScore);
                }
            }

        }
    }
    return bestScore;
}
publicstaticdoubleminimax(字符串[][]arr,int-depth,布尔值最大化){
Map Map=newhashmap();
地图放置(“X”,1);
地图放置(“O”,-1);
地图放置(“绘制”,0);
双倍最佳分数=双倍负_∞;
字符串结果=evaluateWinner(arr);
如果(!result.equals(“”){
返回map.get(结果);
}
if(最大化){
对于(int i=0;i<3;i++){
对于(int j=0;j<3;j++){
if(arr[i][j].等于(“”){
arr[i][j]=“X”;
双倍分数=最小最大值(arr,深度+1,错误);
arr[i][j]=“”;
bestScore=Math.max(bestScore,score);
}
}
}
}否则{
bestScore=双正无穷大;
对于(int i=0;i<3;i++){
对于(int j=0;j<3;j++){
if(arr[i][j].等于(“”){
arr[i][j]=“0”;
双倍分数=最小最大值(arr,深度+1,真);
arr[i][j]=“”;
bestScore=Math.min(分数,bestScore);
}
}
}
}
返回最佳分数;
}
主方法中的代码是:

double bestScore = Double.POSITIVE_INFINITY;
                        for (int i = 0; i < 3; i++) {
                            for (int j = 0; j < 3; j++) {
                                if (arr[i][j].equals(" ")) {
                                    arr[i][j] = "O";
                                    double score = minimax(arr, 0, false);
                                    arr[i][j] = " ";
                                    if (score < bestScore) {
                                        bestScore = score;
                                        iCoordinate = i;
                                        jCoordinate = j;
                                    }
                                }
                            }
                        }
                        arr[iCoordinate][jCoordinate] = "O";
double bestScore=double.POSITIVE_∞;
对于(int i=0;i<3;i++){
对于(int j=0;j<3;j++){
if(arr[i][j].等于(“”){
arr[i][j]=“O”;
双倍分数=最小最大值(arr,0,假);
arr[i][j]=“”;
如果(分数<最佳分数){
最佳分数=分数;
i坐标=i;
jCoordinate=j;
}
}
}
}
arr[iCoordinate][jCoordinate]=“O”;

1-我强烈建议对状态和/或单元格数据使用
eunm
(或最小常数)-字符串有点危险:
arr[I][j]=“0”可能是
…=“O”
(不确定,因为我看不到evaluateWinner中的内容)

2-在main中,首先设置一个
“O”
并传递
isMaximizing:false

但在
minimax
中,如果
isMaximizing==false
则设置另一个
“0”
(或
“O”
,请参见上一点)
似乎对
isMaximizing

3-检查Henry的-大多数IDE都有很好的调试器,这是检查程序运行情况的最佳方法

4-正如我所记得的,如果从一个空的场地开始(假设对手没有错误-minimax假设的情况),就没有获胜的动作,因此我怀疑如果从一个空的棋盘开始,算法会选择第一个位置
在第一个位置设置一个“X”,并检查发生了什么

“唯一成功的做法是不玩”(

尝试使用调试器执行程序,以查看程序偏离预期的地方。很抱歉没有提及它,我尝试了,它在极大极小值和评估赢家之间无限循环(如果我将断点放在极大极小值()的开头)(或者至少我连续按F8键2分钟,它不断旋转并改变深度(2,3,2,5,4,3,2),诸如此类。但是,如果我不在方法中设置断点,而在主方法中仅保留一个断点,则minimax方法会不时返回一些内容,但结果与前面描述的相同。谢谢!抱歉没有提及它,我尝试了,它会在minimax和evaluate winner之间无限循环(如果我将断点放在minimax()的开始处(或者至少我连续按F8键2分钟,它继续旋转并改变深度(2,3,2,5,4,3,2),诸如此类。但是,如果我不在方法中设置断点,而在主方法中只保留一个断点,则minimax方法会不时返回一些内容,但结果与前面描述的相同。至于其他步骤,我将立即尝试更正,非常感谢!成功了,你太棒了!干杯!啊,我现在看到了,幸运的是我这主要是打字错误造成的