我如何从 TicTacToe 中的 Min Max 中提取出我的最佳动作?

发布于 2025-01-04 12:42:22 字数 987 浏览 5 评论 0原文

        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() - 如果赢/输/平局则返回 true,否则

返回 game.Score(turn) - 返回 -1/ 0/1,如果玩家的下一步行动是输/平/赢

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

game.Do_Move() - 将移动应用到游戏中的无效

game.Undo_Move() - 不言自明

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

The thing is that this little function tells me if the game is a win, a lose or a draw, but how can i get the move that will led me to a win? My Point class is a simple Class With 2 coordinates X, Y and i want to get the answer as a point so i can latter say something like game.Do_Move(myPoint).

In case some functions aren't obvious:

game.IsFinished() - returns true if win/lose/draw else otherwise

game.Score(turn) - returns -1/0/1 in case is a lose/draw/win for the player with the next move

game.Generate_Moves() - returns a List with available moves

game.Do_Move() - void that applies the move to game

game.Undo_Move() - talks for itself

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

℡寂寞咖啡 2025-01-11 12:42:22

如果在游戏树的根节点上调用的 minimax 函数返回选择的移动和分数就足够了。对于游戏树的所有其他节点,该函数只需要返回分数。因此,通常的方法是实现两个略有不同的极小极大函数 - 查看注释#2对此 NegaMax 框架的描述
应用于您的 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

It would be enough if the minimax function which gets called on the root node of the game tree returns both, the choosen move and the score. For all other nodes of the game tree, the function needs only to return the score. Thus the usual way is to implement two slightly different minimax functions – Look at Note #2 in the description to this NegaMax Framework.
Applied to your minimax interface you would have following additional function:

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

Note that I have removed the call to Undo_Move as it is not needed because you make a copy of game in each iteration.

╰◇生如夏花灿烂 2025-01-11 12:42:22

您需要应用 极小极大定理。

您基本上必须制作一个博弈树,其中的每个节点这棵树是一个棋盘位置,每个孩子都是合法移动的结果。叶子节点(游戏结束的地方)将根据 game.score() 获得分数,一个玩家试图沿着通向高分的路径选择移动,而另一个玩家则尝试选择迫使低分的移动分数。该定理将帮助您了解如何严格应用该想法。

You need to apply the minimax theorem.

You basically have to make a game tree, where each node in the tree is a board position, and each child is the result of a legal move. The leaf nodes (where the game is ended) will have scores according to game.score(), and one player is trying to pick moves down a path leading to a high score, while the other is trying to pick moves that force a low score. The theorem will help you see how to apply that idea, rigorously.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文