gpt4 book ai didi

计算一定深度的 Minimax Tree 中的移动分数

转载 作者:太空狗 更新时间:2023-10-29 16:56:52 25 4
gpt4 key购买 nike

我用 C 实现了一个国际象棋游戏,具有以下结构:

move - which represents a move from (a,b) to (c,d) on a char board[8][8] (Chess board)

moves - which is a linked list of moves with head and tail.

Variables:playing_color is 'W' or 'B'.minimax_depth is a minimax depth that was set before.

这是我的带有 alpha-beta 修剪的 Minimax 函数和 getMoveScore 函数的代码,它应该返回之前设置的某个 minimax_depth 的 Minimax Tree 中移动的分数。

我还使用了 getBestMoves 函数,我也将在此处列出它,它基本上可以找到 Minimax 算法期间的最佳移动并将它们保存到全局变量中,以便我以后能够使用它们。

我必须补充一点,我将在此处添加的三个函数中列出的所有函数都可以正常工作并经过测试,因此问题要么是 alphabetaMax 算法的逻辑问题,要么是getBestMoves/getMoveScore。

问题主要是,当我在深度 N 获得我的最佳移动(不知为何也没有正确计算),然后使用 getMoveScore 函数检查它们在相同深度的分数时,我得到的分数不同'匹配那些实际最佳移动的分数。我花了几个小时调试它,但看不到错误,我希望也许有人能给我提示以找到问题所在。

代码如下:

/*
* Getting best possible moves for the playing color with the minimax algorithm
*/
moves* getBestMoves(char playing_color){
//Allocate memory for the best_moves which is a global variable to fill it in a minimax algorithm//
best_moves = calloc(1, sizeof(moves));
//Call an alpha-beta pruned minimax to compute the best moves//
alphabeta(playing_color, board, minimax_depth, INT_MIN, INT_MAX, 1);
return best_moves;
}

/*
* Getting the score of a given move for a current player
*/
int getMoveScore(char playing_color, move* curr_move){
//Allocate memory for best_moves although its not used so its just freed later//
best_moves = calloc(1, sizeof(moves));
int score;
char board_cpy[BOARD_SIZE][BOARD_SIZE];
//Copying a a current board and making a move on that board which score I want to compute//
boardCopy(board, board_cpy);
actualBoardUpdate(curr_move, board_cpy, playing_color);
//Calling the alphabeta Minimax now with the opposite color , a board after a given move and as a minimizing player, because basicly I made my move so its now the opponents turn and he is the minimizing player//
score = alphabeta(OppositeColor(playing_color), board_cpy, minimax_depth, INT_MIN, INT_MAX, 0);
freeMoves(best_moves->head);
free(best_moves);
return score;
}

/*
* Minimax function - finding the score of the best move possible from the input board
*/
int alphabeta(char playing_color, char curr_board[BOARD_SIZE][BOARD_SIZE], int depth,int alpha,int beta, int maximizing) {
if (depth == 0){
//If I'm at depth 0 I'm evaluating the current board with my scoring function//
return scoringFunc(curr_board, playing_color);
}
int score;
int max_score;
char board_cpy[BOARD_SIZE][BOARD_SIZE];
//I'm getting all the possible legal moves for the playing color//
moves * all_moves = getMoves(playing_color, curr_board);
move* curr_move = all_moves->head;
//If its terminating move I'm evaluating board as well, its separate from depth == 0 because only here I want to free memory//
if (curr_move == NULL){
free(all_moves);
return scoringFunc(curr_board,playing_color);
}
//If maximizing player is playing//
if (maximizing) {
score = INT_MIN;
max_score = score;
while (curr_move != NULL){
//Make the move and call alphabeta with the current board after the move for opposite color and !maximizing player//
boardCopy(curr_board, board_cpy);
actualBoardUpdate(curr_move, board_cpy, playing_color);
score = alphabeta(OppositeColor(playing_color), board_cpy, depth - 1,alpha,beta, !maximizing);

alpha = MAX(alpha, score);
if (beta <= alpha){
break;
}
//If I'm at the maximum depth I want to get current player best moves//
if (depth == minimax_depth){
move* best_move;
//If I found a move with a score that is bigger then the max score, I will free all previous moves and append him, and update the max_score//
if (score > max_score){
max_score = score;
freeMoves(best_moves->head);
free(best_moves);
best_moves = calloc(1, sizeof(moves));
best_move = copyMove(curr_move);
concatMoves(best_moves, best_move);
}
//If I have found a move with the same score and want to concatenate it to a list of best moves//
else if (score == max_score){
best_move = copyMove(curr_move);
concatMoves(best_moves, best_move);
}

}
//Move to the next move//
curr_move = curr_move->next;
}
freeMoves(all_moves->head);
free(all_moves);
return alpha;
}
else {
//The same as maximizing just for a minimizing player and I dont want to look for best moves here because I dont want to minimize my outcome//
score = INT_MAX;
while (curr_move != NULL){
boardCopy(curr_board, board_cpy);
actualBoardUpdate(curr_move, board_cpy, playing_color);
score = alphabeta(OppositeColor(playing_color), board_cpy, depth - 1,alpha,beta, !maximizing);
beta = MIN(beta, score);
if (beta <= alpha){
break;
}
curr_move = curr_move->next;
}
freeMoves(all_moves->head);
free(all_moves);
return beta;
}
}

正如 Eugene 所指出的——我在这里添加了一个示例: http://imageshack.com/a/img910/4643/fmQvlm.png

我目前是白色玩家,我只有 king-k 和 queen-q,相反的颜色有 king-K 和 rook-R。显然,我在这里最好的举动是吃掉一只车或至少进行检查。棋子的 Action 经过测试,效果很好。虽然当我在深度 3 调用 get_best_moves 函数时,我在那个深度得到了很多不必要的 Action 和负分。也许现在更清楚了。谢谢!

最佳答案

如果不调试整个代码,至少有一个问题是您的分数验证可能适用于极小极大算法,但不适用于 Alpha-Beta。以下问题:

getMoveScore() 函数必须从打开的 AB 窗口开始。

然而,getBestMoves() 调用 getMoveScore() 时已关闭 AB 窗口。

所以在 getBestMoves 的情况下,可能有一些分支在 getMoveScore() 中没有被修剪,因此分数不准确,这就是这些值可能不同的原因(或至少其中之一)。

关于计算一定深度的 Minimax Tree 中的移动分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32014791/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com