Skip to content
Low Level Design Mastery Logo
LowLevelDesign Mastery

Designing a Tic Tac Toe Game

Design a Tic Tac Toe game that allows two players to play on a 3x3 grid.

Design a Tic Tac Toe game that allows two players to play on a 3x3 grid. Players take turns placing their symbols (X or O) in empty cells. The game should detect wins (three in a row horizontally, vertically, or diagonally) and handle draws when all cells are filled.

In this problem, you’ll design a system that manages player turns, validates moves on a shared board, and identifies the exact moment a player wins or the game ends in a draw.


Design a two-player game played on a 3x3 grid where players alternate placing their symbols (X and O) until one wins or the board is full.

Functional Requirements:

  • Standard Grid: Play on a classic 3x3 board.
  • Two Players: Support two players taking turns with ‘X’ and ‘O’ symbols.
  • Win Detection: Identify when a player has three symbols in a row (horizontal, vertical, or diagonal).
  • Draw Handling: Detect when all cells are filled without a winner.
  • Move Validation: Reject invalid moves (e.g., occupied cells) and notify the player.
  • Scoreboard: Keep track of scores/wins across multiple games.
  • Demo Mode: Support predefined moves for flow demonstration.

Non-Functional Requirements:

  • Object-Oriented Design: Clear separation between Game, Board, Cell, and Player.
  • Modularity: Easy to extend for larger boards (N x N) or AI opponents.
  • Testability: Core game logic should be easy to understand and unit test.
  • Readable Output: Display the current state of the board clearly after each move.

The system coordinates between the Game controller, the Board, and the Players.

Diagram Diagram
Diagram

Checking every row, column, and diagonal after every move (using nested loops) is $O(N^2)$. While fine for 3x3, it’s inefficient for 1000x1000.

Solution: Use Counter-based tracking. Maintain arrays rows[] and cols[] and two variables for diagonals. When a player moves at (r, c), increment the count for that row and column. If the count reaches $N$, you have a winner. This reduces detection to $O(1)$.

The game logic should not be tied to a fixed 3x3 array.

Solution: Encapsulate the grid in a Board class. Provide methods like isValidMove(r, c) and setCellValue(r, c, val). This allows you to change the underlying storage (e.g., from a 2D array to a Map for sparse boards) without affecting the Game controller.

Hardcoding ‘X’ and ‘O’ in the logic makes it hard to support more players or custom symbols.

Solution: Use an Enum or a Player Class. The game logic should check if player.getSymbol() matches across a row, rather than checking specifically for the character ‘X’.


By solving this problem, you’ll master:

  • State Management - Handling game lifecycles and transitions.
  • Algorithmic Optimization - Turning $O(N^2)$ checks into $O(1)$ updates.
  • Grid Logic - Modeling and traversing 2D spatial structures.
  • Clean Code - Separating rule enforcement from data representation.

Ready to see the full implementation? Open the interactive playground to access:

  • 🎯 Step-by-step guidance through the 8-step LLD approach
  • 📊 Interactive UML builder to visualize your design
  • 💻 Complete Code Solutions in Python, Java, C++, TypeScript, JavaScript, C#
  • 🤖 AI-powered review of your design and code

After mastering Tic Tac Toe, try these similar problems: