【问题标题】:Transposition Table for chess move generation inside minimax function极小极大函数内国际象棋移动生成的转置表
【发布时间】:2020-11-02 06:55:53
【问题描述】:

背景

我正在尝试针对国际象棋优化我的极小极大算法,并且迄今为止使用了 alpha-beta 修剪。我还使用转置表实现了迭代深化,以便以后进行优化。到目前为止我得到的基本上是一些python代码:

# Original call
def ai_make_move(gamestate):
    for depth in range(1, max_depth):
        move, evaluation = minimax(gamestate, depth, -math.inf, math.inf, maximizing_player)

# Minimax
def minimax(gamestate, depth, -math.inf, math.inf, maximizing_player):
    board.is_human_turn = not maximizing_player
    children = board.get_all_possible_moves()

    if depth == 0 or board.is_draw or board.is_check_mate:
        return None, evaluate(board)

    best_move = children[0]

    if maximizing_player:
        max_eval = -math.inf
        for child in children:
            board.make_move(child)
            current_eval = minimax(board, depth - 1, alpha, beta, False)[1]
            board.unmake_move()

            if current_eval > max_eval:
                max_eval = current_eval
                best_move = child
            alpha = max(alpha, current_eval)

            if beta <= alpha:
                break

        return best_move, max_eval

    else:
        min_eval = math.inf
        for child in children:
            board.make_move(child)
            current_eval = minimax(board, depth - 1, alpha, beta, True)[1]
            board.unmake_move()

            if current_eval < min_eval:
                min_eval = current_eval
                best_move = child
            beta = min(beta, current_eval)

            if beta <= alpha:
                break
        return best_move, min_eval

问题

由于我进行了迭代深化,我认为我可以利用之前计算的 valid_moves(一个位置的子级)从之前的深度。因此,当计算深度 1 处的位置时,它会计算该位置中黑色的所有有效移动。在深度 2 处计算时,它将从计算相同的位置开始,再次为黑色有效移动,这似乎是一个不必要的操作,因为我已经在最后一个循环中这样做了。所以我应该能够从表中保存的 valid_moves 中检索它。

我已经使用 zobrist 散列来为每个位置获取一个几乎唯一的数字,并尝试在我的 minimax 函数中像这样使用它:

# Minimax
def minimax(gamestate, depth, -math.inf, math.inf, maximizing_player):

    if gamestate.zobrist_key in gamestate.transposition_table:
        children = gamestate.transposition_table[gamestate.zobrist_key]
    else:
        board.is_human_turn = not maximizing_player
        children = board.get_all_possible_moves()

    if depth == 0 or board.is_draw or board.is_check_mate:
        return None, evaluate(board)

   ......

由于某种原因,引擎做出了完全不合理的动作,在当前位置是不合法的,而且似乎不起作用。

我的尝试

我已经检查过了:

  • 我的 Zobrist 计算方式正确。
  • make_move 和 unmake_move 函数可以正常工作(在人类与人类比赛时)。
  • 当没有换位表的概念时,AI 似乎在工作并下出良好有效的动作。

问题

我不知道出了什么问题,也不知道这是否是正确的方法。非常感谢任何指导!

【问题讨论】:

    标签: python chess


    【解决方案1】:

    您不能假设引擎在较浅深度下进行的评估是准确的,因为位置可能会改变下一步行动,例如简单地捕获您的女王。这就是为什么您可以进行移动排序并首先从表中计算先前迭代中最有希望的移动,而不是根本不计算先前搜索的移动,并且通常α-β修剪会使这比仅仅从搜索更快固定深度。

    【讨论】:

      猜你喜欢
      • 2021-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多