【问题标题】:Slow chess bot, need to go faster慢棋机器人,需要走得更快
【发布时间】:2021-03-15 06:17:15
【问题描述】:

我创建了一个使用 minimax 和 alpha beta 修剪的国际象棋机器人,同时我还创建了一个 GUI。但是我的机器人在变得非常缓慢之前不能深入。已经在深度 4 中找到移动可能需要 40-50 秒。

算法如下:

def minimax(depth,board, alpha, beta, is_max):
    if depth == 0:
        return evaluation(board)
    leg_moves = board.legal_moves
    if is_max:
        value = -9999
        for i_move in leg_moves:
            move = chess.Move.from_uci(str(i_move))
            board.push(move)
            value = max(value, minimax(depth - 1, board, alpha, beta, False))
            board.pop()
            alpha = max(alpha, value)
            if beta <= alpha:
                return value
        return value
    else:
        value = 9999
        for i_move in leg_moves:
            move = chess.Move.from_uci(str(i_move))
            board.push(move)
            value = min(value, minimax(depth - 1, board, alpha, beta, True))
            board.pop()
            beta = min(beta, value)
            if(beta <= alpha):
                return value
        return value

总而言之,我怎样才能让它更快?

【问题讨论】:

  • 你分析过你的代码吗?瓶颈是什么?在大多数情况下,问题是算法慢而不是代码慢。您正在尝试所有可能的合法举措。 AFAIK 国际象棋引擎使用启发式算法。
  • 另一个重要因素是通过多个移动序列可以到达相同的位置,因此缓存位置分析是有好处的。

标签: python algorithm chess minimax alpha-beta-pruning


【解决方案1】:

实现一个 Negamax 函数而不是 Minimax 将使未来的效率实现更容易开始,它也将使代码看起来更干净:

def negamax(depth, board, alpha, beta, color):
    if depth == 0:
        return evaluation(board)
    leg_moves = board.legal_moves
    for i_move in leg_moves:
        move = chess.Move.from_uci(str(i_move))
        board.push(move)
        value = -negamax(depth - 1, board, -beta, -alpha, -color)
        board.pop()
        alpha = max(alpha, value)
        if beta <= alpha:
            return value
     return value

然后,您可能需要研究一些概念,例如在进入递归函数之前对移动进行排序,因为这样您将更快地获得 beta 截止,并且不必查看那么多移动。然后,您还可以实现例如转置表(具有迭代深化)、空移动和后期移动减少。

您可能还想查看您的移动生成,看看您是否可以使其更快。例如,您使用哪种董事会代表?

我用 Python 制作了一个国际象棋引擎,它根本不是一流的。它在大约 15 秒内进入深度 6,您可以在此处找到代码以获得灵感:Affinity Chess。它使用一维板表示,但位板表示会更快。

我也强烈建议您查看www.chessprogramming.org,那里有很多非常好的信息。

【讨论】:

  • 感谢您的回答。我实现了这个并修复了评估功能。现在,机器人实际上可以进一步深入 1 个深度。谢谢你:)
【解决方案2】:

有许多因素可以使算法快速添加更多国际象棋程序的标准功能。但是你的源代码只有 4 个动作和这么多时间是不正常的。你如何产生动作?您不应该通过 UCI 协议询问它们,而是尝试非常快速地生成它们。特别是不要搜索板上的数字,而是在列表中组织那里的位置,如果它们是从板上取出的,则添加/删除它们。

也许您的评估功能很慢。如果你只关心碎片的值,那么有一个变量来保存颜色的差异,并且只有在拍摄或恢复一块时才更新它。所以评估几乎不需要时间了。

在一个 java 程序中,我在不使用哈希表之类的方法的情况下实现了这些细节,在 4 秒内达到了 7 的深度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多