【问题标题】:Problem implementing alpha-beta pruning for chess engine为国际象棋引擎实现 alpha-beta 修剪的问题
【发布时间】:2021-01-18 12:29:23
【问题描述】:

我最近一直在研究国际象棋引擎,我准备实施某种 AI 来实际玩游戏(搜索位置)。我写了一个 alpha-beta 剪枝算法,但是当我测试它时它并没有返回最好的移动。

alpha-beta 搜索的代码是:

float Search::alphabeta(S_BOARD* pos, S_SEARCHINFO *info, int depth, float alpha, float beta){
if (depth == 0) {
    info->nodes++;
    return eval::staticEval(pos);
}

info->nodes++;

S_MOVELIST list;
MoveGeneration::validMoves(pos, list);

float value = 0;
S_MOVE bestMove;
bestMove.move = NOMOVE;
bestMove.score = 0;

float prevBound = (pos->whitesMove == WHITE) ? alpha : beta;

int pvMove = TT::probeMove(pos);
if (pvMove != NOMOVE) {
    for (int i = 0; i < list.count; i++) {
        if (list.moves[i].move == pvMove) {
            list.moves[i].score = 20000000;
            break;
        }
    }
}


if (pos->whitesMove == WHITE) {
    value = -INFINITE;
    for (int moveNum = 0; moveNum < list.count; moveNum++) {
        pickNextMove(moveNum, &list);
        MoveGeneration::makeMove(*pos, list.moves[moveNum].move);

        value = max(value, alphabeta(pos, info, depth - 1, alpha, beta));

        MoveGeneration::undoMove(*pos);

        if (value > alpha) {
            if (value >= beta) {
                if (moveNum == 0) {
                    info->fhf++;
                }
                info->fh++;
                break;
            }
            alpha = value;
            bestMove = list.moves[moveNum];

        }

    }

    if (pos->is_checkmate) {
        return -MATE + pos->ply;
    }
    else if (pos->is_stalemate) {
        return 0;
    }

    if (alpha != prevBound) {
        TT::storePvMove(pos, bestMove);
    }

    return value;
}

else {
    value = INFINITE;

    for (int moveNum = 0; moveNum < list.count; moveNum++) {
        pickNextMove(moveNum, &list);
        MoveGeneration::makeMove(*pos, list.moves[moveNum].move);

        value = min(value, alphabeta(pos, info, depth - 1, alpha, beta));

        MoveGeneration::undoMove(*pos);

        if (value < beta){
            if (beta <= alpha) {
                if (moveNum == 0) {
                    info->fhf++;
                }
                info->fh++;
                break;
            }
            beta = value;
            bestMove = list.moves[moveNum];
        }


    }

    if (pos->is_checkmate) {
        return MATE - pos->ply;
    }
    else if (pos->is_stalemate) {
        return 0;
    }

    if (beta != prevBound) {
        TT::storePvMove(pos, bestMove);
    }

    return value;
}

(MoveGeneration 是一个命名空间,因此在对象实例之外调用函数不是问题。)

我在一个迭代加深函数里面运行这个函数,如下:

float Search::searchPosition(S_BOARD* pos, S_SEARCHINFO *info){

clearForSearch(pos, info);
float score = -INFINITE;
int bestMove = NOMOVE;
int pvMoves = 0;

// Iterative deepening.
for (int currDepth = 1; currDepth <= info->depth; currDepth++){
    auto start = std::chrono::high_resolution_clock::now();
    score = alphabeta(pos, info, currDepth, -INFINITE, INFINITE);
    auto end = std::chrono::high_resolution_clock::now();
    pvMoves = TT::getPvLine(pos, currDepth);
    bestMove = pos->pvArray[0];
    
    std::chrono::duration<double> elapsed = end - start;
    std::cout << "[+] Depth: " << currDepth << " score: " << score << " move: " << printMove(bestMove)
    << " nodes: " << info->nodes << " kN/s: " << (info->nodes/elapsed.count())/1000 << std::endl;
    
    std::cout << "pv";
    for (int i = 0; i < pvMoves; i++){
        std::cout << " " << printMove(pos->pvArray[i]);
    }
    std::cout << std::endl;
    
    std::cout << "Ordering: " << info->fhf/info->fh << std::endl;
    
}


return score;}

谁能帮我指出我犯的潜在错误?

感谢您的帮助,如果我需要上传更多代码,请告诉我。

【问题讨论】:

    标签: artificial-intelligence chess minimax alpha-beta-pruning


    【解决方案1】:

    它不会返回移动,因为您只返回 alpha/beta 函数底部的值。在原始调用中,输入:

    move, score = alphabeta(pos, info, currDepth, -INFINITE, INFINITE);
    

    在你的深度 == 0,将死并相持你返回:

    return None, eval
    

    在您的两个播放器函数(最小化和最大化播放器)结束时,您返回:

    return move, value
    

    最后,当您从两个播放器函数进行递归调用时,您只需要获取值即可。我不确定您的编程语言,但在例如Python 你把 [1] 放在最后只是为了获取价值而不是移动,就像这样:

    value = max(value, alphabeta(pos, info, depth - 1, alpha, beta))[1]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 2022-06-17
      • 1970-01-01
      • 2015-05-02
      • 2010-11-12
      相关资源
      最近更新 更多