Python Forum
Python Tic Tac Toe with Functions
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python Tic Tac Toe with Functions
Hi all,

I have written a Python Tic Tac Toe game with functions for 2 players on a shared keyboard. I am interested in feedback. It works well, but I am interested in proper scoping of variables ? Have I used functions in a correct way and anything else is highly appreciated. I am learning how to code, however I want to do it in the correct way. I am not up to classes yet. That will be my next project.

Thank you



# Display welcome and instructions 
# Display board 
# Who gets X or O ?
# While no one has won and it isn't a tie loop 
    # get player's move X or O
    # Update the board with the new move 
    # and check legal move, so move that hasn't been taken
    #Switch Turns into X or O
#Congratulate Winner X or O or say it's a Tie

def display_welcome():
    """Display Welcome to Tic Tac Toe """
        Hi and welcome to this Tic Tac Toe game_board.
        You can win by haveing three X or 3 O in a row.
        This can be horizontal, vertical or diagonal

def display_board(game_board):
    """display the board"""
    for x in range(3):
        print("+---+---+---+" )
        for y in range(3):
            print("|", game_board[x*3+y], end = " ")
    print("+---+---+---+" )

def determine_pieces():
    """Determine who gets X or O"""
    answer = None
    answer = input("Do you wish to start with X or O ").upper()
    while not answer in ['X','O']:
        answer = input("Sorry this needs to be X or O ").upper()
    return answer

def determine_winner(game_board):
    """check if there is a win, draw"""
    # check rows
    for i in range(3):
        if game_board[i*3] == game_board[i*3+1] == game_board[i*3+2] and game_board[i*3] in ('X', 'O'):
            return game_board[i*3]
    # check columns
    for i in range(3):
        if game_board[i] == game_board[i+3] == game_board[i+6] and game_board[i] in ('X', 'O'):
            return game_board[i]
    # check diagonals
    if game_board[0] == game_board[4] == game_board[8] and game_board[0] in ('X', 'O'):
        return game_board[0]
    if game_board[2] == game_board[4] == game_board[6] and game_board[2] in ('X', 'O'):
        return game_board[2]
    # check tie
    if all(x in ('X', 'O') for x in game_board):
        return 'Tie'
    # no winner or tie
    return False

def get_move(game_board):
    """ Get the player's move """
    move = int(input(" Please make a move between 1 and 9 "))
    while not legal_move(game_board,move):
        move = int(input( " That move is not legal try again "))
    return move

def legal_move(game_board,player_move):
    """Check if the move is legal"""
    legal = True
    if game_board[player_move -1] in ['X','O']:
        legal = False
    return legal
def modify_board(game_board,user_piece,move):
    """ Modify the board positions into X or O"""
    game_board[move - 1] = user_piece
def switch_turns(user_piece):
    """ Change player's piece into X or O"""
    if user_piece == 'X':
        user_piece = 'O'
        user_piece = 'X'
    return user_piece 

def win_or_tie(user_piece):
    """ display win for X or O or a tie"""
    if user_piece == "TIE":
        print("This is a TIE, but feel free to play again")
        print(f"Yes the player with {user_piece} won !!" )

def main():
    """ game_board starting point """
    game_board = [1,2,3,4,5,6,7,8,9]
    player_turn = None
    player_turn = determine_pieces()
    print(f"ok you start with {player_turn}")

    while not determine_winner(game_board):
        player_move = get_move(game_board)
        if not determine_winner(game_board):
            player_turn = switch_turns(player_turn)


if __name__ == "__main__":
Well, you have covered many basic aspects of Python including exploring new concepts.
Second thing that I want to say that you have also cleary used all function very effectively.
Observer all code deely, nice information at all.
1. Move variables that do not change to the global scope as constants.
2. Avoid DRYness (note that you are repeating variables like "+---+---+---+"
3. Removed unused declaration (this is not C), (as example see answer=None)
4. Consider using a class instead of passing the game_board as param
5. If you really need to pass a list (like game_board) consider using a copy of
it (is passed by ref and this can have side effects)
5. Consider a more concise style (see how legal_move can be simplified)
6. Your logic can be simplified
7. Write some unit tests

Forum Jump:

User Panel Messages

Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020