繁体   English   中英

minmax算法的Java tictactoe问题

[英]Java tictactoe problems with minmax algorithm

我想为针脚实现MinMax算法。 我有两种方法min()和max()以及一种评估方法,但它不起作用。 例如当我打电话

max(9);
Field[bestCol][bestRow]='O';
min(8);
Field[bestCol][bestRow]='X';     

在主要功能中,结果是

OX-                                  
---
---

但是,玩家“ X”的最佳举动是将“ X”放在中间。

这是我的没有评估方法的代码:

static char[][] Field = { { '-', '-', '-' },
                          { '-', '-', '-' },
                          { '-', '-', '-' } };

static char Player = 'O';
static char Computer = 'X';

static int Depth =9; // searchdepth
static int bestRow=0, bestCol=0; // best Move

public static int max(int depth) {
    if (depth == 0) {
        return evaluateMove();
    }

    int maxValue = Integer.MIN_VALUE;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (Field[i][j] == '-') {
                Field[i][j] = Computer;

                int value = min(depth - 1);
                Field[i][j] ='-';

                if (value > maxValue) {
                    maxValue = value;
                    if (depth == Depth) {
                        bestCol=i;
                        bestRow=j;
                    }
                }
            }
        }
    }
    return maxValue;
}

public static int min(int depth) {
    int minValue = Integer.MAX_VALUE;

    if (depth == 0) {
        return evaluateMove();
    }
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (Field[i][j] == '-') {
                Field[i][j] = Player;
                int value = max(depth - 1);
                Field[i][j] = '-';

                if (value < minValue) {
                    minValue = value;
                    bestCol=i;
                    bestRow=j;
                }
            }
        }
    }
    return minValue;
}

最好的祝福

编辑:

感谢您的回答。 首先,我忘记将“ *”更改为“-”,这是我的评估方法:

public static int evaluateMove() {
    for(int i=0; i<3; i++) {
        int countX=0; int countY=0;
        for(int j=0; j<3; j++) {
            if(Feld[i][j]==Computer) countX++;
            if(Feld[i][j]==Player) countY++;
        }
        if(countX==3) return 10;
        if(countY==3) return -10;
    }

    for(int j=0; j<3; j++) { // Spalten
        int countX=0; int countY=0;
        for(int i=0; i<3; i++) {
            if(Feld[i][j]==Computer) countX++;
            if(Feld[i][j]==Player) countY++;
            if(countX==3) return 10;
            if(countY==3) return -10;
        }
    }
    return 0; // Unentschieden
}

一些让我印象深刻的事情:

  1. 您使用'-'初始化了比赛场地的空白方块,但是在最小/最大值函数中,您假设'*'是空白方块
  2. 在最小功能中,与最大功能相反,您在每个级别而不是顶层都设置了最佳移动,因此较深的级别将覆盖顶层的最佳结果(因此,我认为您还应该检查深度==深度)
  3. 我不知道您主要做什么,但每次移动后也应减小“深度”,因为这定义了最高级别(因此也应指定最佳移动的级别),并根据您的问题减小每次通话中的“深度”参数
  4. 我想你知道,只有当你递归直到游戏结束时,你才会获得最佳的结果(这是每次移动之后深度和深度递减的另一个参数)
  5. 您没有在评估移动功能中检查对角线
  6. 在valuateMove的第二个双循环中,检查最内层循环中countX,countY的条件(可以,但是令人讨厌的是,它与第一个双循环不同,=>不太适合发现错误)

编辑:最后(鼓卷...):

  1. 在第一个动作中,您使增益最大化 (对于计算机动作(“ X”)),但实际上执行了Player动作(“ O”)。 反之亦然。 但是,您必须在第一步中最小化收益(这意味着玩家获胜),而在第二步中最大化。

也就是说,您实际执行的操作:

    public static void ComputeAndExecuteBestMove()
    {
        // since Player begins, we minimize the gain value for the first move
        if ((MaxDepth-Depth) % 2 == 0) 
        {
            max(Depth);
            Field[bestCol,bestRow] = Player;
        }
        else 
        {
            min(Depth);
            Field[bestCol,bestRow] = Computer;
        }

        // next move
        Depth--;
    }

但是您应该做什么:

    public static void ComputeAndExecuteBestMove()
    {
        // since Player begins, we minimize the gain value for the first move
        if ((MaxDepth-Depth) % 2 == 0) 
        {
            min(Depth);
            Field[bestCol,bestRow] = Player;
        }
        else 
        {
            max(Depth);
            Field[bestCol,bestRow] = Computer;
        }

        // next move
        Depth--;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM