You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python国际象棋引擎Move Ordering功能实现问题及优化求助

核心修改方案

1. 修复domove函数的致命逻辑错误

你当前domove函数的try-except-finally结构完全错误:finally块的代码无论前面是否触发返回都会强制执行,等于开局库查询、走法排序的结果全部被覆盖,这是你走法排序完全不生效的核心原因。同时开局库连续赋值三次move只会保留最后一个库的查询结果,没有容错逻辑。
修改后的代码:

def domove(depth):
    # 优先查询开局库
    book_paths = [
        "C:/Users/bruno/Desktop/chess/books/pecg_book.bin",
        "C:/Users/bruno/Desktop/chess/books/human.bin",
        "C:/Users/bruno/Desktop/chess/books/computer.bin"
    ]
    for path in book_paths:
        try:
            with chess.polyglot.MemoryMappedReader(path) as reader:
                move = reader.weighted_choice(board).move()
                movehistory.append(move)
                return move
        except:
            continue
    
    # 开局库无匹配,先对走法排序
    ordered_moves = orderMoves(board)
    bestMove = chess.Move.null()
    bestValue = -9999
    alpha = -10000
    beta = 10000
    
    # 用排序后的走法做alpha-beta搜索
    for move in ordered_moves:
        make_move(move)
        boardValue = -negamax(board, depth-1, -beta, -alpha)
        unmake_move()
        if boardValue > bestValue:
            bestValue = boardValue
            bestMove = move
        if boardValue > alpha:
            alpha = boardValue
        if alpha >= beta:
            break
    
    movehistory.append(bestMove)
    return bestMove

2. 重写orderMoves走法排序函数

你原有orderMoves逻辑完全混乱:没有对走法做排序、参数无意义、异常滥用。走法排序的核心是给所有合法走法计算优先级分数,按分数从高到低返回排序后的走法列表,而非直接返回某个走法。
修改后的代码:

def orderMoves(board):
    move_scores = {}
    # 先获取所有合法走法
    legal_moves = list(board.legal_moves)
    
    for move in legal_moves:
        score = 0
        # 优先级1:置换表中存储的当前局面最优走法
        tt_entry = transpositionTableLookup(board)
        if tt_entry.is_valid and tt_entry.best_move == move:
            score += 10000
        # 优先级2:一步将死走法
        board.push(move)
        if board.is_checkmate():
            score += 9000
        board.pop()
        # 优先级3:吃子走法用MVV-LVA规则打分
        if board.is_capture(move):
            victim = board.piece_at(move.to_square).piece_type
            attacker = board.piece_at(move.from_square).piece_type
            # 子力价值参考:兵1、马3、象3、车5、后9、王0
            piece_values = {1:1, 2:3, 3:3, 4:5, 5:9, 6:0}
            score += 100 * piece_values[victim] - piece_values[attacker]
        move_scores[move] = score
    
    # 按分数从高到低排序
    legal_moves.sort(key=lambda x: move_scores[x], reverse=True)
    return legal_moves

3. 修复negamax函数逻辑错误

你原有negamax存在参数冗余、置换表存储缩进错误、递归调用逻辑混乱的问题:置换表存储代码被写在for循环内,只有触发剪枝时才会执行存储,大部分情况不会写入置换表,同时参数score、bestValue不需要外部传入。
修改后的代码:

def negamax(node, depth, alpha, beta):
    alphaOrig = alpha
    EXACT = 0
    LOWERBOUND = 1
    UPPERBOUND = 2

    # 置换表查询
    ttEntry = transpositionTableLookup(node)
    if ttEntry.is_valid:
        if ttEntry.depth >= depth:
            if ttEntry.flag == EXACT:
                return ttEntry.value
            elif ttEntry.flag == LOWERBOUND:
                alpha = max(alpha, ttEntry.value)
            elif ttEntry.flag == UPPERBOUND:
                beta = min(beta, ttEntry.value)
        if alpha >= beta:
            return ttEntry.value

    # 递归终止条件:深度为0或者局面终局
    if depth == 0 or node.is_game_over():
        return evaluate(node) # 替换为你自己的局面评估函数
    
    # 获取排序后的走法
    ordered_moves = orderMoves(node)
    bestValue = -99999
    best_move = None

    for move in ordered_moves:
        node.push(move)
        current_value = -negamax(node, depth - 1, -beta, -alpha)
        node.pop()
        if current_value > bestValue:
            bestValue = current_value
            best_move = move
        alpha = max(alpha, bestValue)
        if alpha >= beta:
            break

    # 置换表存储
    ttEntry.value = bestValue
    ttEntry.best_move = best_move
    if bestValue <= alphaOrig:
        ttEntry.flag = UPPERBOUND
    elif bestValue >= beta:
        ttEntry.flag = LOWERBOUND
    else:
        ttEntry.flag = EXACT
    ttEntry.depth = depth
    transpositionTableStore(node, ttEntry)
    
    return bestValue

4. 验证优化步骤

  • 先单独测试orderMoves函数,打印排序后的走法顺序,确认高优先级走法(吃子、将死、置换表最优走法)排在最前
  • 暂时关闭开局库、置换表,验证基础negamax+alpha-beta搜索的正确性,24个测试用例全部通过后再逐步开启其他模块
  • 确认你的局面评估函数evaluate逻辑正确,这是搜索结果准确的基础

内容的提问来源于stack exchange,提问作者Bruno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 15:54:06