Open In App

Simple Tic-Tac-Toe Game using JavaScript

Last Updated : 06 Feb, 2025
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

This is a simple and interactive Tic Tac Toe game built using HTML, CSS, and JavaScript. Players take turns to mark X and O on the grid, with automatic win detection and the option to reset or start a new game.

What We’re Going to Create

  • Players take turns marking X and O on a 3×3 grid, with real-time interaction.
  • The game checks for a winner or a draw, displaying messages accordingly.
  • The layout adapts to different screen sizes, with a reset button to start a new game.

Project Preview

Screenshot-2025-01-25-125249

Simple Tic-Tac-Toe Game using JavaScript

Simple Tic-Tac-Toe Game – HTML and CSS Code

This Tic Tac Toe game features a simple yet interactive design, allowing two players to take turns marking X and O on a 3×3 grid. The layout is responsive, with a reset button to restart the game.

<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        body {
            background-color: lightcyan;
            text-align: center;
        }
        .container {
            height: 70vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .game {
            height: 60vmin;
            width: 60vmin;
            display: flex;
            flex-wrap: wrap;
            gap: 1.5vmin;
            justify-content: center;
        }
        .box {
            height: 18vmin;
            width: 18vmin;
            border-radius: 1rem;
            border: none;
            box-shadow: 0 0 1rem rgba(0, 0, 0, 0.3);
            font-size: 8vmin;
            color: red;
            background-color: yellow;
        }
        #reset {
            padding: 1rem;
            font-size: 1.25rem;
            background: #191913;
            color: white;
            border-radius: 1rem;
            border: none;
        }
        .box:hover {
            background-color: chocolate;
        }
        #new-btn {
            padding: 1rem;
            font-size: 1.25rem;
            background: #191913;
            color: white;
            border-radius: 1rem;
            border: none;
        }
        #msg {
            font-size: 8vmin;
        }
        .msg-container {
            height: 30vmin;
        }
        .hide {
            display: none;
        }
    </style>
</head>
<body>
    <div class="msg-container hide">
        <p id="msg">Winner</p>
        <button id="new-btn">New Game</button>
    </div>
    <main>
        <h1>Tic Tac Toe</h1>
        <div class="container">
            <div class="game">
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
            </div>
        </div>
        <button id="reset">Reset Game</button>
    </main>
</body>
</html>

In this example

  • The game board is a flexbox-based grid inside a .container, ensuring a centered and responsive design.
  • Buttons for each cell have hover effects, rounded corners, and shadows, enhancing user experience.
  • The winner message container (.msg-container) is hidden by default and appears when the game ends, with buttons to start a new game or reset.

Simple Tic-Tac-Toe Game – JavaScript code

The JavaScript code manages the gameplay of Tic Tac Toe, including alternating turns, detecting winners based on patterns, and handling game resets.

let boxes = document.querySelectorAll('.box');
let resetBtn = document.querySelector('#reset');
let turnO = true; // Player O starts
let newGameBtn = document.querySelector('#new-btn');
let msgContainer = document.querySelector('.msg-container');
let msg = document.querySelector('#msg');

const winPatterns = [
    [0, 1, 2],
    [0, 3, 6],
    [0, 4, 8],
    [1, 4, 7],
    [2, 5, 8],
    [2, 4, 6],
    [3, 4, 5],
    [6, 7, 8]
];

boxes.forEach((box) => {
    box.addEventListener('click', function () {
        if (turnO) {
            box.innerText = 'O';
            box.style.color = 'green';
            turnO = false;
            box.disabled = true;
            checkWinner();
        } else {
            box.innerText = 'X';
            box.style.color = 'black';
            turnO = true;
            box.disabled = true;
            checkWinner();
        }
    });
});

const enableBoxes = () => {
    for (let box of boxes) {
        box.disabled = false;
        box.innerText = "";
    }
};

const disableBoxes = () => {
    for (let box of boxes) {
        box.disabled = true;
    }
};

const showWinner = (winner) => {
    msg.innerText = `Congratulations, Winner is ${winner}`;
    msgContainer.classList.remove('hide');
    disableBoxes();
};

const checkWinner = () => {
    let hasWin = false;
    for (let pattern of winPatterns) {
        let pos1Val = boxes[pattern[0]].innerText;
        let pos2Val = boxes[pattern[1]].innerText;
        let pos3Val = boxes[pattern[2]].innerText;

        if (pos1Val !== "" && pos2Val!=="" && pos3Val!=="" 
            && pos1Val === pos2Val && pos2Val === pos3Val) {
            showWinner(pos1Val);
            hasWin = true;
            return;
        }
    }

    if (!hasWin) {
        const allBoxes = [...boxes].every((box) => box.innerText !== "");
        if (allBoxes) {
            msgContainer.classList.remove('hide');
            msg.innerText = 'Match Drawn';
        }
    }
};

const resetGame = () => {
    turnO = true;
    enableBoxes();
    msgContainer.classList.add('hide');
};

newGameBtn.addEventListener('click', resetGame);
resetBtn.addEventListener('click', resetGame);

In this example

  • The turnO variable tracks the player, placing ‘X’ or ‘O’ on each button click and switching turns.
  • box.addEventListener(‘click’, …) detects clicks, marks the cell, and checks for a winner after each move.
  • checkWinner() scans predefined win patterns to see if any row, column, or diagonal has three identical marks.
  • resetGame() clears the board, re-enables boxes, and hides the winner message for a fresh start.
  • showWinner() reveals the winning message, disables all grid buttons, and stops further moves.

Simple Tic-Tac-Toe Game – Complete code

<html>
<head>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        body {
            background-color: lightcyan;
            text-align: center;
        }
        .container {
            height: 70vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .game {
            height: 60vmin;
            width: 60vmin;
            display: flex;
            flex-wrap: wrap;
            gap: 1.5vmin;
            justify-content: center;
        }
        .box {
            height: 18vmin;
            width: 18vmin;
            border-radius: 1rem;
            border: none;
            box-shadow: 0 0 1rem rgba(0,0,0,0.3);
            font-size: 8vmin;
            color: red;
            background-color: yellow;
        }
        #reset {
            padding: 1rem;
            font-size: 1.25rem;
            background: #191913;
            color: white;
            border-radius: 1rem;
            border: none;
        }
        .box:hover {
            background-color: chocolate;
        }
        #new-btn {
            padding: 1rem;
            font-size: 1.25rem;
            background: #191913;
            color: white;
            border-radius: 1rem;
            border: none;
        }
        #msg {
            font-size: 8vmin;
        }
        .msg-container {
            height: 30vmin;
        }
        .hide {
            display: none;
        }
    </style>
</head>
<body>
    <div class="msg-container hide">
        <p id="msg">Winner</p>
        <button id="new-btn">New Game</button>
    </div>
    <main>
        <h1>Tic Tac Toe</h1>
        <div class="container">
            <div class="game">
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
                <button class="box"></button>
            </div>
        </div>
        <button id="reset">Reset Game</button>
    </main>
    <script>
        let boxes = document.querySelectorAll('.box');
        let resetBtn = document.querySelector('#reset');
        let turnO = true; // Player O starts
        let newGameBtn = document.querySelector('#new-btn');
        let msgContainer = document.querySelector('.msg-container');
        let msg = document.querySelector('#msg');

        const winPatterns = [
            [0, 1, 2],
            [0, 3, 6],
            [0, 4, 8],
            [1, 4, 7],
            [2, 5, 8],
            [2, 4, 6],
            [3, 4, 5],
            [6, 7, 8]
        ];

        boxes.forEach((box) => {
            box.addEventListener('click', function () {
                if (turnO) {
                    box.innerText = 'O';
                    box.style.color = 'green';
                    turnO = false;
                    box.disabled = true;
                    checkWinner();
                } else {
                    box.innerText = 'X';
                    box.style.color = 'black';
                    turnO = true;
                    box.disabled = true;
                    checkWinner();
                }
            });
        });

        const enableBoxes = () => {
            for (let box of boxes) {
                box.disabled = false;
                box.innerText = "";
            }
        };

        const disableBoxes = () => {
            for (let box of boxes) {
                box.disabled = true;
            }
        };

        const showWinner = (winner) => {
            msg.innerText = `Congratulations, Winner is ${winner}`;
            msgContainer.classList.remove('hide');
            disableBoxes();
        };

        const checkWinner = () => {
            let hasWin = false;
            for (let pattern of winPatterns) {
                let pos1Val = boxes[pattern[0]].innerText;
                let pos2Val = boxes[pattern[1]].innerText;
                let pos3Val = boxes[pattern[2]].innerText;

                if (pos1Val !== "" && pos2Val!=="" && pos3Val!=="" && 
                    pos1Val === pos2Val && pos2Val === pos3Val) {
                    showWinner(pos1Val);
                    hasWin = true;
                    return;
                }
            }

            if (!hasWin) {
                const allBoxes = [...boxes].every((box) => box.innerText !== "");
                if (allBoxes) {
                    msgContainer.classList.remove('hide');
                    msg.innerText = 'Match Drawn';
                }
            }
        };

        const resetGame = () => {
            turnO = true;
            enableBoxes();
            msgContainer.classList.add('hide');
        };

        newGameBtn.addEventListener('click', resetGame);
        resetBtn.addEventListener('click', resetGame);
    </script>
</body>
</html>


Next Article

Similar Reads

three90RightbarBannerImg