Tic-Tac-Toe is a simple yet exciting game that many of us grew up playing. In this guide, you will learn how to build your own Tic-Tac-Toe game using Python and the popular Pygame library. This project is perfect for beginners who want to get started with game development using Python.

Why Do We Use the Pygame Library?

Pygame makes it super simple to create games with Python. It handles all the tricky stuff, like graphics, user input, and game mechanics, so you can focus on the fun part—building the game. Plus, it’s a great starting point if you’re new to game development.

What You’ll Learn from This Python Tic-Tac-Toe Tutorial

Here’s what we’ll cover in this project:

  • Creating a Tic-Tac-Toe game board
  • Handling player turns and input
  • Detecting wins and draws
  • Adding a restart option for endless fun

Installing Pygame

Before jumping in, you’ll need to install Pygame. If you haven’t done that yet, run this command:

pip install pygame

Source Code for Creating Tic-Tac-Toe game in Python

import pygame
import sys

# Initialize pygame
pygame.init()

# Set up the display
WIDTH, HEIGHT = 600, 600
LINE_WIDTH = 15
BOARD_ROWS = 3
BOARD_COLS = 3
SQUARE_SIZE = WIDTH // BOARD_COLS
CIRCLE_RADIUS = SQUARE_SIZE // 3
CIRCLE_WIDTH = 15
CROSS_WIDTH = 25
SPACE = SQUARE_SIZE // 4

# Colors (classic theme)
BG_COLOR = (0, 0, 0)  # Black background
LINE_COLOR = (128, 128, 128)  # Gray lines
CIRCLE_COLOR = (255, 0, 0)  # Red for circles (Player 1)
CROSS_COLOR = (0, 0, 255)  # Blue for crosses (Player 2)

# Initialize board
board = [[0 for _ in range(BOARD_COLS)] for _ in range(BOARD_ROWS)]

# Set up the window
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Tic-Tac-Toe')
screen.fill(BG_COLOR)

# Font for text
font = pygame.font.Font(None, 50)
small_font = pygame.font.Font(None, 30)

# Draw lines
def draw_lines():
    # Horizontal lines
    pygame.draw.line(screen, LINE_COLOR, (0, SQUARE_SIZE), (WIDTH, SQUARE_SIZE), LINE_WIDTH)
    pygame.draw.line(screen, LINE_COLOR, (0, 2 * SQUARE_SIZE), (WIDTH, 2 * SQUARE_SIZE), LINE_WIDTH)
    
    # Vertical lines
    pygame.draw.line(screen, LINE_COLOR, (SQUARE_SIZE, 0), (SQUARE_SIZE, HEIGHT), LINE_WIDTH)
    pygame.draw.line(screen, LINE_COLOR, (2 * SQUARE_SIZE, 0), (2 * SQUARE_SIZE, HEIGHT), LINE_WIDTH)

draw_lines()

# Mark square on the board
def mark_square(row, col, player):
    board[row][col] = player

# Check if square is available
def available_square(row, col):
    return board[row][col] == 0

# Check for a win
def check_win(player):
    # Check vertical, horizontal, and diagonal wins
    for col in range(BOARD_COLS):
        if board[0][col] == board[1][col] == board[2][col] == player:
            return True
    for row in range(BOARD_ROWS):
        if board[row][0] == board[row][1] == board[row][2] == player:
            return True
    if board[0][0] == board[1][1] == board[2][2] == player:
        return True
    if board[2][0] == board[1][1] == board[0][2] == player:
        return True
    return False

# Check for a draw
def check_draw():
    for row in range(BOARD_ROWS):
        for col in range(BOARD_COLS):
            if board[row][col] == 0:
                return False
    return True

# Draw figures
def draw_figures():
    for row in range(BOARD_ROWS):
        for col in range(BOARD_COLS):
            if board[row][col] == 1:
                pygame.draw.circle(screen, CIRCLE_COLOR, (int(col * SQUARE_SIZE + SQUARE_SIZE // 2), int(row * SQUARE_SIZE + SQUARE_SIZE // 2)), CIRCLE_RADIUS, CIRCLE_WIDTH)
            elif board[row][col] == 2:
                pygame.draw.line(screen, CROSS_COLOR, 
                                 (col * SQUARE_SIZE + SPACE, row * SQUARE_SIZE + SQUARE_SIZE - SPACE), 
                                 (col * SQUARE_SIZE + SQUARE_SIZE - SPACE, row * SQUARE_SIZE + SPACE), CROSS_WIDTH)
                pygame.draw.line(screen, CROSS_COLOR, 
                                 (col * SQUARE_SIZE + SPACE, row * SQUARE_SIZE + SPACE), 
                                 (col * SQUARE_SIZE + SQUARE_SIZE - SPACE, row * SQUARE_SIZE + SQUARE_SIZE - SPACE), CROSS_WIDTH)

# Display message (win, draw, restart)
def display_message(text):
    text_surface = font.render(text, True, (255, 255, 255))  # White text for result
    text_rect = text_surface.get_rect(center=(WIDTH // 2, HEIGHT // 2))
    screen.fill(BG_COLOR)
    screen.blit(text_surface, text_rect)

    # Show restart instruction
    restart_text = small_font.render('Press Ctrl + R to restart', True, (255, 255, 255))
    restart_rect = restart_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 50))
    screen.blit(restart_text, restart_rect)
    
    pygame.display.update()

# Restart the game
def restart_game():
    global board, game_over, player
    board = [[0 for _ in range(BOARD_COLS)] for _ in range(BOARD_ROWS)]
    game_over = False
    player = 1
    screen.fill(BG_COLOR)
    draw_lines()

# Main game loop
player = 1
game_over = False

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.MOUSEBUTTONDOWN and not game_over:
            mouseX = event.pos[0]  # X coordinate
            mouseY = event.pos[1]  # Y coordinate

            clicked_row = mouseY // SQUARE_SIZE
            clicked_col = mouseX // SQUARE_SIZE

            if available_square(clicked_row, clicked_col):
                mark_square(clicked_row, clicked_col, player)
                draw_figures()

                if check_win(player):
                    game_over = True
                    display_message(f'Player {player} wins!')
                elif check_draw():
                    game_over = True
                    display_message('It\'s a Draw!')

                player = 2 if player == 1 else 1

        # Restart the game if Ctrl + R is pressed
        if event.type == pygame.KEYDOWN and event.mod & pygame.KMOD_CTRL:
            if event.key == pygame.K_r and game_over:
                restart_game()

    pygame.display.update()

Output

Understanding the Code

Let’s take a quick look at what’s happening in the game:

  • Creating the Game Board: We draw a simple 3×3 grid using gray lines on a black background for that classic feel.
  • Player Turns and Input: Player 1 uses a red circle, and Player 2 uses a blue cross. You take turns clicking on the grid to place your symbol.
  • Winning and Draws in Python Tic-Tac-Toe: After each move, the game checks if someone has won or if it’s a draw.
  • Restarting the Game: Finished a game? No worries—just hit Ctrl + R to start a new round.

Conclusion

And you’re done! You’ve just built your own Tic-Tac-Toe game using Python and Pygame. Now that you’ve got the basics, feel free to tweak the code and make it your own. If you’re interested in more Python projects, click here. Thanks for reading, and I’ll see you in the next article!

Author

Hi, I'm Yagyavendra Tiwari, a computer engineer with a strong passion for programming. I'm excited to share my programming knowledge with everyone here and help educate others in this field.

Write A Comment