我怎样才能从TicTacToe的Min Max中获取最佳动作?

时间:2012-02-10 13:38:31

标签: artificial-intelligence tic-tac-toe minmax

        int minmax(Board game, int depth)
        {
            if (game.IsFinished() || depth < 0)
                return game.Score(game.Turn);

            int alpha = int.MinValue + 1;
            foreach (Point move in game.Generate_Moves())
            {
                Board currentBoard = game;
                currentBoard.Do_Move(move); 

                alpha = max(alpha, -minmax(currentBoard, depth-1));
                currentBoard.Undo_Move(move);
            }

            return alpha;
        }

问题在于,这个小功能告诉我游戏是赢,输还是平局,但我怎么能得到让我获胜的举动呢?我的Point类是一个简单的类,有2个坐标X,Y,我希望得到答案作为一个点,所以后来我可以说game.Do_Move(myPoint)之类的东西。

如果某些功能不明显:

game.IsFinished() - 如果输赢/输/否则返回

game.Score(turn) - 如果是下次移动的玩家失败/平局/获胜,则返回-1/0/1

game.Generate_Moves() - 返回包含可用移动的列表

game.Do_Move() - 适用于游戏移动的空白

game.Undo_Move() - 为自己说话

2 个答案:

答案 0 :(得分:0)

您需要应用minimax theorem.

你基本上必须制作一个游戏树,其中树中的每个节点都是一个棋盘位置,每个孩子都是合法移动的结果。叶子节点(游戏结束的地方)将根据game.score()得分,并且一个玩家试图选择向下移动导致高分的路径,而另一个玩家试图选择强制低的移动得分了。该定理将帮助您了解如何严格应用该想法。

答案 1 :(得分:0)

如果在游戏树的根节点上调用的minimax函数同时返回选择的移动和分数就足够了。对于游戏树的所有其他节点,该功能仅需要返回分数。因此,通常的方法是实现两个稍微不同的极小极大函数 - Look at Note #2 in the description to this NegaMax Framework 应用于您的minimax界面,您将拥有以下附加功能:

int minimaxWithMove(Board game, int depth, Point& choosen)
{
    assert (!game.IsFinished() && depth > 0); // not possible at root node
    int alpha = int.MinValue + 1;
    foreach (Point move in game.Generate_Moves())
    {
        Board currentBoard = game;
        currentBoard.Do_Move(move);
        int score = -minmax(currentBoard, depth-1);
        if (score > alpha)
        {
            alpha = score;
            choosen = move;
        }
    }
    return alpha;
}

请注意,我已删除了对Undo_Move的调用,因为您在每次迭代中都会复制game