【问题标题】:(Chess) Problem with negamax search missing checkmate(国际象棋)negamax 搜索缺少将死的问题
【发布时间】:2021-09-05 18:11:12
【问题描述】:

我正在使用 Negamaxalpha-beta 修剪 在搜索函数中实现搜索算法。但是,它经常会错过强制将死。
注意:“Mate in X”计算整个回合,而“depth”和“move(s)”依赖于半个移动。)

示例

具有以下 FEN 的位置:1k1r4/pp1b1R2/3q2pp/4p3/2B5/4Q3/PPP2B2/2K5 b - - 0 1 有一个 Mate in 3(算法的深度为 5)。 它去 Qd1+, Kxd1, Bg4+, Kc1/Ke1 (没关系), Rd1#。

它可以在 1 步远的地方发现将死,但在更高的深度会失败。

可能的原因

这可能是一个错字,一个误用的type,甚至是对方法的完全误解,因为这一切都发生在以前。

简化代码

我已经使代码的某些部分更易于阅读。 (例如,删除std::,将多行转换为函数)。
不过不应该改变功能。

根调用

pieceMove searchBestMove (gameState currentState, int depth) {
//Calls the Negamax search
    pieceColor sideToMove = whoseTurnIsIt();
    
    vector<pieceMove> moveList = generateLegalMoves(currentState, sideToMove);
    
    pieceMove bestMove;
    signed int bestEval = numeric_limits<signed int>::max();
    
    for (const auto move : moveList) {
        signed int evaluation = negaMax(applyMove(currentState, move), numeric_limits<signed int>::min(), numeric_limits<signed int>::max(), depth - 1, 1);
        if (evaluation < bestEval) {
            bestMove = move;
            bestEval = evaluation;
        }
    }
    
    return bestMove;
}

搜索功能

signed int negaMax (gameState currentState, signed int alpha, signed int beta, int depth, int rootDepth) {
//Main Negamax search
    //Terminal node
    if (depth == 0) {
        return evaluates(currentState); //Replace this line with the one below to enable the extended search
        //return quiescenceSearch(currentState, alpha, beta); 
    }
    
    //Mate distance pruning
    signed int mateDistScore = numeric_limits<signed int>::max() - rootDepth;
    alpha = max(alpha, -mateDistScore);
    beta = min(beta, mateDistScore - 1);
    if (alpha >= beta) return alpha;
    
    vector<pieceMove> moveList = generateLegalMoves(currentState);

    //If no moves are allowed, then it's either checkmate or stalemate
    if (moveList.size() == 0) return evaluates(currentState)
     
    orderMoves(currentState, moveList);


    for (const auto move : moveList) {
        signed int score = -negaMax(applyMove(currentState, move), -beta, -alpha, depth - 1, rootDepth + 1);
        if (score >= beta) return beta; //Bata cutoff
        alpha = max(score, alpha);
    }
    
    return alpha;
}

扩展搜索

signed int quiescenceSearch (gameState currentState, signed int alpha, signed int beta) {
//Searches only captures
    //Terminal node
    int evaluation = evaluates(currentState);
    if (evaluation >= beta) return beta;
    alpha = max(alpha, evaluation);
    
    vector<pieceMove> moveList = generateCaptureMoves(currentState);

    //If no moves are allowed, then it's either checkmate or stalemate
    if (moveList.size() == 0) return evaluates(currentState);
    
    orderMoves(currentState, moveList);

    for (const auto move : moveList) {
        signed int score = -quiescenceSearch(applyMove(currentState, move), -beta, -alpha);
        if (score >= beta) return beta; //Bata cutoff
        alpha = max(score, alpha);
    }
    
    return alpha;
}

【问题讨论】:

    标签: c++ chess minimax negamax


    【解决方案1】:

    我认为你需要在“negaMax”中深度为0时调用函数“quiescenceSearch”。此外,您还需要在“quiescenceSearch”中检查“检查”以及捕获,因为它们不是安静的动作。此外,Matedistance 修剪仅在正确评分时才有效(https://www.chessprogramming.org/Mate_Distance_Pruning#Mating_Value)。检查您的评估功能是否正确评估也可能会有所帮助。

    【讨论】:

    • 谢谢!这正是答案 - 如果黑色获胜,则评​​估是 numeric_limit::min(),当算法尝试以黑色为中心进行评估时(Negamax 需要),它会尝试将其与 -1 相乘,并产生 numeric_limit::max() + 1导致溢出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多