通过递归函数调用传递的空dict被视为"NoneType"



我有一个递归函数,机器人正在使用它来玩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。

相关内容

  • 没有找到相关文章

最新更新