DEV Community

Cover image for Tic Tac Toe Game With HTML and JS
Caner Demirci
Caner Demirci

Posted on

Tic Tac Toe Game With HTML and JS

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tic Tac Toe</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        html, body {
            background-color: #14bdac;
            width: 100%;
            height: 100%;
            padding: 1.5rem;
        }

        .grid {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: .5rem;
            width: 80%;
            height: 100%;
            margin: auto;
            background-color: #70757a;
        }
            .grid > div {
                background-color: #3fecdb;
                cursor: pointer;
                font-size: 3rem;
                font-weight: bold;
                color: #fff;
                display: flex;
                flex-direction: column;
                justify-content: center;
                transition: all .5s;
            }
            .grid > div:hover {
                opacity: .6;
            }
            .grid > div > div {
                text-align: center;
            }
    </style>
</head>
<body>
    <div id="grid" class="grid">
    </div>

    <script>
        const grid = document.getElementById('grid');

        var won = false;
        var freezeGame = false;
        var squaresHTML = '';
        var sqId = 0;
        var moveX = true;

        const squares = [];

        for (let r=0; r<3; r++) {
            for (let c=0; c<3; c++) {
                sqId++;
                squaresHTML += `<div id="${sqId}"><div></div></div>`;
                squares.push({ id: sqId, move: null });
            }
        }

        grid.innerHTML = squaresHTML;

        const squaresEL = document.querySelectorAll('#grid > div');

        squaresEL.forEach(s => s.addEventListener(
            'click',
            () => {                
                if (!freezeGame) {
                    square = squares.find(sq => sq.id == s.id);

                    if (!square.move) {
                        moveX = !moveX;
                        square.move = moveX ? 'X' : 'O';
                        s.querySelector('div').innerText = moveX ? 'X' : 'O';
                        s.style.backgroundColor = moveX ? 'royalblue' : 'tomato';

                        checkGame();
                    }
                }
            }
        ));

        function wonGame(one, two, three, character) {
            freezeGame = true;
            won = true;
            let anim = true;

            if (one == null && two == null && three == null && character == null) {
                gameOverAnimation(anim, function() {
                    squaresEL.forEach(s => s.style.backgroundColor = anim ? 'green' : 'yellow');
                    anim = !anim;
                }, function() {
                    alert('DRAW!');
                    location.reload();
                });
                return;
            }

            gameOverAnimation(anim, function() {
                squaresEL[one].style.backgroundColor = anim ? 'green' : 'yellow';
                squaresEL[two].style.backgroundColor = anim ? 'green' : 'yellow';
                squaresEL[three].style.backgroundColor = anim ? 'green' : 'yellow';
                anim = !anim;
            },function() {
                alert(`${character} won`);
                    location.reload();
                });
        }

        function gameOverAnimation(anim, animCallback, overCallback) {
            setInterval(function() {
                animCallback();
            }, 200);
            setTimeout(function() {
                overCallback();
            }, 2000);
        }

        function checkGame() {
            // Rows
            // first row
            if (squares[0].move == 'X' && squares[1].move == 'X' && squares[2].move == 'X') {
                wonGame(0, 1, 2, 'X');
            } else if (squares[0].move == 'O' && squares[1].move == 'O' && squares[2].move == 'O') {
                wonGame(0, 1, 2, 'O');
            }
            // second row
            if (squares[3].move == 'X' && squares[4].move == 'X' && squares[5].move == 'X') {
                wonGame(3, 4, 5, 'X');
            } else if (squares[3].move == 'O' && squares[4].move == 'O' && squares[5].move == 'O') {
                wonGame(3, 4, 5, 'O');
            }
            // third row
            if (squares[6].move == 'X' && squares[7].move == 'X' && squares[8].move == 'X') {
                wonGame(6, 7, 8, 'X');
            } else if (squares[6].move == 'O' && squares[7].move == 'O' && squares[8].move == 'O') {
                wonGame(6, 7, 8, 'O');
            }

            // first column
            if (squares[0].move == 'X' && squares[3].move == 'X' && squares[6].move == 'X') {
                wonGame(0, 3, 6, 'X');
            } else if (squares[0].move == 'O' && squares[3].move == 'O' && squares[6].move == 'O') {
                wonGame(0, 3, 6, 'O');
            }
            // second column
            if (squares[1].move == 'X' && squares[4].move == 'X' && squares[7].move == 'X') {
                wonGame(1, 4, 7, 'X');
            } else if (squares[1].move == 'O' && squares[4].move == 'O' && squares[7].move == 'O') {
                wonGame(1, 4, 7, 'O');
            }
            // third column
            if (squares[2].move == 'X' && squares[5].move == 'X' && squares[8].move == 'X') {
                wonGame(2, 5, 8, 'X');
            } else if (squares[2].move == 'O' && squares[5].move == 'O' && squares[8].move == 'O') {
                wonGame(2, 5, 8, 'O');
            }

            // left cross
            if (squares[0].move == 'X' && squares[4].move == 'X' && squares[8].move == 'X') {
                wonGame(0, 4, 8, 'X');
            } else if (squares[0].move == 'O' && squares[4].move == 'O' && squares[8].move == 'O') {
                wonGame(0, 4, 8, 'O');
            }
            // right cross
            if (squares[2].move == 'X' && squares[4].move == 'X' && squares[6].move == 'X') {
                wonGame(2, 4, 6, 'X');
            } else if (squares[2].move == 'O' && squares[4].move == 'O' && squares[6].move == 'O') {
                wonGame(2, 4, 6, 'X');
            }

            const nullSquaresNum = squares.filter(s => s.move == null);

            if (nullSquaresNum.length == 0 && !won) {
                wonGame(null, null, null, null);
            }
        }
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Top comments (0)