Local Scope Issue in Tic Tac Toe game (Python)
<p>I've been learning python for the last couple days and in my book the challenge was to create a tic tac toe program. I think I have a general idea of how to do the game, but I ran into an issue in which insight would be helpful, </p>

<p>Heres the relevant part of my code</p>

<pre><code>   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
</code></pre>

<p><strong>The Error</strong></p>

<pre><code>**UnboundLocalError: local variable 'the_winner' referenced before assignment**
</code></pre>

<p>At first, I did not understand why the line <code>the_winner = current_player</code> gave me an error, then after reading some SO questions like <a href="http://stackoverflow.com/questions/10851906/python-3-unboundlocalerror-local-variable-referenced-before-assignment">Unbound Local Error</a>, I realized my issue.</p>

<p>On my own I thought of two solutions. </p>

<p><strong>My attempt</strong></p>

<p><strong>1.</strong> Make <code>the_winner</code> global. This way I wouldn't have an issue with setting the winner for the winning column to the current player. The reason I don't want to do this, is because I recall people saying during my research on this error, that  it is very bad practice to use the keyword <code>global</code>, and thus I do not really want to use it.</p>

<p><strong>2</strong>. inside the function add a parameter for <code>the_winner</code>. But the problem with this idea, is that how I would access <code>the_winner</code> outside of the function itself. This would create <code>the_winner</code> inside the <code>check_win_col()</code> local scope, and I would not be able to manipulate this outside of the function, if I for some reason needed to. Plus the idea of adding a parameter to a function for checking the column winner seems odd. It seems like its one of those functions that should just be parameter-less if you will.</p>

<p>Is there a better solution I am missing? Sorry if this question seems trivial.</p>

<p>The issue with your function is not on the line you say gives an error, but rather on the line where you <code>print</code> or <code>return</code> the variable <code>the_winner</code>. That variable may not have been set in the loop, since the (buggy!) condition you're checking is not always be true.</p>

<p>There are a few options for how you can deal with that possibility. One might be to initialize the <code>the_winner</code> local variable in the function before starting the loop. <code>None</code> is often a reasonable default value for a variable that may or may not get changed.</p>

<pre><code>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
</code></pre>

<p>Putting the <code>return</code> statement in the loop (as suggested by Skirrebattie) is almost exactly the same as this, since <code>None</code> is the default return value for functions in Python. If the condition is never met in the code in the other answer, the function will return <code>None</code> after it reaches the end of its code.</p>

<p>A final note about the condition you're checking. It doesn't make any sense! Currently you're checking if any value in the first column matches any value in the first row and is not a space. That's not a very relevant condition for winning Tic-Tac-Toe. You probably want something different (though I'm not exactly sure what).</p>

python