pythontic-tac-toeglobal-scope

Why am I not changing the global scope the way I thought


I guess my problem has to do with global scope. I'm not sure what it is that I am not understanding. I have computer_symbol defined in the global scope in line 6. Then the choose_symbol function on line 18 should be making the computer_symbol whatever the user doesn't choose. Then I call the function in line 30. But when I try to use the variable in line 45 and test my code, I see that computer_symbol still equals the 'nothing' value that was only ever meant as a placeholder.

import random


board_locations = [0, 1, 2, 3, 4, 5, 6, 7, 8]

computer_symbol = 'nothing'

def draw_board():
    print('   |   |   ')
    print(f'_{board_locations[0]}_|_{board_locations[1]}_|_{board_locations[2]}_')
    print('   |   |   ')
    print(f'_{board_locations[3]}_|_{board_locations[4]}_|_{board_locations[5]}_')
    print('   |   |   ')
    print(f' {board_locations[6]} | {board_locations[7]} | {board_locations[8]} ')
    print('   |   |   ')


def choose_symbol(user_symbol):
    if user_symbol == 'X':
        computer_symbol = 'O'
    else:
        computer_symbol = 'X'

    return computer_symbol


draw_board()

user_symbol = input("Would you like to be 'X' or 'O': ")
choose_symbol(user_symbol)

game = True

while game:
    draw_board()

    chosen_location = int(input('Choose the location you want to move on the board: '))
    if chosen_location in board_locations:
        board_locations.pop(chosen_location)
        board_locations.insert(chosen_location, user_symbol)
        draw_board()
        computer_choice = random.choice(board_locations)

        board_locations.pop(computer_choice)
        board_locations.insert(computer_choice, computer_symbol)

At first, I didn't even have the computer_symbol variable because I thought that I could do that in the function choose_symbol() but the program didn't like that because computer_symbol hadn't been defined.


Solution

  • The computer_symbol variable that you use inside the function is a local variable inside the function, so it is not the same as the global computer_symbol variable. To change that, you could explicitly reference the global variable inside the function by adding the statement global computer_symbol at the top of the function body.

    However, judging from the code you show, it is not necessary to have your function change the global variable here. In general, it's better to avoid such side effects if you can. Just delete the computer_symbol = 'nothing' assignment and assign the function's return value instead:

    computer_symbol = choose_symbol(user_symbol)