Open In App

Tic-Tac-Toe Game in C++

Last Updated : 19 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In this article, we will learn how to develop a tic-tac-toe game in C++. Tic-tac-toe is a game played between two players usually with paper and pencil but here, we will create a C++ program that will display the game on the console screen and players can use different keys from the keyboard to play it.

tic tac toe game in c++

Before we start, let's understand some rules to play the game:

Rules of Tic-Tac-Toe

Following are the rules that define how to play the tic tac toe game:

  • A player can put only a single letter X or O in the 3 x 3 grid in each chance.
  • Both players will get chances alternatively one after another till someone wins or draws. 
  • To win this game, the player must create a horizontal, vertical, or diagonal line consisting of three same letters.
  • The game is drawn, if all grids are filled with X or O letters but no line is made.

Feature of Tic-Tac-Toe in C++

This game provides the following features:

  • This game is developed on a 3x3 grid.
  • This game is designed for two players.
  • Every player may choose a letter between X and O.
  • Both players will get their chances to turn by turn.

Components of the Game

The game is made of the following components that include the functions and data structures to provide the basic operations of the game.

1. Game Board

The game board is managed by the Board class which contains:

  • A 3x3 character grid to represent the board.
  • A counter to track filled cells.

2. Player Management

Players are represented by the Player class which stores:

  • The player's symbol (X or O)
  • The player's name

3. Movement Of Player

The Boardclass includes methods to handle player moves:

  • drawBoard() to display the current state of the board
  • isValidMove() to check if a move is valid
  • makeMove() to update the board with a player's move

How to check if the input is valid or not?

  • Valid input: If the cell is empty and is within the boundary (0-2 for internal tracking, 1-3 for user input)
  • Invalid input: If the cell has already been filled with another letter or is outside the bounds

4. Game Logic

The TicTacToe class manages the overall game logic:

  • Handles player turns
  • Processes user input
  • Checks for win/draw conditions

5. Win, Lose or Draw

The Board class includes methods to check game status:

  • checkWin() to determine if a player has won
  • isFull() to check if the board is full (a draw)

The draw condition is checked in the play() method of the TicTacToe class when the board is full and no player has won.

C++ Program for Tic Tac Toe Game

Below is the complete code for a basic console-based Tic-Tac-Toe game in C++:

C++
#include <iostream>
#include <string>
using namespace std;

// Player class to represent a player in game
class Player {
private:
    char symbol;
    string name;

public:
    // Constructor
    Player(char sym = 'X', string n = "Player X") : symbol(sym), name(n) {}

    // Getter methods
    char getSymbol() const { return symbol; }
    string getName() const { return name; }
};

// Board class to manage game board
class Board {
private:
    char grid[3][3];
    int filledCells; // Counter for filled cells
    
public:
    // Constructor to initialize the board
    Board() : filledCells(0) {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                grid[i][j] = ' ';
            }
        }
    }

    // Method to display the board
    void drawBoard() const {
        cout << "-------------" << endl;
        for (int i = 0; i < 3; i++) {
            cout << "| ";
            for (int j = 0; j < 3; j++) {
                cout << grid[i][j] << " | ";
            }
            cout << endl << "-------------" << endl;
        }
    }

    // Method to check if a move is valid
    bool isValidMove(int row, int col) const {
        return (row >= 0 && row < 3 && col >= 0 && col < 3 && grid[row][col] == ' ');
    }

    // Method to make a move
    void makeMove(int row, int col, char symbol) {
        if (isValidMove(row, col)) {
            grid[row][col] = symbol;
            filledCells++; // Increment counter when a cell is filled
        }
    }

    // Method to check for a win
    bool checkWin(char symbol) const {
        // Check rows
        for (int i = 0; i < 3; i++) {
            if (grid[i][0] == symbol && grid[i][1] == symbol && grid[i][2] == symbol) {
                return true;
            }
        }
        
        // Check columns
        for (int i = 0; i < 3; i++) {
            if (grid[0][i] == symbol && grid[1][i] == symbol && grid[2][i] == symbol) {
                return true;
            }
        }
        
        // Check diagonals
        if (grid[0][0] == symbol && grid[1][1] == symbol && grid[2][2] == symbol) {
            return true;
        }
        if (grid[0][2] == symbol && grid[1][1] == symbol && grid[2][0] == symbol) {
            return true;
        }
        
        return false;
    }

    // Method to check if board is full using the counter
    bool isFull() const {
        return filledCells == 9;
    }
    
    // Method to get the number of filled cells
    int getFilledCellsCount() const {
        return filledCells;
    }
};

// Game class to manage the game logic
class TicTacToe {
private:
    Board board;
    Player players[2];
    int currentPlayerIndex;

public:
    // Constructor
    TicTacToe() : currentPlayerIndex(0) {
        players[0] = Player('X', "Player X");
        players[1] = Player('O', "Player O");
    }

    // Method to get the current player
    Player& getCurrentPlayer() {
        return players[currentPlayerIndex];
    }

    // Method to switch turns
    void switchTurn() {
        currentPlayerIndex = (currentPlayerIndex + 1) % 2;
    }

    // Method to play the game
    void play() {
        int row, col;
        cout << "Welcome to Tic-Tac-Toe!" << endl;

        while (!board.isFull()) {
            // Display the board
            board.drawBoard();
            
            Player& currentPlayer = getCurrentPlayer();
            
            // Get valid input
            while (true) {
                cout << currentPlayer.getName() << " (" << currentPlayer.getSymbol() 
                     << "), enter row (1-3) and column (1-3): ";
                cin >> row >> col;
                row--; col--; // Convert to 0-indexed
                
                if (board.isValidMove(row, col)) {
                    break;
                } else {
                    cout << "Invalid move. Try again." << endl;
                }
            }
            
            // Make move
            board.makeMove(row, col, currentPlayer.getSymbol());
            
            // Check for win
            if (board.checkWin(currentPlayer.getSymbol())) {
                board.drawBoard();
                cout << currentPlayer.getName() << " wins!" << endl;
                return;
            }
            
            // Switch turns
            switchTurn();
        }
        
        // Game ended in a draw
        board.drawBoard();
        cout << "It's a draw!" << endl;
    }
};

int main() {
    // Creating game object
    TicTacToe game;
    
    // Starting the game
    game.play();
    return 0;
}


Output

Welcome to Tic-Tac-Toe!
-------------
| | | |
-------------
| | | |
-------------
| | | |
-------------
Player X (X), enter row (1-3) and column (1-3): 2 2
-------------
| | | |
-------------
| | X | |
-------------
| | | |
-------------
Player O (O), enter row (1-3) and column (1-3): 1 1
-------------
| O | | |
-------------
| | X | |
-------------
| | | |
-------------
Player X (X), enter row (1-3) and column (1-3): 3 1
-------------
| O | | |
-------------
| | X | |
-------------
| X | | |
-------------
Player O (O), enter row (1-3) and column (1-3): 1 3
-------------
| O | | O |
-------------
| | X | |
-------------
| X | | |
-------------
Player X (X), enter row (1-3) and column (1-3): 3 3
-------------
| O | | O |
-------------
| | X | |
-------------
| X | | X |
-------------
Player O (O), enter row (1-3) and column (1-3): 1 2
-------------
| O | O | O |
-------------
| | X | |
-------------
| X | | X |
-------------
Player O wins!

Next Article

Similar Reads