Tic tac toe game in Python

Do not miss this exclusive book on Binary Tree Problems. Get it now for free.

In this article, we have presented how to develop the classic Tic Tac Toe game project in Python Programming Language. This will be a strong addition to Software Developer Portfolio.

What is Tic-Tac-Toe ?

Tic tac toe, also known as noughts and crosses or Xs and Os, is a simple strategy game for two players. It is played on a 3x3 grid, and each player takes turns placing their symbol (either an X or an O) on an empty space on the grid. The first player to get three of their symbols in a row (horizontally, vertically, or diagonally) wins the game. If all of the spaces on the grid are filled and no player has won, the game is a draw.

To play the game, the players take turns choosing a space on the grid and marking it with their symbol. The player who goes first typically uses X, while the second player uses O. The game continues until one player gets three of their symbols in a row or all of the spaces on the grid are filled.

The conditions that can occur in a game of tic tac toe are :

  1. Win: If a player gets three of their symbols in a row (horizontally, vertically, or diagonally), they win the game.

  2. Draw: If all of the spaces on the grid are filled and no player has won, the game is a draw.

  3. Unfinished game: If the game is not over and there are still empty spaces on the grid, the game is considered unfinished. Players can continue to take turns until one player wins or the game ends in a draw.

  4. Illegal move: If a player tries to make a move on a space that is already occupied, it is considered an illegal move and the turn passes to the other player.

  5. Stalemate: A stalemate occurs when both players are unable to win, even if they make optimal moves. This can happen if the players are evenly matched and play defensively, blocking each other's attempts to get three in a row.

The Design Elements of a tic tac toe are :

To design a Tic-Tac-Toe game in Python, you will need to consider the following elements:

1) Board: You will need to create a board with a 3x3 grid to represent the Tic-Tac-Toe game. Each cell in the grid can be either empty or occupied by a player's piece (either an "X" or an "O").

2) Players: You will need to implement a way for two players to take turns placing their pieces on the board.

3) Game loop: You will need to create a game loop that continues until the game is won by one of the players or the game ends in a draw.

4) Winning conditions: You will need to implement a way to determine if one of the players has won the game by getting three of their pieces in a row (horizontally, vertically, or diagonally).

5) User input: You will need to allow the players to input the coordinates of the cell where they want to place their piece.

6) Displaying the board: You will need to implement a way to display the current state of the board to the players, so they can see the positions of the pieces.

7) Error handling: You will need to handle cases where the players try to place their pieces in invalid locations or make other invalid moves.

This is a sample design code for tic tac toe :

board = [[" " for _ in range(3)] for _ in range(3)]

def draw_board():
  print("  0 1 2")
  for i, row in enumerate(board):
    print(i, " ".join(row))

def get_move(player):
  while True:
    col = input(f"{player}, enter column: ")
    row = input(f"{player}, enter row: ")
    if col.isdigit() and row.isdigit():
      col, row = int(col), int(row)
      if 0 <= col < 3 and 0 <= row < 3:
        if board[row][col] == " ":
          board[row][col] = player
          return
        else:
          print("That space is already occupied. Try again.")
      else:
        print("Invalid move. Try again.")
    else:
      print("Invalid input. Try again.")

def has_winner():
  # check rows
  for row in board:
    if row[0] == row[1] == row[2] and row[0] != " ":
      return True
  # check columns
  for col in range(3):
    if board[0][col] == board[1][col] == board[2][col] and board[0][col] != " ":
      return True
  # check diagonals
  if board[0][0] == board[1][1] == board[2][2] and board[0][0] != " ":
    return True
  if board[2][0] == board[1][1] == board[0][2] and board[2][0] != " ":
    return True
  return False

def main():
  while True:
    draw_board()
    get_move("X")
    if has_winner():
      print("X wins!")
      break
    draw_board()
    get_move("O")
    if has_winner():
      print("O wins!")
      break

main()

Output :

Another version of tic tac toe where one player is the computer looks like :

import random

board = [[" " for _ in range(3)] for _ in range(3)]

def draw_board():
  print("  0 1 2")
  for i, row in enumerate(board):
    print(i, " ".join(row))

def get_human_move():
  while True:
    col = input("Enter column: ")
    row = input("Enter row: ")
    if col.isdigit() and row.isdigit():
      col, row = int(col), int(row)
      if 0 <= col < 3 and 0 <= row < 3:
        if board[row][col] == " ":
          board[row][col] = "X"
          return
        else:
          print("That space is already occupied. Try again.")
      else:
        print("Invalid move. Try again.")
    else:
      print("Invalid input. Try again.")

def get_computer_move():
  while True:
    col = random.randint(0, 2)
    row = random.randint(0, 2)
    if board[row][col] == " ":
      board[row][col] = "O"
      return

def has_winner():
  for row in board:
    if row[0] == row[1] == row[2] and row[0] != " ":
      return True
  for col in range(3):
    if board[0][col] == board[1][col] == board[2][col] and board[0][col] != " ":
      return True
  if board[0][0] == board[1][1] == board[2][2] and board[0][0] != " ":
    return True
  if board[2][0] == board[1][1] == board[0][2] and board[2][0] != " ":
    return True
  return False

def main():
  while True:
    draw_board()
    get_human_move()
    if has_winner():
      print("X wins!")
      break
    draw_board()
    get_computer_move()
    if has_winner():
      print("O wins!")
      break

main()

The Implementation Design of a tic tac toe game looks like :

There are several ways to implement tic tac toe in Python, but one possible design is as follows:

1)Define a Board class to represent the game board. This class should have a board attribute, which is a 2D list containing the current state of the game. Each element of the list can be either 'X', 'O', or ' ' (empty space). The class should also have a turn attribute, which stores the symbol of the player whose turn it is (either 'X' or 'O').

2)The Board class should have a display() method that prints the current state of the board to the console. This method should use ASCII art to draw the grid and show the positions of the Xs and Os.

3)The Board class should have a make_move() method that allows a player to make a move on the board. This method should accept a row and column index (both 0-based) and a symbol (either 'X' or 'O'). It should check if the chosen space is empty, and if it is, it should update the board and the turn attribute accordingly. If the space is not empty, the method should print an error message and allow the player to try again.

The Board class should have a game_over() method that checks if the game is over and returns a Boolean value indicating whether it is. The game is over if one player has won or if the board is full and no one has won.

4)Define a Player class to represent a player in the game. This class should have a symbol attribute (either 'X' or 'O') and a name attribute. It should also have a get_move() method that prompts the player for a row and column index and returns them as a tuple.

5)Define a Game class to manage the game. This class should have a board attribute (an instance of the Board class) and a player1 and player2 attribute (instances of the Player class). It should also have a play() method that runs the game loop. The game loop should display the board, ask the current player for their move, make the move on the board, and check if the game is over.

If the game is over, the method should print a message indicating who won or that the game ended in a draw. If the game is not over, the loop should continue and the next player's turn should begin.

6)To start the game, create an instance of the Game class and call its play() method. You may also want to add additional methods or attributes to the Board, Player, and Game classes as needed.

How does a tic tac toe game end?

A tic tac toe game can end in one of three ways:

1) Win: If a player gets three of their symbols in a row (horizontally, vertically, or diagonally), they win the game.

2) Draw: If all of the spaces on the grid are filled and no player has won, the game is a draw.

3) Stalemate: A stalemate occurs when both players are unable to win, even if they make optimal moves. This can happen if the players are evenly matched and play defensively, blocking each other's attempts to get three in a row.

In all of these cases, the game ends and no further moves can be made. The outcome of the game (win, draw, or stalemate) can be determined by checking the state of the board and the number of empty spaces remaining.

What is the function of has_winner() -

The has_winner function is used to check whether the game has been won by either player. It does this by checking for any winning combinations of X's or O's on the board.

In the code, the has_winner function first checks for any rows that are completely filled with either X's or O's. It then checks for any columns that are completely filled with either X's or O's. Finally, it checks for any diagonal lines that are completely filled with either X's or O's. If any of these conditions are met, the function returns True, indicating that the game has been won. If none of these conditions are met, the function returns False, indicating that the game is still in progress.

The overall flow of the game works as such -

  1. The game begins by initializing an empty 3x3 board, represented as a list of lists.

  2. The main function is called, which enters a loop that continues until the game is won or the board is full.

  3. Within the loop, the draw_board function is called to print the current state of the board to the console.

  4. The get_human_move function is called to allow the human player to enter their move. This function prompts the user to enter a column and row, and then places an "X" at that position on the board if it is a valid move.

  5. The has_winner function is called to check if the game has been won by the human player. If the function returns True, the loop is broken and the game ends.

  6. If the game is not yet won, the draw_board function is called again to update the board with the human player's move.

  7. The get_computer_move function is called to allow the computer player to make a move. This function generates a random column and row, and then places an "O" at that position on the board if it is a valid move.

  8. The has_winner function is called again to check if the game has been won by the computer player. If the function returns True, the loop is broken and the game ends.

  9. If the game is not yet won, the loop continues and the players take turns making moves until the game is won or the board is full.


In this article in OpenGenus, we learnt about the famous tic tac toe game and how to implement it using Python.

Sign up for FREE 3 months of Amazon Music. YOU MUST NOT MISS.