Java TicTacToe MiniMax递归AI

时间:2014-02-02 17:49:57

标签: java algorithm recursion minimax

我目前正在开发包含带有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 提前谢谢!

1 个答案:

答案 0 :(得分:2)

问题在于你总是从最深层次回归。在您检查是否有改进的行中 ,您应该将bestMove设置为包含坐标ij,而不是更深层次移动的坐标,即result