Skip to content

codehelping.com

  • Home
  • Projects
  • Blog
  • Contact Us
  • About Us

Master Tic-Tac-Toe Game in C++: 2025 with Source Code

Posted on December 9, 2024April 6, 2025 By Omkar Pathak No Comments on Master Tic-Tac-Toe Game in C++: 2025 with Source Code
C++ Projects, Project

What is a Tic-Tac-Toe Game in C++?

A Tic-Tac-Toe Game in C++ Project is an exciting and trivial game in which two players use turns to mark the points in a 3*3 grid to have the three in a line. In this game, our computer will be the second player.

Tic-Tac-Toe Game in C++ 2025 Project CodeHelping

Who is the second player in our Tic-Tac-Toe Game in C++?

This game uses the Minimax algorithm which a decision-making technique used by two-player games like in our Tic-Tac-Toe Game in C++. The AI (Our Computer) looks at all the moves, evaluates the results, and chooses the move that gives it the highest chance of winning while ensuring the player has the worst possible chance of winning.

Size of Board in Tic-Tac-Toe Game:

The game board for Tic-Tac-Toe is just a 2D array 3*3 grid. Every cell of the grid is empty ‘ ‘ unless filled by a mark, ‘X’ from the user and ‘O’ from AI.

Tic-Tac-Toe Game Initialization:

  • The initializeGame() function established the initial 3×3 grid filled with blank spaces and shuffled the sequence of moves.
  • The displayGrid() function showed the current state of the grid that changed after each move to reflect changes from both players and AI.
Tic-Tac-Toe Game in C++ 2025 CodeHelping

Step-by-Step Tic-Tac-Toe Game in C++:

Initial Game State:

Start game: this will ask you to play the game on itself the screen will open and will request you to play, here the board will start populating and some basics hints about the game.

  • User move: Choose a cell (1–9); if it’s free, your mark is placed. If not, pick again
  • Repeat Turns: The game alternates turns between you and the AI. It continues until one wins or the grid is full.
  • Winning/Draw: After each turn, the game checks for a winner. You win by getting three marks in a row—horizontally, vertically, or diagonally. If the board fills up with no winner, it’s a draw.

Complete Source Code: Tic-Tac-Toe Game in C++

How to run code? You can directly copy & paste the code in your compiler.

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define AI 1
#define USER 2
#define GRID 3
#define AI_MOVE 'O'
#define USER_MOVE 'X'

// ---------------- Intelligent Moves start

struct Position {
    int row, col;
};

char aiPlayer = 'x', humanPlayer = 'o';

// This function checks if moves are available on the grid.
bool hasMovesRemaining(char grid[3][3])
{
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            if (grid[i][j] == '_')
                return true;
    return false;
}

// This evaluates the current grid state
int evaluateGrid(char g[3][3])
{
    // Check rows for victory.
    for (int row = 0; row < 3; row++) {
        if (g[row][0] == g[row][1]
            && g[row][1] == g[row][2]) {
            if (g[row][0] == aiPlayer)
                return +10;
            else if (g[row][0] == humanPlayer)
                return -10;
        }
    }

    // Check columns for victory.
    for (int col = 0; col < 3; col++) {
        if (g[0][col] == g[1][col]
            && g[1][col] == g[2][col]) {
            if (g[0][col] == aiPlayer)
                return +10;

            else if (g[0][col] == humanPlayer)
                return -10;
        }
    }

    // Check diagonals for victory.
    if (g[0][0] == g[1][1] && g[1][1] == g[2][2]) {
        if (g[0][0] == aiPlayer)
            return +10;
        else if (g[0][0] == humanPlayer)
            return -10;
    }

    if (g[0][2] == g[1][1] && g[1][1] == g[2][0]) {
        if (g[0][2] == aiPlayer)
            return +10;
        else if (g[0][2] == humanPlayer)
            return -10;
    }

    // If no one has won, return 0
    return 0;
}

// This is the minimax algorithm.
int minimaxAlgorithm(char grid[3][3], int level, bool isMaximizer)
{
    int score = evaluateGrid(grid);

    // Return score if game has been won.
    if (score == 10)
        return score;

    if (score == -10)
        return score;

    // Return 0 if no moves left.
    if (!hasMovesRemaining(grid))
        return 0;

    if (isMaximizer) {
        int maxScore = -1000;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (grid[i][j] == '_') {
                    grid[i][j] = aiPlayer;
                    int result = minimaxAlgorithm(grid, level + 1, !isMaximizer);
                    if (result > maxScore) {
                        maxScore = result;
                    }
                    grid[i][j] = '_';
                }
            }
        }
        return maxScore;
    } else {
        int minScore = 1000;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (grid[i][j] == '_') {
                    grid[i][j] = humanPlayer;
                    int result = minimaxAlgorithm(grid, level + 1, !isMaximizer);
                    if (result < minScore) {
                        minScore = result;
                    }
                    grid[i][j] = '_';
                }
            }
        }
        return minScore;
    }
}

// This function finds the best move for the AI.
struct Position calculateBestMove(char grid[3][3])
{
    int bestScore = -1000;
    struct Position optimalMove;
    optimalMove.row = -1;
    optimalMove.col = -1;

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (grid[i][j] == '_') {
                grid[i][j] = aiPlayer;

                int moveScore = minimaxAlgorithm(grid, 0, false);
                grid[i][j] = '_';

                if (moveScore > bestScore) {
                    optimalMove.row = i;
                    optimalMove.col = j;
                    bestScore = moveScore;
                }
            }
        }
    }

    return optimalMove;
}

// -----------------------------------Intelligent Moves end

// Display the game grid
void displayGrid(char grid[][GRID])
{
    printf("\n\n");
    printf("\t\t\t %c | %c | %c \n", grid[0][0],
           grid[0][1], grid[0][2]);
    printf("\t\t\t--------------\n");
    printf("\t\t\t %c | %c | %c \n", grid[1][0],
           grid[1][1], grid[1][2]);
    printf("\t\t\t--------------\n");
    printf("\t\t\t %c | %c | %c \n\n", grid[2][0],
           grid[2][1], grid[2][2]);
}

// Show game instructions
void displayInstructions()
{
    printf("\t\t\t Tic-Tac-Toe\n\n");
    printf("Choose a cell numbered from 1 to 9 as below "
           "and play\n\n");

    printf("\t\t\t 1 | 2 | 3 \n");
    printf("\t\t\t--------------\n");
    printf("\t\t\t 4 | 5 | 6 \n");
    printf("\t\t\t--------------\n");
    printf("\t\t\t 7 | 8 | 9 \n\n");

    printf("-\t-\t-\t-\t-\t-\t-\t-\t-\t-\n\n");
}

// Initialize the grid and moves array
void initializeGame(char grid[][GRID], int moves[])
{
    srand(time(NULL));

    for (int i = 0; i < GRID; i++) {
        for (int j = 0; j < GRID; j++)
            grid[i][j] = ' ';
    }

    for (int i = 0; i < GRID * GRID; i++)
        moves[i] = i;

    for (int i = 0; i < GRID * GRID; i++) {
        int randomIdx = rand() % (GRID * GRID);
        int temp = moves[i];
        moves[i] = moves[randomIdx];
        moves[randomIdx] = temp;
    }
}

// Declare the winner
void announceWinner(int currentPlayer)
{
    if (currentPlayer == AI)
        printf("AI wins!\n");
    else
        printf("User wins!\n");
}

// Check if a row has been crossed
int rowCheck(char grid[][GRID])
{
    for (int i = 0; i < GRID; i++) {
        if (grid[i][0] == grid[i][1]
            && grid[i][1] == grid[i][2]
            && grid[i][0] != ' ')
            return 1;
    }
    return 0;
}

// Check if a column has been crossed
int columnCheck(char grid[][GRID])
{
    for (int i = 0; i < GRID; i++) {
        if (grid[0][i] == grid[1][i]
            && grid[1][i] == grid[2][i]
            && grid[0][i] != ' ')
            return 1;
    }
    return 0;
}

// Check if a diagonal has been crossed
int diagonalCheck(char grid[][GRID])
{
    if ((grid[0][0] == grid[1][1]
         && grid[1][1] == grid[2][2]
         && grid[0][0] != ' ')
        || (grid[0][2] == grid[1][1]
            && grid[1][1] == grid[2][0]
            && grid[0][2] != ' '))
        return 1;

    return 0;
}

// Check if the game is over
int isGameOver(char grid[][GRID])
{
    return (rowCheck(grid) || columnCheck(grid)
            || diagonalCheck(grid));
}

// Play the Tic-Tac-Toe game
void startTicTacToe(int firstTurn)
{
    char grid[GRID][GRID];
    int moves[GRID * GRID];

    initializeGame(grid, moves);
    displayInstructions();

    int moveIndex = 0, row, col;

    while (!isGameOver(grid) && moveIndex != GRID * GRID) {
        if (firstTurn == AI) {
            char tempGrid[3][3];
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    tempGrid[i][j] = grid[i][j] == 'X' ? 'x' : grid[i][j] == 'O' ? 'o' : '_';
                }
            }
            struct Position nextMove = calculateBestMove(tempGrid);
            row = nextMove.row;
            col = nextMove.col;

            grid[row][col] = AI_MOVE;
            printf("AI places %c in cell %d %d\n", AI_MOVE, row, col);
            displayGrid(grid);
            moveIndex++;
            firstTurn = USER;
        } else if (firstTurn == USER) {
            int move;
            printf("Enter your move (1-9): ");
            scanf("%d", &move);
            if (move < 1 || move > 9) {
                printf("Invalid input! Choose a number between 1 and 9.\n");
                continue;
            }
            row = (move - 1) / GRID;
            col = (move - 1) % GRID;
            if (grid[row][col] == ' ') {
                grid[row][col] = USER_MOVE;
                displayGrid(grid);
                moveIndex++;
                if (isGameOver(grid)) {
                    announceWinner(USER);
                    return;
                }
                firstTurn = AI;
            } else {
                printf("Cell %d is occupied. Try again.\n", move);
            }
        }
    }

    if (!isGameOver(grid) && moveIndex == GRID * GRID)
        printf("It's a draw!\n");
    else {
        firstTurn = (firstTurn == AI) ? USER : AI;
        announceWinner(firstTurn);
    }
}
int main()
{
    startTicTacToe(AI);
    return 0;
}

Conclusion: Tic-Tac-Toe Game C++ Project

This Tic-Tac-Toe Game in C++ Project implementation comes under the top project for college students. Building of AI opponent with the Minimax Algorithm is new to learn. In this Tic-Tac-Toe Game Project, C/C++ programmers and seasoned pros will go through the ins and outs of game logic, recursion, and artificial intelligence.

Thanks for visiting codehelping.com, for more such exciting projects must visit: Link

Post navigation

❮ Previous Post: Build Snake Game in C++: 2025 CodeHelping
Next Post: Efficient Library Management System in C++: Source Code 2025 ❯

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • Home
  • Projects
  • Blog
  • Contact Us
  • About Us

Copyright © 2025 codehelping.com.

Theme: Oceanly by ScriptsTown

Social Chat is free, download and try it now here!