gpt4 book ai didi

python - 国际象棋 negamax 函数

转载 作者:太空宇宙 更新时间:2023-11-03 11:08:41 31 4
gpt4 key购买 nike

嗨!

我正在尝试为我的国际象棋引擎编写一个 negamax 搜索算法,但我似乎无法让它工作。我以 wikipedias 伪代码为例,但不知何故它没有产生预期的结果。当我用 2 层运行它时,它改变了我的板数据结构,尽管它不应该。在第 2 层函数完成运行后,所有白棋(或黑棋。取决于玩家对函数的称呼。)棋子从起始位置向前移动 2 个空格。

我的 make 和 unmake 移动函数运行良好,因为我使用最多搜索 5 层的非递归函数测试了它们。然后,它完美地工作。我的 negamax 实现一定有问题。

非常感谢您的帮助!

def negaMax(self, board, rules, ply, player):
""" Implements a minimax algorithm. """
if ply == 0:
return self.positionEvaluation()

self.max_eval = float('-infinity')

self.move_list = board.generateMoves(rules, player)
for self.move in self.move_list:
board.makeMove(self.move, player)
self.eval = -self.negaMax(board, rules, ply - 1, board.getOtherPlayer(player))
board.unmakeMove(self.move, player)

if self.eval > self.max_eval:
self.max_eval = self.eval

return self.max_eval

最佳答案

这里的主要问题是我相信使用对象变量而不是局部变量。

self.move 是一个对象变量,每次更改它时 - 递归的每个级别都“看到”更改,这对于递归来说通常是一件坏事算法。

递归算法应该是自包含的,并且即使对调用环境有任何改变也应该做到最小 - 这使得遍历算法流程变得更加容易。

我在这段代码中看到的两个主要问题是:

  1. self.move 应该是一个本地 变量(声明为move)。当您稍后执行以下操作时:board.unmakeMove(self.move, player) - 我怀疑棋盘正在撤消另一个移动,该移动在递归树中设置得更深,而不是您想要的移动。使用局部变量将消除这种不良行为。
  2. 递归调用的每个级别都在设置 self.max_eval = float('-infinity') - 因此您可以不断更改它,尽管这可能不是您想要的。

解决方案应该是这样的:

def negaMax(self, board, rules, ply, player):
""" Implements a minimax algorithm. """
if ply == 0:
return self.positionEvaluation()

max_eval = float('-infinity')

move_list = board.generateMoves(rules, player)
for move in move_list:
board.makeMove(move, player)
currentEval = -self.negaMax(board, rules, ply - 1, board.getOtherPlayer(player))
board.unmakeMove(move, player)

if currentEval > max_eval:
max_eval = currentEval
return max_eval

我不是 100% 确定它确实会解决代码中的所有问题(但它会解决部分问题)但我 100% 确定避免对象变量会使您的代码更容易理解和调试。

关于python - 国际象棋 negamax 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12343298/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com