简体   繁体   English

为什么 minimax 不选择井字游戏中的最佳位置?

[英]Why doesn't minimax pick the best position in Tic Tac Toe?

I've made a Minimax algorithm to determine the best position in Tic Tac Toe.我制作了一个 Minimax 算法来确定井字游戏中的最佳位置。 I want it to play for both 'x' and 'o'.我希望它同时播放“x”和“o”。 For the most part, it works great;在大多数情况下,它工作得很好。 it's unbeatable.这是无与伦比的。 But as we all know, when starting the game, the strongest position to hold is the middle of the board.但众所周知,在开始游戏时,最稳固的位置是棋盘中间。 For some reason, my AI seems to go to the top left consistently (when it plays 'x' and has the first go)...出于某种原因,我的 AI 似乎一直在左上角(当它播放“x”并先走时)......

Now to be clear: this isn't a bug, I just want some clarification as to why it does this.现在要明确一点:这不是一个错误,我只是想澄清一下它为什么这样做。 Does it see no difference between top left and middle?左上和中之间没有区别吗? or is there a bug somewhere in my code?还是我的代码中某处有错误?

minimax(char board[9], bool is_maximizing, char computer)

int minimax(char board[9], bool is_maximizing, char computer)
{
    char winner = check_winner(board);
    int free_spaces = check_free_spaces(board);
    char player = computer == 'x' ? 'o' : 'x';

    if (free_spaces <= 1)
        return 0;
    else if (winner == computer)
        return 1;
    else if (winner == player)
        return -1;

    if (is_maximizing)
    {
        int best_score = INT_MIN;

        for (int i = 0; i < 9; i++)
        {
            if (board[i] == ' ')
            {
                board[i] = computer;

                int score = minimax(board, false, computer);

                board[i] = ' ';

                if (score > best_score)
                {
                    best_score = score;
                }
            }
        }

        return best_score;
    }
    else
    {
        int best_score = INT_MAX;

        for (int i = 0; i < 9; i++)
        {
            if (board[i] == ' ')
            {
                board[i] = player;

                int score = minimax(board, true, computer);

                board[i] = ' ';

                if (score < best_score)
                {
                    best_score = score;
                }
            }
        }

        return best_score;
    }
}

computer_turn(char board[9], char computer)

void computer_turn(char board[9], char computer)
{
    printf("%c's turn.\n", computer);

    int best_score = INT_MIN;
    int best_pos = -1;
    int free_spaces = check_free_spaces(board);

    for (int i = 0; i < 9; i++)
    {
        if (board[i] == ' ')
        {
            if (free_spaces == 1)
            {
                best_pos = i;
            }
            else
            {
                board[i] = computer;

                int score = minimax(board, 0, 10, false, computer);

                board[i] = ' ';

                if (score > best_score)
                {
                    best_score = score;
                    best_pos = i;
                }
            }
        }
    }

    board[best_pos] = computer;
}

also new to C from typescript so if you have suggestions to shorten my code it's much appreciated :)从打字稿到 C 也是新手,所以如果你有缩短我的代码的建议,非常感谢:)

Minimax assumes best play from both players, that is the core of the algorithm. Minimax 假设两个玩家的最佳发挥,这是算法的核心。 Tic Tac Toe will always be a draw no matter starting position, if both players play the best moves.井字游戏无论起始位置如何,只要双方都玩得最好,就永远是平局。 Therefore the algorithm will think each move from the starting position is equally good (a score of 0, a draw).因此,算法会认为从起始位置开始的每一步都同样好(得分为 0,平局)。

So when you do this check:因此,当您执行此检查时:

score > best_score

The score will never be better than the first possible place you check, which I assume is the top left corner.分数永远不会比你检查的第一个可能的地方好,我假设它是左上角。 If you for example try and change this to score >= best_score it will pick the bottom right corner (the last item in the list of possible moves).例如,如果您尝试将其更改为score >= best_score ,它将选择右下角(可能移动列表中的最后一项)。

So regarding your question, it isn't a bug.所以关于你的问题,这不是一个错误。 And it does actually pick the best move, given the nature of the algorithm.考虑到算法的性质,它实际上确实选择了最好的移动。 If you want it to play in the middle in the first move you need to force it to do so by hard coding it and bypassing the minimax algorithm.如果您希望它在第一步中发挥作用,则需要通过对其进行硬编码并绕过极小极大算法来强制它这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM