c - 我的 tictactoe 极小极大算法有什么问题

标签 c algorithm tic-tac-toe minimax

我正在构建一个井字游戏,以获得有趣的学习体验。我构建了一个 minimax 算法来返回计算机的最佳移动,但不知何故我出错了,得到了这样的奇怪输出

TIC TAC TOE V1.0
---
---
---
Enter row, column of your move
1,1
---
-X-
---
...
0, 0: -1038
0, 1: -1470
0, 2: -1038
1, 0: -1470
1, 2: -1470
2, 0: -1038
2, 1: -1470
2, 2: -1038
O--
-X-
---
Enter row, column of your move
1,2
O--
-XX
---
...
0, 1: -15
0, 2: -9
1, 0: -10
2, 0: -1
2, 1: -29
2, 2: -41
O--
-XX
O--
Enter row, column of your move
1,0
O--
XXX
O--
WINNER: PLAYER

可以看到电脑选择了左下角而不是切断播放器。我的代码尝试在所有可能的游戏状态之间递归地翻转,总结回合可能导致的每次输赢的分数,然后返回得分最高的 Action 。打印输出是每回合之前的分数(你可以看到它选择了最高的),那我为什么不切断玩家呢?我怎样才能解决这个问题?这是我的代码。

int compMoveScoreRecursive(state_t **board, int dimension, int row, int col, state_t turn) {
    board[row][col] = turn;
    state_t winner = checkWinner(board, dimension);
    if (winner == COMPUTER) {
        return 1;
    } else if (winner == PLAYER) {
        return -1;
    } else {
        int score = 0;
        state_t nextTurn = turn == COMPUTER ? PLAYER : COMPUTER;
        for (int i = 0; i < dimension; i++) {
            for (int j = 0; j < dimension; j++) {
                if (board[i][j] == NIL) {
                    state_t **boardCopy = copyBoard(board, dimension);
                    score += compMoveScoreRecursive(boardCopy, dimension, i, j, nextTurn);
                    destroyBoard(boardCopy, dimension);
                }
            }
        }
        return score;
    }
}

move_t optimalCompMove(state_t **board, int dimension) {
    move_t optMove;
    int optScore = INT_MIN;
    for (int row = 0; row < dimension; row++) {
        for (int col = 0; col < dimension; col++) {
            if (board[row][col] == NIL) {
                state_t **boardCopy = copyBoard(board, dimension);
                int score = compMoveScoreRecursive(boardCopy, dimension, row, col, COMPUTER);
                printf("%d, %d: %d\n", row, col, score);
                if (score > optScore) {
                    optMove.row = row;
                    optMove.col = col;
                    optScore = score;
                }
                destroyBoard(boardCopy, dimension);
            }
        }
    }
    return optMove;
}

最佳答案

minmax 算法的概念是“最小化最大损失”(Wikipedia),因此您的算法首先出错的是您的总和。

对于游戏的任何状态 S,以及对于当前玩家可用的任何移动 M(假设玩家 1 P1), minmax (S + M, P2) 的值是 P2最大 可能输出,如果 P1 播放 M。所以如果 P1 想要最大化他获胜的机会,他应该尽可能地减少 P2 的最大输出,即他必须找到最小值 的输出。

tictactoe minmax 中,可以测试整个游戏(最多 9 步),这意味着如果 PX 赢 (1),输 ( -1) 或平局 (0)。所以 minmax (state, PX) 将只返回这三个值之一。

在很多游戏中,你不能玩完整个游戏(例如草稿),所以返回值是状态的指示,例如-oo如果你输了,+oo 如果你赢了,否则就是你和对手的选秀次数之差。

关于c - 我的 tictactoe 极小极大算法有什么问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31617469/

相关文章:

java - 如何找到两个节点之间的距离 map<Integer,List<Integer>>

javascript - Tic-Tac-Toe 中的 Minimax 没有返回正确的值

javascript - 如何使用 Minimax Algorithm.and Alpha Beta Pruning 解决 Tic Tac Toe 4x4 游戏

dart - 发现 Flutter W/zipro ( 2568) : Error opening archive build\app\outputs\apk\app. apk : ERROR: dump failed because no AndroidManifest. xml

c - 如何在不使用字符串的情况下计算单词总数?

algorithm - Find Top 10 Most Frequent visited URl,数据跨网络存储

c - C中的字数统计,学习更多CS

c++算法 - count_if对象中的第三个参数

c - fflush() 函数不适用于标准输入

C 使用n+1维数组作为n维数组参数