簡體   English   中英

確定井字游戲的最佳動作

[英]Determine best move in tic tac toe

我想編寫一個遞歸函數來確定給定井字游戲中的最佳動作

int nextMove(struct Game g, enum Symbol player) {
if (game_over(g) != 0) {
return -1;
}
int i, j;
int score, end;
for(i = 0; i < 3; i += 1) {
    for (j = 0; j < 3; j += 1) {
        if(g.board.fields[i][j] == 0) {
            g.board.fields[i][j] = player;
            score = nextMove(g, -player);
        }
    }
}
end = game_over(g)
}

我的game_over函數:

enum Symbol game_over(struct Game g)
{
int x, y = x = 0;
int full = 0;

for (y = 0; y < SIZE_Y_AXIS; y += 1)
{
    for (x = 0; x < SIZE_X_AXIS; x += 1)
    {
        if (g.board.fields[x][y] == NONE)
            full++;
        else if (x < SIZE_X_AXIS - 2 &&
                 g.board.fields[x][y] == g.board.fields[x+1][y] &&
                 g.board.fields[x][y] == g.board.fields[x+2][y])
            return g.board.fields[x][y];
        else if (y < SIZE_Y_AXIS - 2 &&
                 g.board.fields[x][y] == g.board.fields[x][y+1] &&
                 g.board.fields[x][y] == g.board.fields[x][y+2])
            return g.board.fields[x][y];
        else if (x < SIZE_X_AXIS - 2 && y < SIZE_Y_AXIS - 2 &&
                 g.board.fields[x][y] == g.board.fields[x+1][y+1] &&
                 g.board.fields[x][y] == g.board.fields[x+2][y+2])
            return g.board.fields[x][y];
        else if (x >= 2 && y < SIZE_Y_AXIS - 2 &&
                 g.board.fields[x][y] == g.board.fields[x-1][y+1] &&
                 g.board.fields[x][y] == g.board.fields[x-2][y+2])
            return g.board.fields[x][y];
    }
}
if (full == 0)
    return FULL;
return NONE;
}

我認為煙葉的生產效果很好,但是我不知道如何確定哪一葉(或哪一招)是最好的? 現在有什么建議嗎?

謝謝

在井字游戲中,搜索樹是如此之小,可以評估所有葉子節點(與象棋或圍棋這樣的搜索被縮短的游戲不同)。 由於檢查了所有節點,因此可以通過檢查葉子節點是贏,輸還是平局來評估葉子節點。 您可以分別使用1,-1和0來表示這些值。 完成后,將節點的值返回給它的父節點。 對於非葉節點,它必須選擇其子節點的最大值或最小值,這取決於它是最大節點(計算機)還是最小節點(其對手),這將一直備份樹根,為其所有可能的移動賦予價值。 在樹的根部具有最高值的移動是該位置的最佳移動。這是minimax算法。 此外,在您提供的代碼示例中,您未能在所有字段都填滿之前檢查游戲是否結束。 相反,請檢查玩家是否已經連續獲得三局,因為游戲已經結束。 注意:您的nextMove函數聲稱返回一個int,但在大多數情況下不返回。 那必須解決。 這是我要添加到您的代碼中的內容(偽代碼中添加的部分)。 我不確定確切的game_over函數做什么,所以我不確定確切的代碼應該是什么。 因此,我要刪除它並添加psuedocode來代替它。

int nextMove(struct Game g, enum Symbol player) {
    if (computerWon) {
    return 1;
    }
    if (OpponnentWon) {
    return -1;
    }
    if (allSquaresAreFull) {
    return 0;
    }
    int i, j;
    int bestScore;//use this to calculate which move to return
    int score, end;
    //now check whose turn it is
    if(player == 1){//I'm assuming this is the computer player
        bestScore = -100;//start with an arbitrary low value 
        for(i = 0; i < 3; i += 1) {
            for (j = 0; j < 3; j += 1) {
                if(g.board.fields[i][j] == 0) {
                    g.board.fields[i][j] = player;
                    score = nextMove(g, -player);
                    g.board.fields[i][j] = 0;//make sure to undo every move made in the search
                    if(score > bestScore){//a better move for this player
                         bestScore = score;//update bestScore
                    }
               }
           }
        }
        return bestScore;//return best move to parent;

    }
    if(player == -1){//I'm assuming this is the opponent
        bestScore = 100;//start with an arbitrary high value 
        for(i = 0; i < 3; i += 1) {
            for (j = 0; j < 3; j += 1) {
                if(g.board.fields[i][j] == 0) {
                    g.board.fields[i][j] = player;
                    score = nextMove(g, -player);
                    g.board.fields[i][j] = 0;//make sure to undo every move made in the search
                    if(score < bestScore){//a better move for the opponent is a lower move
                         bestScore = score;//update bestScore
                    }
               }
           }
        }
        return bestScore;//return best move to parent;

    }
end = game_over(g)//this variable is never used. Not sure what it does. I would remove it, it seems useless
}

這應該返回頭寸的值(如果贏得,丟失或平倉)。 為了確定采取哪一步,必須對此做些微修改。 添加一個測試以查看是否在第一次調用nextMove(即根),而不是僅跟蹤移動的值ony bestMove,同時跟蹤實際的最佳移動是什么(也許在移動結構中)。 如果最好的話,將其返回。 現在nextMove將返回要采取的動作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM