0

just starting out with programming (first post on stack overflow), and working my way through the most basic stuff in Python. I try to complete as many exercises as possible to better my understanding on how it all works.

The latest exercise was to make the game Tic Tac Toe. I finally got the code working after a lot of googling, but I'm not sure what I missed in regards to local variables used as arguments to my function 'draw()'. As you can see from the first lines of my code, I had to import the module copy and use copy.deepcopy() to define a local variable inside this function from the list 'board'.

The function 'draw()' is called from 'play_game()', but without making a copy of the list variable 'board' I ended up with overriding this list for all other functions. This resulted in errors in all other parts of the program.

What did I miss? Any other comments to my code is most welcome.

import copy
def draw(board):
    #Draws the board game and converts numbers from game board list to X and O's
    print()
    bo = copy.deepcopy(board)
    for i in range(3):
        for b in range(3):
            if bo[i][b] == 1:
                bo[i][b] = "X"
            elif bo[i][b] == 2:
                bo[i][b] = "O"
            else:
                bo[i][b] = " "
    for i in range(3):
        print(" ---" * 3)
        print("| %s | %s | %s |" % (bo[i][0], bo[i][1], bo[i][2]), end="\n")
    print(" ---" * 3)

def winner(board):
    # Checkis if there's a diagonal winner
    if (board[0][0] == board[1][1] == board[2][2]) and board[1][1] != 0:
        return board[1][1]
    elif (board[0][2] == board[1][1] == board[2][0]) and board[1][1] != 0:
        return board[1][1]
    else:
        for i in range(3):
            #Checks if there's a winner in a row
            if (board[i][0] == board[i][1] == board[i][2]) and board[i][i] != 0:
                return board[i][i]
            #Checks if there's a winner in a column
            elif (board[0][i] == board[1][i] == board[2][i]) and board[i][i] != 0:
                return board[i][i]
    return 0

def player_input(board, turn):
    print("Enter a coordinate (row,column) for your choice, eg. '2,3'")
    while True:
        player = input("Player " + str(turn) + ": ")
        try:
            cor = player.split(",")
            row = int(cor[0]) - 1
            col = int(cor[1]) - 1
            if board[row][col] == 0:
                board[row][col] = turn
                return board
            else:
                print("This space is allready occupied, please choose another coordinate.")
        except:
            print("Your choice raised an error, please try again.")

def play_again():
    play = input("This was fun! Play again? (y/n): ")
    if play == "y":
        return True
    else:
        return False

def player_turn(turn):
    # Returns what player is to go next
    if turn == 1:
        return 2
    else:
        return 1

def play_game():
    # This method run all other functions in a single gameplay, and exits when the game is over
    # Set all initial variables used in a new game
    game = [[0,0,0],[0,0,0],[0,0,0]]
    turn = 1
    count = 0
    win = 0
    while True:
        draw(game)
        game = player_input(game, turn)
        count += 1
        win = winner(game)
        if count == 9 and win == 0:
            print("It's a draw!")
            return
        elif win != 0:
            print("Player " + str(win) + " won!")
            return
        turn = player_turn(turn)

if __name__ == "__main__":
    ''' This is the game Tic, Tac, Toe. When run as a standalone script the game will
        be initialized from the main method. When game is over the user will be prompted
        to play again... '''
    print("\n\n" + "----------     WELCOME TO TIC, TAC TOE. LET'S PLAY!     ----------\n\n")
    play = True

    while play:
        play_game()
        play = play_again()
Inge
  • 1
  • 1
  • Lists are given by ref into the function, if you change them there, the changes reflect outside as well. deepcopy() copys thedata of your board your list of lists into bo that you then modify without sideeffects as it is a distinct list of list - ref-wise. working code and code for optimization goes to codereview.stackexchange.com, not SO. – Patrick Artner Jan 30 '18 at 20:35
  • Thanks, I actually read the other post, but somewhat missed the point after all. Will go to codereview.stackexchange.com with working code from now on, thanks for the heads up. – Inge Jan 30 '18 at 20:46

0 Answers0