How To Create Tic-Tac-Toe Game With JavaScript

Learn to create tic tac toe game with javascript.

HTML

<div class="container">
 <div class="game_container">
  <div class="grid">
   <div class="row">
    <div class="square" id="cell1" data-position="1"></div>
    <div class="square" id="cell2" data-position="2"></div>
    <div class="square" id="cell3" data-position="3"></div>
   </div>
   <div class="row">
    <div class="square" id="cell4" data-position="4"></div>
    <div class="square" id="cell5" data-position="5"></div>
    <div class="square" id="cell6" data-position="6"></div>
   </div>
   <div class="row">
    <div class="square" id="cell7" data-position="7"></div>
    <div class="square" id="cell8" data-position="8"></div>
    <div class="square" id="cell9" data-position="9"></div>
   </div>
  </div>
 </div>
 <div class="result_container">
  <h2 class="game_result">Result</h2>
  <button id="btnPlay">Play</button>
 </div>
</div>

CSS

html {
    box-sizing: border-box;
}

*,
*::before,
*::after {
    box-sizing: inherit;
}

body {
    padding: 0;
    margin: 0;
    height: 100vh;
}

.container {
    width: 1200px;
    display: flex;
    flex-direction: column;
    margin: 50px auto;
}

.game_container {
    width: 600px;
    margin: 0 auto;

}

.grid {
    width: 50%;
    margin: 0 auto;
}

.row {
    display: flex;
}

.square {
    width: 100px;
    height: 80px;
    border: 1px solid #000;
    padding: 20px;
    font-size: 40px;
    text-align: center;
    line-height: 50px;
}

#cell1,
#cell4,
#cell7 {
    border-left: none;
}

#cell1,
#cell2,
#cell3 {
    border-top: none;
}

#cell7,
#cell8,
#cell9 {
    border-bottom: none;
}

#cell3,
#cell6,
#cell9 {
    border-right: none;
}

.x-mark {
    color: green;
}

.o-mark {
    color: red;
}

.result_container {
    width: 400px;
    margin: 50px auto;
}

button {
    font-size: 22px;
    padding: 7px 15px;
    background-color: aquamarine;
    cursor: pointer;
}

JS

let square = document.querySelectorAll(".square");
let button = document.querySelector('button');
let game_over = false;

square.forEach(ele => {
    ele.addEventListener('click', player)
})

function player() {
    if (!game_over) {
        let getClass = this.getAttribute("class");
        if (getClass.indexOf("marked") < 0) {
            this.classList.add("x-mark", "marked");
            this.innerHTML = "X";
            getPosition(this.dataset.position, "x-mark");
            computer();
        } else {
            return
        }
        if (document.querySelectorAll('.marked').length === 9 && game_over === false) {
            displayResult('Draw!', 'draw');
            finished = true;
        }
    }
}
function computer() {
    let unmarked = document.querySelectorAll(".square:not(.marked)");
    if (unmarked.length > 0) {
        let randPosition = Math.floor(Math.random() * unmarked.length);
        let randCell = unmarked[randPosition];
        randCell.classList.add("o-mark", "marked");
        randCell.innerHTML = "O"
        getPosition(randCell.dataset.position, "o-mark");
    } else {
        return;
    }


}

function getPosition(pos, mark) {
    let winningPos = [[1, 2, 3], [1, 4, 7], [1, 5, 9], [2, 5, 8], [3, 6, 9], [3, 5, 7], [4, 5, 6], [7, 8, 9]]
    if (document.querySelectorAll(".x-mark").length >= 3 || document.querySelectorAll(".o-mark").length >= 3) {
        winningPos.forEach((element) => {
            if (game_over === true) {
                return false;
            } else {
                if (element.indexOf(Number(pos)) >= 0) {
                    let marksInARow = 0;
                    element.forEach((ele) => {
                        let classNames = document.getElementById("cell" + ele).getAttribute('class');
                        if (classNames.indexOf(mark) >= 0) {
                            marksInARow++;
                            if (marksInARow === 3) {
                                game_over = true;
                                if (mark === "x-mark") {
                                    displayResult("You Win!", "win")
                                } else if (mark === "o-mark") {
                                    displayResult("You Lost!", "lost")
                                    return false;
                                }
                            }
                        }
                    })

                }
            }
        })
    }
}

function displayResult(message) {
    document.querySelector('.game_result').innerHTML = 'Result:' + " " + message;
}
button.addEventListener('click', reset);

function reset() {
    document.querySelector('.game_result').innerHTML = 'Result';
    square.forEach(ele => {
        ele.classList.remove('x-mark', 'o-mark', 'marked');
        ele.innerHTML = "";
    })
    game_over = false;
}