2016-09-05 12 views
0

私は最後のカップルの日のためにPythonを学んできました。私の本では、ティックタックトープログラムを作成することが課題でした。私はゲームを行う方法の一般的な考えを持っていると思うが、私は洞察力が参考になるここで問題に遭遇した、Tic Tac Toeゲーム(Python)のローカルスコープの問題

HERESに私のコードの関連部分

board = [] 
for i in range(0,3): 
    board.append([" "," "," "]) # Fill the board 

def print_board(): 
    for i in range(0,3): 
     print "| ", 
     for k in range(0,3): 
      print board[i][k], 
     print "|\n" 

print "The first player to start will be player one with X\n, the second player will be O\n" 
player_one = "X" 
player_two = "O" 
current_player_name = "Player One" 
current_player = player_one 
filled_board = False 
winner = False 

def check_win_col(the_winner): 
    for i in range(0,3): 
     for j in range(0,3): 
      if board[0][i] == board[j][0] and board[0][i] != " ": 
       the_winner = current_player 
    return the_winner 




while(filled_board == False): 
    get_row = int(raw_input("Please enter which row you would like to move to " + current_player)) 
    get_col = int(raw_input("Please enter the col you want to move to" + current_player)) 
    board[get_row][get_col] = current_player 
    print_board() 
    check_win_col() 
    if current_player == player_one: 
     current_player = player_two 
    else: 
     current_player = player_one 

エラー

まず
**UnboundLocalError: local variable 'the_winner' referenced before assignment** 

、ラインthe_winner = current_playerは私にエラーを与えた理由を私は理解していなかった、そしてUnbound Local ErrorのようないくつかのSOの質問を読んだ後、私は私の問題を実現。

私自身は2つの解決策を考えました。

私の試み

1.the_winnerが世界ください。この方法では、私は現在の選手に優勝欄の勝者を設定することに問題はありません。私がこれをしたくない理由は、このエラーに関する私の研究中に、globalというキーワードを使用することは非常に悪い習慣であると言っている人々を思い出しているからです。

。関数内にthe_winnerのパラメータを追加します。しかし、このアイデアの問題は、私がどのようにしてthe_winnerにアクセスするのかということです。これにより、check_win_col()ローカルスコープ内にthe_winnerが作成されます。何らかの理由でこの関数の外でこれを操作することはできません。さらに、列の勝者をチェックするための関数にパラメータを追加するというアイデアは奇妙に思えます。それはあなたが望むならば、パラメータなしでなければならないその機能の1つのようです。

もっと良い解決策がありますか?申し訳ありませんが、この質問が簡単な場合。

+0

関数の外で "the_winner"にアクセスする必要がある場合は、関数の最後に関数を返し、関数を呼び出すときに関数を保存することができます。 – Tryph

+1

あなたは 'return'という言葉を知らないように見えます。 – polku

+0

あなたはどこでthe_winnerを使用していますか?あなたの関数は 'check_win_col'と呼ばれますが、他に2つのことがあります。関数の外部で状態を変更し、勝者を出力します。私はこの関数を単純に勝利した 'current_player'を返すように提案し、あなたが関数を呼び出すところでそれを使用してください。 –

答えて

0

勝者を返すのはどうですか?この線に沿って何か:

player_one = "X" 
player_two = "O" 
current_player_name = "Player One" 
current_player = player_one 
filled_board = False 
winner = False 

def check_win_col(): 
    for i in range(0,3): 
     for j in range(0,3): 
      if board[0][i] == board[j][0] and board[0][i] != " ": 
       return current_player # Current player wins, so return it. 

the_winner = check_win_col() 
print the_winner 
1

問題あなたの関数とは、あなたがエラーを与えると言うライン上ではなく、あなたprintまたはreturn変数the_winnerライン上にありません。その変数はループ内に設定されていないかもしれません。なぜなら、チェックしている(バグ!)状態が常に真ではないからです。

この可能性にどのように対処できるかについては、いくつかの選択肢があります。ループを開始する前に、関数のローカル変数the_winnerを初期化することがあります。 Noneは、変更される可能性のある、または変更されない可能性がある変数にとって、しばしば妥当なデフォルト値です。 (Skirrebattieにより示唆されるように)ループ内でreturn文を置く

def check_win_col(): 
    the_winner = None # set a default value for the variable unconditionally 
    for i in range(0,3): 
     for j in range(0,3): 
      if board[0][i] == board[j][0] and board[0][i] != " ": 
       the_winner = current_player # this *may* modify it, if the condition was met 
    return the_winner # this will work always, not only if the loop modified the variable 

Noneは、Pythonでの関数のデフォルトの戻り値であることから、ほぼ正確にこれと同じです。条件が他の答えのコードで決して満たされない場合、関数はコードの最後に達した後にNoneを返します。

あなたが確認している状態についての最後のメモ。それは意味をなさない!現在、最初の列の値が最初の行の値と一致し、空白ではないかどうかを確認しています。それはTic-Tac-Toeを獲得するための非常に関連した条件ではありません。あなたはおそらく何か異なるものを望んでいるでしょう(私は確かに何かを確信していません)

+0

これは完璧です!ありがとう、私は何をすべきか私の頭を叩いていた! – bill

+0

うんうん、私の状態は意味をなさない、私はいくつかのアイデアを持っているが、私はここから何をすべきか知っていると思う – bill