迷你最大算法在C语言中的井字游戏解释

我在尝试学习关于计算机游戏玩家的知识,以熟悉人工智能。我理论上理解了迷你最大算法的工作原理,但无法理解我在网上找到的这部分代码的工作方式。能有人向我解释迷你最大函数/计算机移动函数(38-78行)吗。鸣谢:https://gist.github.com/MatthewSteel/3158579

谢谢

char gridChar(int i) {    switch(i) {        case -1:            return 'X';        case 0:            return ' ';        case 1:            return 'O';    }}void draw(int b[9]) {    printf(" %c | %c | %c\n",gridChar(b[0]),gridChar(b[1]),gridChar(b[2]));    printf("---+---+---\n");    printf(" %c | %c | %c\n",gridChar(b[3]),gridChar(b[4]),gridChar(b[5]));    printf("---+---+---\n");    printf(" %c | %c | %c\n",gridChar(b[6]),gridChar(b[7]),gridChar(b[8]));}int win(const int board[9]) {    //determines if a player has won, returns 0 otherwise.    unsigned wins[8][3] = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};    int i;    for(i = 0; i < 8; ++i) {        if(board[wins[i][0]] != 0 &&           board[wins[i][0]] == board[wins[i][1]] &&           board[wins[i][0]] == board[wins[i][2]])            return board[wins[i][2]];    }    return 0;}int minimax(int board[9], int player) {    //How is the position like for player (their turn) on board?    int winner = win(board);    if(winner != 0) return winner*player;    move = -1;    int score = -2;//Losing moves are preferred to no move    int i;    for(i = 0; i < 9; ++i) {//For all moves,        if(board[i] == 0) {//If legal,            board[i] = player;//Try the move            int thisScore = -minimax(board, player*-1);            if(thisScore > score) {                score = thisScore;                move = i;            }//Pick the one that's worst for the opponent            board[i] = 0;//Reset board after try        }    }    if(move == -1) return 0;    return score;}void computerMove(int board[9]) {    int move = -1;    int score = -2;    int i;    for(i = 0; i < 9; ++i) {        if(board[i] == 0) {            board[i] = 1;            int tempScore = -minimax(board, -1);            board[i] = 0;            if(tempScore > score) {                score = tempScore;                move = i;            }        }    }    //returns a score based on minimax tree at a given node.    board[move] = 1;}void playerMove(int board[9]) {    int move = 0;    do {        printf("\nInput move ([0..8]): ");        scanf("%d", &move);        printf("\n");    } while (move >= 9 || move < 0 && board[move] == 0);    board[move] = -1;}int main() {    int board[9] = {0,0,0,0,0,0,0,0,0};    //computer squares are 1, player squares are -1.    printf("Computer: O, You: X\nPlay (1)st or (2)nd? ");    int player=0;    scanf("%d",&player);    printf("\n");    unsigned turn;    for(turn = 0; turn < 9 && win(board) == 0; ++turn) {        if((turn+player) % 2 == 0)            computerMove(board);        else {            draw(board);            playerMove(board);        }    }    switch(win(board)) {        case 0:            printf("A draw. How droll.\n");            break;        case 1:            draw(board);            printf("You lose.\n");            break;        case -1:            printf("You win. Inconceivable!\n");            break;    }}

回答:

以下是minimax的核心内容:

int minimax(int board[9], int player) {    // ....    for(i = 0; i < 9; ++i) { //For all moves,        // ....        int thisScore = -minimax(board, player*-1);    }}

遍历每个可能的移动,对于每个可能的移动,翻转棋盘,假装成为另一个玩家(这就是player*-1部分),并尝试每个可能的移动。thisScore被设置为对minimax的递归调用的负返回值,因为对另一个玩家有利就对我们自己不利。

computerMove只是遍历所有可能的移动,为每个可能的移动调用minimax,并使用结果最佳的那个移动。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注