2017-11-18 16 views
0

私は、ボットがConnect Fourのゲームをプレイするために使用する再帰関数を持っています。関数内で何が起きているのか、それはモンテカルロの検索を使用して統計的に最良の勝利をもたらす次の動きを選択します:すべての可能な動きのうちの割合を失う再帰関数呼び出しを通過する空のdictが `NoneType`とみなされています

しかし、この情報は私の問題には必要ありません。私の再帰関数は、空の辞書{}が呼び出されたときにそのパラメータの1つとして使用されます。この辞書は、ゲームの終わりに達するまで各再帰呼び出しに渡されます。この時点で、ディクショナリが変更されて返されるため、このディクショナリはすべての再帰呼び出しを通過し、最終的には関数の最初の呼び出しまで戻ってきます。辞書の各キーはクラスCellのインスタンスであり、各値は整数の長さ2のリストです。

空のdictで再帰関数を呼び出すとき、ゲームの終わりに達した最初の点で、最初ののキーと値のペアをdictに追加する必要があります。 、キーがすでに辞書に存在するかどうかを確認するif文があります。私は、エラーをgetttingています。この時点で

:ここ

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 

答えて

3

あなたの機能の最後に。再帰呼び出しから値が返されないコードパスがあり、暗黙のNoneが返されます。例えば

if (cell.value == empty or cell.value == blocked) and (cell.row == 0 or cellBelow.value != empty):

がためのループ内のセルのいずれかのTrueに評価されないとき、これは起こります。

+0

ああ私は、関数を最後の行に 'return winRatios'を追加するだけで問題を解決しました。ありがとうございました。 – KOB

+0

助けになるのはうれしい!これがあなたのために働いた場合、答えを「受け入れ」とマークしてください。 :) –

+0

はい、私は別の5分を待たなければならないと言います、それをやるでしょう! – KOB

関連する問題