Java 极小极大算法不返回最佳移动

Java 极小极大算法不返回最佳移动,java,algorithm,search,minimax,Java,Algorithm,Search,Minimax,我正在编写一个使用minimax和alpha-beta修剪的奥赛罗引擎。 工作正常,但我发现以下问题: 当算法发现一个位置丢失时,它返回-如预期的无穷大,但在 在这种情况下,我无法跟踪“最佳”移动…位置已经丢失,但它应该返回一个有效的移动,不管怎样,最好是一个存活时间更长的移动,就像好的国际象棋引擎一样 代码如下: private float minimax(OthelloBoard board, OthelloMove best, float alpha, float beta, int de

我正在编写一个使用minimax和alpha-beta修剪的奥赛罗引擎。 工作正常,但我发现以下问题:

当算法发现一个位置丢失时,它返回-如预期的无穷大,但在 在这种情况下,我无法跟踪“最佳”移动…位置已经丢失,但它应该返回一个有效的移动,不管怎样,最好是一个存活时间更长的移动,就像好的国际象棋引擎一样

代码如下:

private float minimax(OthelloBoard board, OthelloMove best, float alpha, float beta, int depth)
{             
    OthelloMove garbage = new OthelloMove();             
    int currentPlayer = board.getCurrentPlayer();

    if (board.checkEnd())
    {                        
        int bd = board.countDiscs(OthelloBoard.BLACK);
        int wd = board.countDiscs(OthelloBoard.WHITE);

        if ((bd > wd) && currentPlayer == OthelloBoard.BLACK)                
            return INFINITY;
        else if ((bd < wd) && currentPlayer == OthelloBoard.BLACK)                           
            return -INFINITY;            
        else if ((bd > wd) && currentPlayer == OthelloBoard.WHITE)                            
            return -INFINITY;            
        else if ((bd < wd) && currentPlayer == OthelloBoard.WHITE)                            
            return INFINITY;            
        else                             
            return 0.0f;            
    }
    //search until the end? (true during end game phase)
    if (!solveTillEnd )
    {
        if (depth == maxDepth)
            return OthelloHeuristics.eval(currentPlayer, board);
    }

    ArrayList<OthelloMove> moves = board.getAllMoves(currentPlayer);             

    for (OthelloMove mv : moves)
    {                        
        board.makeMove(mv);            
        float score = - minimax(board, garbage, -beta,  -alpha, depth + 1);           
        board.undoMove(mv);             

        if(score > alpha)
        {  
            //Set Best move here
            alpha = score;                
            best.setFlipSquares(mv.getFlipSquares());
            best.setIdx(mv.getIdx());        
            best.setPlayer(mv.getPlayer());                              
        }

        if (alpha >= beta)
            break;                

    }                
    return alpha;
}
当一个丢失的位置想象它丢失了10个移动后,例如搜索,上面的最佳变量等于作为参数传递的空无效移动…为什么


谢谢你的帮助

我已经很久没有实现minimax了,所以我可能是错的,但是在我看来,如果你遇到一个成功或失败的动作,你的代码不会更新方法顶部的board.checkEnd语句中的最佳变量

另外,如果你想让你的算法尽可能多的赢,或者如果赢不了的话尽可能少的输,我建议你更新你的eval函数。在赢的情况下,它应该返回一个比任何非赢的情况都大的值,你赢的越多,值就越大。在丢失的情况下,它应该返回一个比在任何非丢失的情况下都少的大负值,您丢失的越多,值就越小


在我看来,如果您以这种方式更新eval函数并跳过check if board.checkEnd,那么您的算法应该可以正常工作,除非有其他问题。祝你好运

你的问题是你使用了-INFINITY和+INFINITY作为赢/输分数。您的赢/输分数应该高于/低于任何其他职位评估分数,但不等于您的无穷大值。这将保证即使在毫无希望地输掉的位置上也会选择一个移动。

如果你能检测到一个位置是真的赢了还是输了,那么这就意味着你正在解决终局。在这种情况下,您的评估函数应该返回游戏的最终分数,例如,全胜64分,窄输31分,因为这可以准确计算,与您将在中期评估的估计值不同。

请阅读和,并提出更具体的问题。另外,你的问题是不完整的;您还没有展示类AI的定义,这对问题非常关键。问题是概念性的,而不是代码问题。我提供的代码足以解决我认为的问题。不过还是要谢谢你,我会读这篇文章来了解更多。你刚刚解决了这个问题,谢谢!现在,当到达丢失位置时,我返回无穷大/10或-无穷大/10。如果我理解得很好,我必须返回一个介于-INF和+INF之间的值,对吗?正确,只要赢或输的位置可以返回这些值。你还应该尝试让函数根据你赢或输的多少返回一个值,这样如果你赢了64个,它应该返回一个更大的值,如果你赢了50个。这样,您的算法将不仅搜索胜利,而且搜索最佳胜利。所有获胜条件的值应大于非获胜条件的任何值。
AI ai = new AI(board, maxDepth, solveTillEnd);

//create empty (invalid) move to hold best move
OthelloMove bestMove = new OthelloMove();
ai.bestFound = bestMove;
ai.minimax(board, bestMove, -INFINITY, INFINITY, 0);

//dipatch a Thread
 new Thread(ai).start();
//wait for thread to finish

OthelloMove best = ai.bestFound();