Skip to content
geeksforgeeks
  • Tutorials
    • Python
    • Java
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
    • Practice Coding Problems
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • System Design Tutorial
  • What is System Design
  • System Design Life Cycle
  • High Level Design HLD
  • Low Level Design LLD
  • Design Patterns
  • UML Diagrams
  • System Design Interview Guide
  • Scalability
  • Databases
Open In App
Next Article:
Low Level Design of Tic Tac Toe | System Design
Next article icon

Low Level Design of Tic Tac Toe | System Design

Last Updated : 26 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

In classic games, few are as universally recognized and enjoyed as Tic Tac Toe. Despite its apparent simplicity, this game engages players of all ages in a battle of wits and strategy. In this article, we delve into the intricacies of designing a low-level structure for Tic Tac Toe that captures the essence of the game and highlights the underlying complexities.

Important Topics for Low Level Design of Tic Tac Toe

  • The Essence of Tic Tac Toe
  • Rules of the game
  • Representing the Game Board
  • Player Turns and Moves
  • Validating Moves
  • Determining the Winner
  • Tying It All Together
  • Complete Tic Tac Toe implementation
  • Conclusion

The Essence of Tic Tac Toe

Tic Tac Toe, known colloquially as "Xs and Os," is a two-player game typically played on a 3x3 grid. The objective is simple: be the first to form a horizontal, vertical, or diagonal line of three of your marks (either "X" or "O"). The elegance of the game lies in its deceptive complexity, while the rules are straightforward, devising an unbeatable strategy demands a keen understanding of the game's dynamics.

Rules of the game

Firstly let's understand the rules of the game:

  • Setup: The game is played on a 3 * 3 grid. One player uses 'X' another player uses 'O' and each player takes turns making their moves.
  • Winner: The game is won by the player placing his or her symbol in a row, column, or diagonal. The first player to get three symbols in a row wins the game. When the player reaches this, the game ends immediately.
  • Draw: If all the grid cells are filled and no player has three symbols in a row, the game will be a tie or a draw.
  • Illegal Moves: A player cannot place his or her symbol on a tile occupied by an opponent's symbol or their own symbol. The move must be made to an empty cell.

Representing the Game Board

At the heart of every game lies the game board. In our low-level design for Tic Tac Toe, we choose a 2D array or matrix to represent the board. Each cell of the array can take three possible values: empty, "X," or "O." This array forms the canvas upon which players will make their moves.

Python
# Initialize an empty 3x3 Tic Tac Toe board board = [[' ' for _ in range(3)] for _ in range(3)] 

Player Turns and Moves

In any game, managing player turns is crucial. We can represent the players using simple integers – player 1 and player 2. Their moves are translated to row and column indices on the game board.

Python
current_player = 1  # Player 1 starts  row = 1 column = 2  # Placing the current player's mark on the board board[row][column] = 'X' if current_player == 1 else 'O' 

Validating Moves

Ensuring that players adhere to the rules is paramount. The low-level design includes a move validation process, verifying that the chosen cell is empty and within the bounds of the board.

Python
def is_valid_move(row, column):     return 0 <= row < 3 and 0 <= column < 3 and board[row][column] == ' '  # Example usage if is_valid_move(1, 2):     # Perform the move else:     print("Invalid move. Please choose an empty cell within the board.") 

Determining the Winner

The climax of any Tic Tac Toe game is the declaration of a winner. Our low-level design accommodates a function to check for victory conditions after each move.

Python
def check_winner(player):     # Check rows, columns, and diagonals for three marks in a row     # Return True if the player wins, False otherwise  # Example usage if check_winner(1):     print("Player 1 wins!") elif check_winner(2):     print("Player 2 wins!") 

Tying It All Together

Tic Tac Toe's low-level design is a harmonious interplay of game mechanics, data structures, and decision-making logic. From managing the game board to validating moves and determining victory, every element contributes to the immersive experience of the game.

So, the next time you engage in a friendly match of Tic Tac Toe, remember that behind the Xs and Os lies a thoughtfully crafted low-level design that brings a timeless game to life. As you strategize to outwit your opponent, you're also experiencing the result of careful planning and design – a testament to the enduring appeal of this classic pastime.

Complete Tic Tac Toe implementation

C++
#include <iostream> #include <vector>  using namespace std;  class TicTacToe { private:     vector<vector<char> > board; // 3x3 game board     int currentPlayer; // 1 for Player 1, 2 for Player 2  public:     TicTacToe()     {         board = vector<vector<char> >(3,                                       vector<char>(3, ' '));         currentPlayer = 1;     }      void printBoard()     {         for (int i = 0; i < 3; ++i) {             for (int j = 0; j < 3; ++j) {                 cout << board[i][j];                 if (j < 2) {                     cout << " | ";                 }             }             cout << endl;             if (i < 2) {                 cout << "---------" << endl;             }         }     }      bool isBoardFull()     {         for (int i = 0; i < 3; ++i) {             for (int j = 0; j < 3; ++j) {                 if (board[i][j] == ' ') {                     return false;                 }             }         }         return true;     }      bool makeMove(int row, int column)     {         if (row < 0 || row >= 3 || column < 0 || column >= 3             || board[row][column] != ' ') {             return false; // Invalid move         }         board[row][column]             = (currentPlayer == 1) ? 'X' : 'O';         currentPlayer             = 3 - currentPlayer; // Switch player (1 to 2 or                                  // 2 to 1)         return true;     }      bool checkWinner()     {         // Check rows, columns, and diagonals for a win         for (int i = 0; i < 3; ++i) {             if (board[i][0] != ' '                 && board[i][0] == board[i][1]                 && board[i][1] == board[i][2]) {                 return true; // Row win             }             if (board[0][i] != ' '                 && board[0][i] == board[1][i]                 && board[1][i] == board[2][i]) {                 return true; // Column win             }         }         if (board[0][0] != ' ' && board[0][0] == board[1][1]             && board[1][1] == board[2][2]) {             return true; // Diagonal win         }         if (board[0][2] != ' ' && board[0][2] == board[1][1]             && board[1][1] == board[2][0]) {             return true; // Diagonal win         }         return false;     }     int getCurrentPlayer() {         return currentPlayer;     }       };  int main() {     TicTacToe game;     int row, column;      while (!game.isBoardFull() && !game.checkWinner()) {         game.printBoard();          cout << "Player " << game.getCurrentPlayer()              << ", enter your move (row and column): ";         cin >> row >> column;          if (game.makeMove(row, column)) {             cout << "Move successful!" << endl;         }         else {             cout << "Invalid move. Try again." << endl;         }     }      game.printBoard();      if (game.checkWinner()) {         cout << "Player " << (3 - game.getCurrentPlayer())              << " wins!" << endl;     }     else {         cout << "It's a draw!" << endl;     }      return 0; } 
Java
import java.util.Scanner;  public class TicTacToe {     private char[][] board; // 3x3 game board     private int         currentPlayer; // 1 for Player 1, 2 for Player 2      public TicTacToe()     {         board = new char[3][3];         for (int i = 0; i < 3; ++i) {             for (int j = 0; j < 3; ++j) {                 board[i][j] = ' ';             }         }         currentPlayer = 1;     }      public void printBoard()     {         for (int i = 0; i < 3; ++i) {             for (int j = 0; j < 3; ++j) {                 System.out.print(board[i][j]);                 if (j < 2) {                     System.out.print(" | ");                 }             }             System.out.println();             if (i < 2) {                 System.out.println("---------");             }         }     }      public boolean isBoardFull()     {         for (int i = 0; i < 3; ++i) {             for (int j = 0; j < 3; ++j) {                 if (board[i][j] == ' ') {                     return false;                 }             }         }         return true;     }      public boolean makeMove(int row, int column)     {         if (row < 0 || row >= 3 || column < 0 || column >= 3             || board[row][column] != ' ') {             return false; // Invalid move         }         board[row][column]             = (currentPlayer == 1) ? 'X' : 'O';         currentPlayer             = 3 - currentPlayer; // Switch player (1 to 2 or                                  // 2 to 1)         return true;     }      public boolean checkWinner()     {         // Check rows, columns, and diagonals for a win         for (int i = 0; i < 3; ++i) {             if (board[i][0] != ' '                 && board[i][0] == board[i][1]                 && board[i][1] == board[i][2]) {                 return true; // Row win             }             if (board[0][i] != ' '                 && board[0][i] == board[1][i]                 && board[1][i] == board[2][i]) {                 return true; // Column win             }         }         if (board[0][0] != ' ' && board[0][0] == board[1][1]             && board[1][1] == board[2][2]) {             return true; // Diagonal win         }         if (board[0][2] != ' ' && board[0][2] == board[1][1]             && board[1][1] == board[2][0]) {             return true; // Diagonal win         }         return false;     }      public static void main(String[] args)     {         TicTacToe game = new TicTacToe();         Scanner scanner = new Scanner(System.in);         int row, column;          while (!game.isBoardFull() && !game.checkWinner()) {             game.printBoard();              System.out.print(                 "Player " + game.currentPlayer                 + ", enter your move (row and column): ");             row = scanner.nextInt();             column = scanner.nextInt();              if (game.makeMove(row, column)) {                 System.out.println("Move successful!");             }             else {                 System.out.println(                     "Invalid move. Try again.");             }         }          game.printBoard();          if (game.checkWinner()) {             System.out.println("Player "                                + (3 - game.currentPlayer)                                + " wins!");         }         else {             System.out.println("It's a draw!");         }          scanner.close();     } } 
Python
class TicTacToe:     def __init__(self):         self.board = [[' ' for _ in range(3)] for _ in range(3)]         self.current_player = 1      def print_board(self):         for row in self.board:             print('|'.join(row))             print('-' * 5)      def is_board_full(self):         return all(cell != ' ' for row in self.board for cell in row)      def make_move(self, row, column):         if 0 <= row < 3 and 0 <= column < 3 and self.board[row][column] == ' ':             self.board[row][column] = 'X' if self.current_player == 1 else 'O'             # Switch player (1 to 2 or 2 to 1)             self.current_player = 3 - self.current_player             return True         return False      def check_winner(self):         for i in range(3):             if self.board[i][0] == self.board[i][1] == self.board[i][2] != ' ':                 return True  # Row win             if self.board[0][i] == self.board[1][i] == self.board[2][i] != ' ':                 return True  # Column win         if self.board[0][0] == self.board[1][1] == self.board[2][2] != ' ':             return True  # Diagonal win         if self.board[0][2] == self.board[1][1] == self.board[2][0] != ' ':             return True  # Diagonal win         return False   # Main game loop if __name__ == "__main__":     game = TicTacToe()      while not game.is_board_full() and not game.check_winner():         game.print_board()          row, column = map(int, input(             f"Player {game.current_player}, enter your move (row and column): ").split())          if game.make_move(row, column):             print("Move successful!")         else:             print("Invalid move. Try again.")      game.print_board()      if game.check_winner():         print(f"Player {3 - game.current_player} wins!")     else:         print("It's a draw!") 
JavaScript
class TicTacToe {     constructor() {         this.board = Array.from(Array(3), () => Array(3).fill(' ')); // 3x3 game board         this.currentPlayer = 1; // 1 for Player 1, 2 for Player 2     }      printBoard() {         for (let i = 0; i < 3; ++i) {             for (let j = 0; j < 3; ++j) {                 process.stdout.write(this.board[i][j]);                 if (j < 2) {                     process.stdout.write(' | ');                 }             }             console.log();             if (i < 2) {                 console.log('---------');             }         }     }      isBoardFull() {         for (let i = 0; i < 3; ++i) {             for (let j = 0; j < 3; ++j) {                 if (this.board[i][j] === ' ') {                     return false;                 }             }         }         return true;     }      makeMove(row, column) {         if (             row < 0 ||             row >= 3 ||             column < 0 ||             column >= 3 ||             this.board[row][column] !== ' '         ) {             return false; // Invalid move         }         this.board[row][column] = this.currentPlayer === 1 ? 'X' : 'O';         this.currentPlayer = 3 - this.currentPlayer; // Switch player (1 to 2 or 2 to 1)         return true;     }      checkWinner() {         // Check rows, columns, and diagonals for a win         for (let i = 0; i < 3; ++i) {             if (                 this.board[i][0] !== ' ' &&                 this.board[i][0] === this.board[i][1] &&                 this.board[i][1] === this.board[i][2]             ) {                 return true; // Row win             }             if (                 this.board[0][i] !== ' ' &&                 this.board[0][i] === this.board[1][i] &&                 this.board[1][i] === this.board[2][i]             ) {                 return true; // Column win             }         }         if (             this.board[0][0] !== ' ' &&             this.board[0][0] === this.board[1][1] &&             this.board[1][1] === this.board[2][2]         ) {             return true; // Diagonal win         }         if (             this.board[0][2] !== ' ' &&             this.board[0][2] === this.board[1][1] &&             this.board[1][1] === this.board[2][0]         ) {             return true; // Diagonal win         }         return false;     } }  function main() {     const game = new TicTacToe();     const readline = require('readline-sync');     let row, column;      while (!game.isBoardFull() && !game.checkWinner()) {         game.printBoard();          console.log(`Player ${game.currentPlayer}, enter your move (row and column): `);         row = parseInt(readline.question('Row: '));         column = parseInt(readline.question('Column: '));          if (game.makeMove(row, column)) {             console.log('Move successful!');         } else {             console.log('Invalid move. Try again.');         }     }      game.printBoard();      if (game.checkWinner()) {         console.log(`Player ${3 - game.currentPlayer} wins!`);     } else {         console.log("It's a draw!");     } }  main(); // This code is contributed by Vikram_Shirsat 

Conclusion

The game of Tic Tac Toe, often deemed simplistic, hides layers of intriguing design choices beneath its surface. From crafting the game board to managing turns and deciphering wins, every aspect intertwines to deliver an immersive gaming experience. As we delve into the low-level design using C++, we uncover the harmony between code and gameplay, reminding us that even seemingly uncomplicated games hold within them a realm of thoughtful intricacies.

So the next time you engage in a round of Tic Tac Toe, take a moment to appreciate the elegance of its design—a design that transforms an ordinary grid into a battlefield of strategic brilliance.


Next Article
Low Level Design of Tic Tac Toe | System Design

M

mr_banerjee
Improve
Article Tags :
  • System Design
  • Low Level Design

Similar Reads

    Most Commonly Asked System Design Interview Problems/Questions
    This System Design Interview Guide will provide the most commonly asked system design interview questions and equip you with the knowledge and techniques needed to design, build, and scale your robust applications, for professionals and newbies Below are a list of most commonly asked interview probl
    2 min read
    How to Crack System Design Interview Round?
    In the System Design Interview round, You will have to give a clear explanation about designing large scalable distributed systems to the interviewer. This round may be challenging and complex for you because you are supposed to cover all the topics and tradeoffs within this limited time frame, whic
    9 min read
    System Design Interview Questions and Answers [2025]
    In the hiring procedure, system design interviews play a significant role for many tech businesses, particularly those that develop large, reliable software systems. In order to satisfy requirements like scalability, reliability, performance, and maintainability, an extensive plan for the system's a
    7 min read
    5 Common System Design Concepts for Interview Preparation
    In the software engineering interview process system design round has become a standard part of the interview. The main purpose of this round is to check the ability of a candidate to build a complex and large-scale system. Due to the lack of experience in building a large-scale system a lot of engi
    12 min read
    5 Tips to Crack Low-Level System Design Interviews
    Cracking low-level system design interviews can be challenging, but with the right approach, you can master them. This article provides five essential tips to help you succeed. These tips will guide you through the preparation process. Learn how to break down complex problems, communicate effectivel
    6 min read

    Chat Applications Design Problems

    Designing Facebook Messenger | System Design Interview
    We are going to build a real-time Facebook messaging app, that can support millions of users. All the chat applications like Facebook Messenger, WhatsApp, Discord, etc. can be built using the same design. In this article, we will discuss the high-level architecture of the system as well as some spec
    9 min read

    Media Storage and Streaming Design Problems

    System Design Netflix | A Complete Architecture
    Designing Netflix is a quite common question of system design rounds in interviews. In the world of streaming services, Netflix stands as a monopoly, captivating millions of viewers worldwide with its vast library of content delivered seamlessly to screens of all sizes. Behind this seemingly effortl
    15+ min read
    Design Dropbox - A System Design Interview Question
    System Design Dropbox, You might have used this file hosting service multiple times to upload and share files or images. System Design Dropbox is a quite common question in the system design round. In this article, we will discuss how to design a website like Dropbox.Important Topics for the Dropbox
    14 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences