Tic_Tac_Toe_against the computer反对当使用4 * 4板翻转计算机时,使用MiniMax算法时,它的游戏性能是否不佳?

时间:2019-12-26 07:22:11

标签: java algorithm

我正在用Java针对AI电脑玩家构建tic_tac_toe(棋盘)游戏,我为电脑编写了MiniMax算法。 木板的宽度可以像 3 * 3 4 * 4。

  

当我在 3 * 3 上运行游戏时,计算机播放器将开始工作   很好,但是当我尝试 4 * 4板子时,计算机播放器没有   工作只需要花费很多时间,然后什么都没有   等到我停止游戏。   这是发生的屏幕截图。   enter image description here

这是我编写的MiniMax算法:

private Pair<Integer, State> maxMove(State b) {
        if(b.isWin('X') || b.isFinished())
            return new Pair<>(b.eval('X'), b);
        else{
            int max = -222, temp;
            Pair<Integer, State> p = null;
            for (State s : b.allNextMoves('O')){
                temp = minMove(s).getKey();
                if (temp > max){
                    max = temp;
                    p = new Pair<>(s.eval('X'), s);
                }
            }
            return p;
        }
    } 


private Pair<Integer, State> minMove(State b) {
        if(b.isWin('O') || b.isFinished())
            return new Pair<>(b.eval('O'), b);
        else{
            int min = 222, temp;
            Pair<Integer, State> p = null;
            for (State s : b.allNextMoves('X')){
                temp = maxMove(s).getKey();
                if (temp < min){
                    min = temp;
                    p = new Pair<>(s.eval('O'), s);
                }
            }
            return p;
        }
    }

eval函数用于评估网格,我只是将其作为样本,这是func:

 public int eval(char player) {
  if (isWin(player))
            return -1;
        else
            return 0;
    }

有人知道为什么会这样吗?

编辑

allNextMoves(char c)函数将拿起这个棋盘,并尝试通过找到棋盘中的第一个空字符并根据玩家的回合放置“ X”或“ O”来查找该棋盘的所有可能动作,并返回新板列表,这是代码。

public List<State> allNextMoves(char player) {
        List<State> nextBoards = new LinkedList<>();
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < width; j++) {
                if (board[i][j] == ' ') {
                    State nextBoard = new State(this);
                    nextBoard.play(i, j, player);
                    nextBoards.add(nextBoard);
                }
            }
        }
        return nextBoards;
    }

1 个答案:

答案 0 :(得分:3)

minimax算法不响应的原因是,使用4x4网格时,要访问的板数要大得多。

首先,我看到您的算法将继续搜索,直到赢得或平局,这意味着很多搜索路径将完全填满整个棋盘。第一步后,左转15圈,每转分别有15、14、13 ... 1个可供选择的替代动作。所以有接近15个!董事会要访问的国家。少了一点,因为会发现(非强制)获胜,但是仍然是15!是对大小的一个很好的粗略估计。

在一个3x3的板上,这个数字只有8个!

比较两个数字:

 8! =            40 230  
15! = 1 307 674 368 000

因此,在4x4面板中进行搜索所需的时间比在3x3面板中进行搜索的时间长3000万倍。

如何解决?

可以采取多种措施,并且可以将它们组合在一起。这不是完整的列表,而是按此顺序列出的我将要处理的事情的列表:

1。限制搜索深度

当搜索深度太大时,您需要停止搜索。有几种方法可以决定何时停止:

  • 以固定的预定义搜索深度
  • 达到最小的固定搜索深度时,,并且当当前状态为“安静”时,即没有直接的获胜威胁。

评估功能

当您限制搜索时,您需要一个评估函数,该函数将给出状态值而无需进行更深入的搜索。这将是一些启发式的价值。例如,它可以计算玩家仍然可以赢得的线数(如果对手不能很好地打),并从对手的角度将其抵消为相同的数字。

2。使用查找表

可以通过不同的移动路径来达到相同的板状态。例如,如果两个玩家将第一步和第二步交换,您将进入相同的棋盘状态。

此外,几个状态通过沿X,Y或对角线轴进行镜像而彼此映射。

通过维护以前评估状态的哈希表(该哈希表还管理镜像方面),可以避免进行本质上是重复的搜索。

3。 Alpha Beta修剪

由alpha-beta算法完成的修剪不会影响结果。其结果与minimax算法相同。

4。首先执行最佳动作

在极端情况下,当前的局面可能距离获胜者只有一步之遥,但是如果考虑到最后一步,则浪费大量时间寻找其他步伐。因此,如果您可以按照先完成最有前途的举动的方式对这些举动进行排序,则可以节省时间:alpha beta修剪将更加有效。

您可以根据移动是否在被“很多”对手棋子占据的线上进行排名,或者在没有区别的情况下,首先处理中心和角点移动,因为它们可以提供比边界移动更多的解决方案

5。杀手的动作

如果经过一定举动后您发现回复是挽救生命,或是迈向强制胜利的关键一步,那么当替代初始举动而不是最初举动时,首先尝试相同的回复可能会有所回报玩过。