【发布时间】: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 似乎在工作并下出良好有效的动作。
问题
我不知道出了什么问题,也不知道这是否是正确的方法。非常感谢任何指导!
【问题讨论】: