【问题标题】:Tic-Tac-Toe Print the Path of Best Move in Game Tree Search?井字游戏在游戏树搜索中打印最佳移动路径?
【发布时间】:2016-05-27 09:19:12
【问题描述】:

我正在研究带有井字游戏 (3x3) 的 alpha-beta 修剪算法。目前对于 3x3 网格的任何给定实例,我都能够找出最佳情况:

public Best chooseAlphaBetaMove(int whosMov, int alpha, int beta) {

    Best reply = new Best();  
    Best myBest = new Best();

    if ((scoreGrid()==COMPUTER_WIN) || (scoreGrid()==OPPONENT_WIN) || 
                                       (scoreGrid()==GAME_DRAW)) {
        int score = scoreGrid();
        return new Best(score,-3,-3,count);
    }

    if (whosMov==COMPUTER_MOVE) {
        myBest.score = alpha;
    } else {
        myBest.score = beta;
    }

    for (int i=0; i<3; i++) {
    for (int j=0; j<3; j++) {
        if (layOut[i][j]==0) {
            moveGrid(whosMov,i,j);
            reply = chooseAlphaBetaMove(-whosMov,alpha,beta); 
            unmoveGrid(i,j);

            if ((whosMov==COMPUTER_MOVE)&&(reply.score>myBest.score)) {
                myBest.score = reply.score;
                alpha = reply.score;
                myBest.row = i;
                myBest.column = j;
            }

            if  ((whosMov==OPPONENT_MOVE)&&(reply.score<myBest.score)) {
                myBest.score = reply.score;
                beta = reply.score;
                myBest.row = i;
                myBest.column = j;
            }
            if (beta <= alpha) return myBest;
        }
    }
    }

        return myBest;
}

最佳结构在哪里:

public class Best {

    public int score;
    public int row;
    public int column;
    public int count
}

给定一个初始网格以及下一个将移动的人,我可以知道下一个玩家的最佳得分和最佳位置。但是,我不知道如何为这个最佳动作打印整个路径。 (注意 - 我不想要整个搜索路径。我只想打印从这个最佳移动到叶子的单个搜索路径)。有什么想法吗?谢谢!

【问题讨论】:

    标签: java tic-tac-toe


    【解决方案1】:

    当您递归地沿着每条路径前进时,您需要跟踪它,可能通过将对 List/Stack 的引用传递给每个 chooseAlphaBetaMove 调用。当您找到比当前最佳路径更好的路径时,您获取当前路径的副本,并将其存储为“迄今为止的最佳路径”。完成后,您可以打印出最佳路径。

    【讨论】:

    • 谢谢。也许我可以为每个 myBest 对象保留一个移动列表(i,j)?然后当我得到最好的 myBest 时,我可以回去打印出这个 myBest 的所有 (i,j)?我会试一试的。
    【解决方案2】:

    http://xkcd.com/832/ 是一种可视化 TTT 树的有效方法

    【讨论】:

    • 谢谢 - 但这看起来比我打算尝试的要复杂得多。
    【解决方案3】:

    您需要一些方法来跟踪搜索中的最佳移动。我的建议是保留一个包含最佳移动列表的数据结构。 Stack 似乎是最适合这种情况的数据结构。在每次递归调用中,将第一个动作压入堆栈(因为这是迄今为止最好的动作)。当找到更好的移动时,弹出堆栈并推送新的。在您的 alpha-beta 修剪算法完成后,只需弹出堆栈并打印每个动作。这将给出游戏结束时的“最佳”动作顺序。

    【讨论】:

    • 这听起来很对 - 但我找不到在每个级别识别 myBest 的好方法。如果我选择每次获得新的 myBest 时都将 myBest 添加到堆栈中,那么这将太多了......在每个级别中可能有多个 myBest,就像我们从分数 -1 开始,然后找到分数 0(首先myBest),然后找到 1(第二个 myBest)...
    • @user1660652 当前的“最佳”应该在堆栈的顶部。如果您找到更好的“最佳”,则在推送新的堆栈之前弹出堆栈。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-08
    相关资源
    最近更新 更多