问题描述
背景
我正在尝试针对下象棋优化我的minimax算法,并且到目前为止已经使用了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,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,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处进行计算时,将从calc相同的位置开始再次进行黑色的有效移动,这似乎是不必要的操作,因为我已经在上一个循环中进行了此操作。因此,我应该能够从表中保存的valid_moves中检索到此信息。
我已经使用zobrist散列来获得每个位置的几乎唯一的数字,并尝试在我的minimax函数中像这样使用它:
# Minimax
def minimax(gamestate,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)
......
由于某种原因,引擎做出了完全不合理的动作,这在当前位置是不合法的,而且似乎不起作用。
我尝试过的事情
我已经检查过:
问题
我无法弄清楚出了什么问题,如果这是正确的解决方法,那么我将无法确定。任何指导都将受到高度赞赏!
解决方法
您不能假设引擎对较浅深度所做的评估是准确的,因为位置可能会改变下一步的移动,例如简单地捕获您的皇后。这就是为什么您可以进行移动排序并首先从表中的先前迭代中计算最有希望的移动,而不是根本不计算先前搜索的移动,并且通常情况下,alpha-beta 修剪将使这比仅从搜索中搜索更快固定深度。