使用minmax算法的Java tictactoe问题

时间:2018-03-04 16:42:19

标签: java algorithm minmax

我想为tictactoe实现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;
}

最好的问候

编辑:

感谢您的回答。至于第一点,我忘了改变&#39; *&#39;到&#39; - &#39;这是我的评估方法:

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 个答案:

答案 0 :(得分:0)

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

  1. 您正在使用&#39; - &#39;初始化比赛场地的空方格,但在最小/最大功能中,您认为&#39; *&#39;是一个空方
  2. 在min-function中,与max-function相反,你在每个级别设置最佳移动而不是顶级,所以更深层次将覆盖顶层的最佳结果(所以我认为你也应该检查深度==深度)
  3. 我不知道你在主要做什么,但也应该减少&#34;深度&#34;在每次移动之后,因为这定义了顶级(以及因此应该分配最佳移动的级别),并且根据您的问题,您减少了&#34;深度&#34;每次通话期间的争论
  4. 我猜你知道如果你递归直到游戏结束(这是在每次移动后递减深度和深度的另一个参数),你将只获得最佳结果。
  5. 您没有检查evaluateMove函数中的对角线
  6. 在evaluateMove的第二个双循环中,检查最里面循环内的countX,countY的条件(有效,但令人恼火的是,它与第一个双循环不同=&gt;不太适合查找错误)
  7. 编辑,最后(鼓声......):

    1. 在第一步中,您最大化增益(对于计算机移动(&#39; X&#39;))但您实际上是在执行玩家移动(&#39; O&#39; )。对于第二次移动反之亦然。但是,您必须最小化第一步中的增益(这意味着玩家获胜)并在第二步中最大化。
    2. 也就是说,你实际做了什么:

          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--;
          }