我有一个递归函数,机器人正在使用它来玩Connect Four游戏。为了让你对函数中发生的事情有一个基本的了解,它使用蒙特卡罗搜索来选择下一个动作,从所有可能的动作中统计出最佳的输赢率
然而,对于我的问题,这些信息都不是必需的。我的递归函数在第一次调用时将一个空字典{}
作为其参数之一。这个字典被传递到每个递归调用中,直到游戏结束。此时,字典将被修改并返回,因此该字典将通过所有递归调用传递,并最终返回到函数的初始调用。字典的每个键都是我的类Cell
的一个实例,每个值都是长度为2的整数列表。
当我最初用一个空dict调用递归函数时,在游戏结束的第一点,我需要向dict添加第一个Cell
-[int, int]
键值对,在这样做的过程中,我有一个if语句来检查该键是否已经存在于字典中。
在这一点上,我得到了错误:
in __MonteCarloSearch
if startingCell in winRatios:
TypeError: argument of type 'NoneType' is not iterable
这是我的代码,我已经评论了导致错误的行:
def getMove(self, prompt, grid):
winRatios = self.__MonteCarloSearch(grid, True, {}, None)
bestCell = [None, None]
for cell, ratio in winRatios.items():
if ratio[0] / ratio[1] > bestCell[1]:
bestCell = Cell
return cell.colLabel
def __MonteCarloSearch(self, grid, myMove, winRatios, startingCell): # COUNT NUM SEQUENCE SIMULATED
for cell in grid:
if startingCell is None:
startingCell = cell
cellBelow = None
if cell.row > 0:
cellBelow = grid.getCellFromLabel(cell.colLabel + rowLabels[cell.row - 1])
if (cell.value == empty or cell.value == blocked) and (cell.row == 0 or cellBelow.value != empty):
testGrid = deepcopy(grid)
if myMove:
testGrid.placeChip(cell.colLabel, self.chip)
else:
testGrid.placeChip(cell.colLabel, chips[(chips.index(self.chip) + 1) % len(chips)])
gameWon, gridFull = testGrid.gameOver()
if gameWon and myMove:
if startingCell in winRatios: # ERROR PRODUCED HERE
winRatios[startingCell] = [winRatios[startingCell][0] + 1, winRatios[startingCell][1] + 1]
else:
winRatios[startingCell] = [1, 1]
return winRatios
if (gameWon and not myMove) or gridFull:
if startingCell in winRatios: # ERROR PRODUCED HERE
winRatios[startingCell] = [winRatios[startingCell][0], winRatios[startingCell][1] + 1]
else:
winRatios[startingCell] = [0, 1]
return winRatios
winRatios = self.__MonteCarloSearch(testGrid, not myMove, winRatios, startingCell)
此外,我已经将线路更改为if winRatios and startingCell in winRatios
,但随后收到类似的错误:
in __MonteCarloSearch
winRatios[startingCell] = [0, 1]
TypeError: 'NoneType' object does not support item assignment
您需要在函数末尾返回winRatios
。有些代码路径不会从递归调用返回winRatios
值,最终返回隐式None。
例如,当
if (cell.value == empty or cell.value == blocked) and (cell.row == 0 or cellBelow.value != empty):
对于for循环中的任何单元格,计算结果均不为True。