Python Functions: Tic-Tac-Toe Game

Python Functions: Tic-Tac-Toe Game

Though not related to data analysis or visualization, the very basic Tic-Tac-Toe game I made while leaning was my favorite project so far. My kids and I have have had so much fun playing and enjoyed watching them go from losses to wins and then constantly to ties as they learnt the rules, applied them, and kept track of them. When, I have a chance in the future, I plan to return to this project to retrieve inputs, create profiles, keep historical track of scores, have a better user interface, and add sounds for the kids.

I started first by defining the board on which the game will be played.

board = ["-", "-", "-", 
         "-", "-", "-",
          "-", "-", "-"]

And then, I wrote a parameter that that will be True when the game is ongoing. The will be set to None when the game starts and in a very simplistic way, the first player will always be "X".

# If game is still going
game_still_going = True

# Who Won? Or Tie?
winner = None

# Who's turn is it
current_player = "X"
# When I have a chance to go back to update this project, I will probably use inputs and players' name.

Next, I wrote a function that will display the board. I added a static help guide on the side to display the digits number on the board.

def display_board():
  print("\n")
  print(" | " + board[0] + " | " + board[1] + " | " + board[2] + " | " + "       | 1 | 2 | 3 |")
  print(" | " + board[3] + " | " + board[4] + " | " + board[5] + " | " + " --->  | 4 | 5 | 6 |")
  print(" | " + board[6] + " | " + board[7] + " | " + board[8] + " | " + "       | 7 | 8 | 9 |")
print("\n")

Next, I create the function that will run the game itself.

def play_game():
  display_board() # Display Initial Board

  while game_still_going:
    handle_turn(current_player) # Handle turns between players

    check_if_game_over() # Check if the game has ended

    flip_player() # Flip to the other player
  
  # The game has ended
  if winner == "X" or winner == "O":
    print(winner + " won!")

  elif winner == None:
    print("Oh, oh, that's a tie.")

Next, I defined the handle_turn() function defined in the play_game() function.

def handle_turn(current_player):

  # Get position from player
  print(current_player + "'s turn.")
  position = input("Choose a position from 1-9: ")

  # Whatever the user inputs, make sure it is a valid input, and the spot is open
  valid = False
  while not valid:

    # Make sure the input is valid
    while position not in ["1", "2", "3", "4", "5", "6", "7", "8", "9"]:
      position = input("Choose a position from 1-9: ")
      # The issue with only the if statement is that it asks only once. Error after another wrong input.
      # While loop will go over and over again.
 
    # Get correct index in our board list
    position = int(position) - 1

    # Then also make sure the spot is available on the board
    if board[position] == "-":
      valid = True
      # So we can jump out of the While Loop and proceed to board[position] = current_player
    else:
      print("Sorry, you can't go there. Try again please.")
      # It will go back to the While Loop

  # Put the game piece on the board
  board[position] = current_player

  # Show the game board
  display_board()

Next, I defined the functions that will check whether whether the game is over, either a player win, or there is a tie when all spots are filled with no winner.

def check_if_game_over():
  # Here you call in two other functions
  check_if_win()
  check_if_tie()

def check_if_tie():
  global game_still_going
  # Check if all cells filled with no winner
  if "-" not in board:
    game_still_going = False
  return

def flip_player():
  global current_player

  # Change player after one input their choice
  if current_player == "X":
    current_player = "O"
  elif current_player == "O":
    current_player = "X"
  return

def check_if_win():

  # Set up Global Variable
  global winner

  # Check Rows
  row_winner = check_rows()
  # Check Columns
  column_winner = check_columns()
  # Check Diagonal
  diagonal_winner = check_diagonals()

  if row_winner:
    # There is a win
    winner = row_winner
  elif column_winner:
    # There is a win
    winner = column_winner
  elif diagonal_winner:
    # THere is a win
    winner = diagonal_winner
  else:
    # There is no win
    winner = None
  
  return

Next, I defined the functions to check ways a player can win.

def check_rows():
  # Set up global variables
  global game_still_going

  row1 = board[0] == board[1] == board[2] != "-"
  row2 = board[3] == board[4] == board[5] != "-"
  row3 = board[6] == board[7] == board[8] != "-"

  # End game if win
  if row1 or row2 or row3:
    game_still_going = False
    print("game over!")

  # Get the winner
  if row1:
    return board[0]
  elif row2:
    return board[3]
  elif row3:
    return board[6]
  return

 

def check_columns():
  # Set up global variables
  global game_still_going

  column1 = board[0] == board[3] == board[6] != "-"
  column2 = board[1] == board[4] == board[7] != "-"
  column3 = board[2] == board[5] == board[8] != "-"

  # End game if win
  if column1 or column2 or column3:
    game_still_going = False

  # Get the winner
  if column1:
    return board[0]
  elif column2: 
    return board[1]
  elif column3:
    return board[2]
  return

 

def check_diagonals():
  # Set up global variables
  global game_still_going

  diagonal1 = board[0] == board[4] == board[8] != "-"
  diagonal2 = board[2] == board[4] == board[6] != "-"

  # End game if win
  if diagonal1 or diagonal2:
    game_still_going = False
  
  # Get the winner
  if diagonal1:
    return board[0]
  elif diagonal2:
    return board[2]
  
  return

 

play_game()

 

 

 

 

Tags