2017-05-24 35 views
0

教育目的のために、私はPythonでtic tac toeゲームを実装しています。Python:再帰関数内での戻りでの問題

選手のXまたはOを設定している関数は再帰的である:

def set_marker(player,board): 
    print "\nplayer",player 

    x = y = 3 
    while(x not in range(0,3)): 
     x = input("x: ") 
    while(y not in range(0,3)):  
     y = input("y: ") 

    if board[x][y] == 0: 
     board[x][y]=player 
     return board 
    else: 
     set_marker(player,board) 
     # return board 

パラメータ:

board = 2dimensional list ([[0, 0, 0], [0, 0, 0], [0, 0, 0]]) 
player = int (value = '1' or '2') 

私が呼んでいる、既に使用されているフィールドに私の「X」を設定した場合再び機能する。 このケースが起こると私は再び、スクリプトは次のエラーを投げている私のメインループ内で「ボード」を使用していた場合:

Python: TypeError: 'NoneType' object has no attribute '__getitem__' 

ボードのタイプがこの場合にありますnoneboardelse:部分にも返すだけで問題を解決しました。ここで

は私の質問に行く:私は適切なボードを返すまで、私は、関数を呼んでいるよう

は、なぜ私は、他の中にもボードを返さなければならないのですか?

答えて

2
set_marker(player,board) 

は次のようになります。

return set_marker(player,board) 

そうでないあなただけの再帰的に結果を通過せずに呼び出しました。それがelseに入る最初の繰り返しでは、set_markerを呼び出し、それはboardを返すことがあります。その時点で、外部呼び出しは何も返さずに終了するので、TypeErrorです。

それは再帰を使用しないように、おそらくより良いですが:

def set_marker(player,board): 
    print "\nplayer",player 

    x = y = 3 
    while(x == 3 or board[x][y] != 0): 
     while(x not in range(0,3)): 
      x = input("x: ") 
     while(y not in range(0,3)):  
      y = input("y: ") 

     if board[x][y] == 0: 
      board[x][y]=player 
      return board 
+0

ありがとう、私はそれを再帰関数にしていない場合は、私の戻り値はもはやない右まで、関数を呼び出す間にループを作るだろうか? –

0

私は、次の構文期待:あなたはif文の最初の部分になり電話をかけるとき

else: 
     return set_marker(player,board) 

を、それは 'board'を返しますが、戻り値はコールチェーンを介して伝播する必要があります。再帰呼び出しで見つかった値をelseブロックから戻さないと、何も返されません。