我目前正在开发包含带有AI对手的TicTacToe的Android应用程序。 我已经走得很远了,但由于某种原因并非所有的动作都是对手的计算导致他取得胜利或平局。 我做了一个递归的MiniMax算法(还没有修剪),我希望有人能够看到这里有什么问题,因为我真的找不到它。到目前为止,我画了很多树 我在Eclipse ADE中做了很多调试,每一步似乎都是正确的,但最后,它显然不是。
所以这是我的功能:
public int[] MiniMax( int[][] gameboard, boolean isCPUTurn, int[] move, int depth ){
if (gameboard[1][1]==EMPTY) { // Always take middle if possible
int[] best = {2,1,1};
return best;
}
// Recursion base-case
int winner = checkWinner();
if ( winner == 1 || winner == 2 || winner == 3 ){ // Game is over
int[] returnSet = {-1,-1,-1}; // leeg
// adjust scores for Minimax Player<----Tie---->CPU
// 0 1 2
switch (winner){
case 1:
returnSet[0] = 0 ; // Player wins
break;
case 2:
returnSet[0] = 2; // CPU wins
break;
case 3:
returnSet[0] = 1; // TIE
break;
default: // impossible..
returnSet[0] = 1;
}
// The last move led to the end of the game, return this outcome and move
returnSet[1] = move[0];
returnSet[2] = move[1];
return returnSet;
}
// A move is still possible, the game's not over yet
else{
int[] bestMove = null; // contains the best move found for this turn
for (int i=0; i<3; i++){ // check all child nodes/boards
for (int j=0; j<3; j++){
if( gameboard[i][j] == EMPTY ) // if the spot's not yet filled
{
if (isCPUTurn) gameboard[i][j] = TWO; // this move is CPU's
else gameboard[i][j] = ONE; // this move is Player's
int[] thismove = {i,j}; // {move Row, move Column}
// recursion
int[] result = MiniMax( gameboard, !isCPUTurn, thismove, depth+1);
// result = { winner result, move Row, move Column}
gameboard[i][j] = EMPTY; // delete last move after recursion
// check if child is best option
if (bestMove == null) // first child is always the best initially
bestMove = result;
else {
if (!isCPUTurn) // for CPU, higher is better
{ if (result[0]>bestMove[0])
bestMove = result;
//if (bestMove[0]==2) return bestMove; Pruning thingy
}
else if (isCPUTurn) // for Player, lower is better
{ if (result[0]<bestMove[0])
bestMove = result;
//if (bestMove[0]==0) return bestMove; Pruning thingy
}
}
}
}
}
return bestMove; // returns the best move found after checking all possible childs
}
}
如您所见,此函数使用中间递归直接调用自身。 它还调用checkWinner函数,它有4种可能的结果:0如果没有人赢了但是棋盘没有被填充,1如果玩家1(你)赢了,2如果玩家2(AI)赢了,3则是3领带(因此董事会被填补)。
所以,是的,我希望有人找到解决方案:D 提前谢谢!
答案 0 :(得分:2)
问题在于你总是从最深层次回归。在您检查是否有改进的行中
,您应该将bestMove
设置为包含坐标i
和j
,而不是更深层次移动的坐标,即result
。