How to create a Tic-Tac-Toe game in Python

Tic-Tac-Toe (also known as Noughts and Crosses) is a classic paper-and-pencil game people enjoy. The aim of the game is to be the first player to form a horizontal, vertical, or diagonal line of three marks (either X or O) on a 3×33\times3 grid. This Answer will walk you through creating a Tic-Tac-Toe game using Python. By following the step-by-step instructions below, you can build your very own interactive Tic-Tac-Toe game that you can play with other people.

Setting up the game board

The first step is to create the game board, essentially a 3×33\times3 grid where players make their moves. We’ll use a list of lists to represent the board and initialize it with empty spaces.

We’ll also create a function display_board() that will display the game board on the console. This function will iterate through the board and print the current state of each cell.

# Create the game board
board = [[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' ']]
def display_board():
print('-' * 5)
for row in board:
print('|'.join(row))
print('-' * 5)
Setting up the game board

Handling player’s input

Let’s implement a function allowing players to enter their moves. We’ll prompt the players to enter their desired move’s row and column numbers and validate the input to ensure it’s within the valid range.

def get_player_move():
while True:
try:
row = int(input("Enter the row number (0-2): "))
column = int(input("Enter the column number (0-2): "))
if 0 <= row <= 2 and 0 <= column <= 2:
return row, column
else:
print("Invalid input. Please enter numbers between 0 and 2.")
except ValueError:
print("Invalid input. Please enter numbers.")
Handling player's input

Updating game board

Once the players make their moves, we need to update the game board accordingly. We’ll modify the board state based on the player’s move and ensure the cell is not already occupied.

def update_board(row, column, player):
if board[row][column] == ' ':
board[row][column] = player
return True
else:
return False
Updating game board

Checking for a winner

After each move, we’ll check if any player has won the game. We’ll define a function that examines the board state and determines if a winning combination of marks is in any row, column, or diagonal.

def check_winner():
# Check rows
for row in board:
if row[0] == row[1] == row[2] != ' ':
return row[0]
# Check columns
for col in range(3):
if board[0][col] == board[1][col] == board[2][col] != ' ':
return board[0][col]
# Check diagonals
if board[0][0] == board[1][1] == board[2][2] != ' ':
return board[0][0]
if board[0][2] == board[1][1] == board[2][0] != ' ':
return board[0][2]
return None
Checking for a winner

Handling the game loop

To create a complete game experience, we’ll wrap the gameplay logic in a loop until there’s a winner or the game ends in a draw. We’ll alternate between players and prompt them for their moves inside the loop.

def play_game():
current_player = 'X'
while True:
display_board()
print(f"Player {current_player}'s turn.")
row, column = get_player_move()
if update_board(row, column, current_player):
winner = check_winner()
if winner:
display_board()
print(f"Player {winner} wins!")
break
elif all(board[i][j] != ' ' for i in range(3) for j in range(3)):
display_board()
print("It's a draw!")
break
current_player = 'O' if current_player == 'X' else 'X'
else:
print("That cell is already occupied. Try again.")
Handling the game loop

Let's combine all this logic and see the code in action:

# Create the game board
board = [[' ', ' ', ' '],
         [' ', ' ', ' '],
         [' ', ' ', ' ']]

def display_board():
    for row in board:
        print('|'.join(row))
        print('-' * 5)

def get_player_move():
    while True:
        try:
            row = int(input("Enter the row number (0-2): "))
            column = int(input("Enter the column number (0-2): "))
            if 0 <= row <= 2 and 0 <= column <= 2:
                return row, column
            else:
                print("Invalid input. Please enter numbers between 0 and 2.")
        except ValueError:
            print("Invalid input. Please enter numbers.")

def update_board(row, column, player):
    if board[row][column] == ' ':
        board[row][column] = player
        return True
    else:
        return False

def check_winner():
    # Check rows
    for row in board:
        if row[0] == row[1] == row[2] != ' ':
            return row[0]

    # Check columns
    for col in range(3):
        if board[0][col] == board[1][col] == board[2][col] != ' ':
            return board[0][col]

    # Check diagonals
    if board[0][0] == board[1][1] == board[2][2] != ' ':
        return board[0][0]
    if board[0][2] == board[1][1] == board[2][0] != ' ':
        return board[0][2]

    return None

def play_game():
    current_player = 'X'
    while True:
        display_board()
        print(f"Player {current_player}'s turn.")
        row, column = get_player_move()
        if update_board(row, column, current_player):
            winner = check_winner()
            if winner:
                display_board()
                print(f"Player {winner} wins!")
                break
            elif all(board[i][j] != ' ' for i in range(3) for j in range(3)):
                display_board()
                print("It's a draw!")
                break
            current_player = 'O' if current_player == 'X' else 'X'
        else:
            print("That cell is already occupied. Try again.")

play_game()
Complete code of the Tic-Tac-Toe game

That’s it! We’ve successfully built a fully functional Tic-Tac-Toe game in Python.

Copyright ©2024 Educative, Inc. All rights reserved