我有点理解minimax算法是如何为Tic Tac Toe python工作的,但我不知道如何用python编写它。。。这就是我目前所拥有的:
from copy import deepcopy
class TicTacToeBrain :
def __init__(self, player = "x") :
self._squares = {}
self._copySquares = {}
self._winningCombos = (
[0, 1, 2], [3, 4, 5], [6, 7, 8],
[0, 3, 6], [1, 4, 7], [2, 5, 8],
[0, 4, 8], [2, 4, 6])
def createBoard(self) :
for i in range(9) :
self._squares[i] = None
print(self._squares)
def showBoard(self) :
print(self._squares[0], self._squares[1], self._squares[2])
print(self._squares[3], self._squares[4], self._squares[5])
print(self._squares[6], self._squares[7], self._squares[8])
def getAvailableMoves(self) :
self._availableMoves = []
for i in range(9) :
if self._squares[i] == None :
self._availableMoves.append(i)
return self._availableMoves
def makeMove(self, position, player) :
self._squares[position] = player
self.showBoard()
def complete(self) :
if None not in self._squares.values() :
return True
if self.getWinner() != None :
return True
return False
def getWinner(self) :
for player in ("x", "o") :
for combos in self._winningCombos :
if self._squares[combos[0]] == player and self._squares[combos[1]] == player and self._squares[combos[2]] == player :
return player
if None not in self._squares.values() :
return "tie"
return None
def getEnemyPlayer(self, player) :
if player == "x" :
return "o"
return "x"
def minimax(self, node, player, depth = 0, first = True) :
if first :
best = 0
self._copySquares = deepcopy(self._squares)
if node.complete() :
if node.getWinner() == "x" :
self._squares = self._copySquares
return -1 - depth
elif node.getWinner() == "tie" :
self._squares = self._copySquares
return 0
elif node.getWinner() == "o" :
self._squares = self._copySquares
return 1 + depth
best = None
for move in node.getAvailableMoves() :
depth += 1
node.makeMove(move, player)
print()
val = self.minimax(node, node.getEnemyPlayer(player), depth, first = False)
print(val)
if player == "o" :
if val > best :
best = val
else :
if val < best :
best = val
return best
print()
print()
def printCopy(self) :
print(self._copySquares)
然而,它从来没有打印出所有的场景…有人请帮忙!!!这是星期一的一个项目。。
一些问题:
在第一次迭代时,执行从带有
return
的for
循环中断:这还为时过早,因为您永远无法测试任何其他可用的移动。循环后return
应该发生在之后。在循环的每次迭代中增加深度值是错误的。相反,将
depth+1
传递给递归调用,这样当您从该调用返回时,就可以以相同的深度继续。在递归调用之前完成的移动必须在调用之后立即收回,否则
for
循环的下一次迭代将不会从同一位置开始。best
的值需要在minimax方法的每个调用处初始化,而不仅仅是在递归树的顶部。此初始值不应为0,因为当前用户的最佳值可能小于0。所以你需要将它初始化为一个极坏的值。minimax方法不返回最佳移动,只返回计算值。因为这个方法的全部目的是告诉你应该玩哪一步,所以你需要两者兼得。因此,让该方法返回一个包含两个值的元组:求值值值和生成该值的移动。
一些非关键问题:
当你想要延迟一个不可避免的失败,或者加速一个强制的胜利时,计算一个玩家获胜时的值的公式应该越远越接近0,而不是越近。所以这个公式需要改变。
因为你应该通过向后移动来恢复棋盘,所以不需要使用复制的棋盘和复制的方块。如果所有的代码都很好,那么在minimax方法的top调用完成之后,电路板的状态应该与该调用之前完全相同。
如果不使用
None
作为空方块,而是使用单个字符(如“.”),则电路板的打印效果会更好。所以在你提到空方块值的地方,放上这个字符。为了分离输出,这里和那里都有
print()
。在方法showBoard
中放一个,剩下的代码就可以不用它们了。考虑到以上几点,您不需要
node
或first
参数到minimax
方法。这是一个评论,更正版本。我把你原来的台词放在原处,但在需要的地方注释掉了。
下面是一个关于如何使用该类的示例:
看它在eval.in上运行。。。等等。
有些事情你还可以改进
我不会提供代码,但您可以:
跟踪轮到谁了。这样你就不必把玩家当作参数传递给minimax,这样可以避免错误。同时,它也使构造函数参数变得有用——目前您对它什么也不做。
添加一个方法
bestMove
,该方法只调用minimax
,但只返回最佳移动,而不返回值。这将更容易管理。使用alpha-beta剪枝,这样就可以停止计算其他移动,如果很明显不能提高递归树中已经获得的值。
相关问题 更多 >
编程相关推荐