Tic Tac Toe Game using HTML CSS & JavaScript

18

Tic Tac Toe Game using HTML CSS & JavaScriptHey friends, today in this blog you’ll learn how to create a Tic Tac Toe Game using HTML CSS & JavaScript. Earlier I have shared a blog on how to create Quiz Web Application using JavaScript and now it’s time to create Tic Tac Toe Game using pure JavaScript.

 
Tic tac toe is a multiplayer game and the players of this game have to position their marks(sign) so that they can construct a continuous line of three cells or boxes vertically, horizontally, or diagonally. An opponent can stop a win by blocking the end of the opponent’s line.

In our program or design [Tic Tac Toe Game], at first, on the webpage, there is a selection box with the game title and two buttons which are labeled as “Player(X)” and “Player(O)”. Users must select one option or button to continue the game. If the user selects the X then the bot will be O and if the user selects the O then the bot will be X. Once the user selects one of them, the selection box will disappear and the playboard is visible.

There are the player names at the top in the playboard section and it indicates or shows whose turn is now. At the center of the webpage, there is a tic tac toe play area with nine square boxes. Once you click on the particular box then there is visible a sign or icon which you have chosen on the selection box. Once you click on any box then after a couple of seconds the bot will automatically select the box which is not selected by you or the bot before, and the opposite icon is visible there means if your icon is X then the bot will have O.


Once a match is won by someone, the playboard section will be hidden and the result box appears with the winner sign or icon and a replay button. If no one wins the match and all nine-box selected then again the playboard section is hidden and the result box appears with “Match has been drawn text” and a replay button. Once you click on the replay button, the current page reloads and you can play again. Actually, the bot of this game is no clever and intelligent and I did use the minimax algorithm in it so you can easily win the match but from the source codes of this game, you can learn many more things.

Video Tutorial of Tic Tac Toe Game in JavaScript

 
In the video, you have seen how this tic tac toe game work and how I created this game using HTML CSS & JavaScript. The design and layout of this game are purely created using HTML & CSS but to make it workable I used JavaScript. If you’re a beginner then you may have difficulty understanding the JavaScript codes of this game but I tried my best to explain each JavaScript line with comments so don’t worry once you download the codes you can easily understand the codes.

You might like this: 

Tic Tac Toe Game in JavaScript [Source Codes]

To create this program [Tic Tac Toe Game]. First, you need to create three files, HTML File, CSS File, and JavaScript File. After creating these files just paste the following codes into your files. You can also download the source code files of this game from the given download button.


First, create an HTML file with the name of index.html and paste the given codes in your HTML file. Remember, you’ve to create a file with .html extension.

<!DOCTYPE html>
<!-- Created By CodingNepal - www.youtube.com/codingnepal || www.codingnepalweb.com -->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Tic Tac Toe Game | CodingNepal</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"/>
</head>
<body>
  <!-- select box -->
  <div class="select-box">
    <header>Tic Tac Toe</header>
    <div class="content">
      <div class="title">Select which you want to be?</div>
      <div class="options">
        <button class="playerX">Player (X)</button>
        <button class="playerO">Player (O)</button>
      </div>
      <div class="credit">Created By <a href="https://www.youtube.com/codingnepal" target="_blank">CodingNepal</a></div>
    </div>
  </div> 

  <!-- playboard section -->
  <div class="play-board">
    <div class="details">
      <div class="players">
        <span class="Xturn">X's Turn</span>
        <span class="Oturn">O's Turn</span>
        <div class="slider"></div>
      </div>
    </div>
    <div class="play-area">
      <section>
        <span class="box1"></span>
        <span class="box2"></span>
        <span class="box3"></span>
      </section>
      <section>
        <span class="box4"></span>
        <span class="box5"></span>
        <span class="box6"></span>
      </section>
      <section>
        <span class="box7"></span>
        <span class="box8"></span>
        <span class="box9"></span>
      </section>
    </div>
  </div>

  <!-- result box -->
  <div class="result-box">
    <div class="won-text"></div>
    <div class="btn"><button>Replay</button></div>
  </div>

  <script src="script.js"></script>

</body>
</html>

Second, create a CSS file with the name of style.css and paste the given codes in your CSS file. Remember, you’ve to create a file with .css extension.

@import url('https://fonts.googleapis.com/css2?family=Poppins:[email protected];300;400;500;600;700&display=swap');
*{
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Poppins', sans-serif;
}
::selection{
  color: #fff;
  background:#56baed;
}
body{
  background:#56baed;
}
.select-box, .play-board, .result-box{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  transition: all 0.3s ease;
}
.select-box{
  background: #fff;
  padding: 20px 25px 25px;
  border-radius: 5px;
  max-width: 400px;
  width: 100%;
}
.select-box.hide{
  opacity: 0;
  pointer-events: none;
}
.select-box header{
  font-size: 30px;
  font-weight: 600;
  padding-bottom: 10px;
  border-bottom: 1px solid lightgrey;
}
.select-box .title{
  font-size: 22px;
  font-weight: 500;
  margin: 20px 0;
}
.select-box .options{
  display: flex;
  width: 100%;
}
.options button{
  width: 100%;
  font-size: 20px;
  font-weight: 500;
  padding: 10px 0;
  border: none;
  background: #56baed;
  border-radius: 5px;
  color: #fff;
  outline: none;
  cursor: pointer;
  transition: all 0.3s ease;
}
.options button:hover,
.btn button:hover{
  transform: scale(0.96);
}
.options button.playerX{
  margin-right: 5px;
}
.options button.playerO{
  margin-left: 5px;
}
.select-box .credit{
  text-align: center;
  margin-top: 20px;
  font-size: 18px;
  font-weight: 500;
}
.select-box .credit a{
  color: #56baed;
  text-decoration: none;
}
.select-box .credit a:hover{
  text-decoration: underline;
}

.play-board{
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0.9);
}
.play-board.show{
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}
.play-board .details{
  padding: 7px;
  border-radius: 5px;
  background: #fff;
}
.play-board .players{
  width: 100%;
  display: flex;
  position: relative;
  justify-content: space-between;
}
.players span{
  position: relative;
  z-index: 2;
  color: #56baed;
  font-size: 20px;
  font-weight: 500;
  padding: 10px 0;
  width: 100%;
  text-align: center;
  cursor: default;
  user-select: none;
  transition: all 0.3 ease;
}
.players.active span:first-child{
  color: #fff;
}
.players.active span:last-child{
  color: #56baed;
}
.players span:first-child{
  color: #fff;
}
.players .slider{
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 100%;
  background: #56baed;
  border-radius: 5px;
  transition: all 0.3s ease;
}
.players.active .slider{
  left: 50%;
}
.players.active span:first-child{
  color: #56baed;
}
.players.active span:nth-child(2){
  color: #fff;
}
.players.active .slider{
  left: 50%;
}
.play-area{
  margin-top: 20px;
}
.play-area section{
  display: flex;
  margin-bottom: 1px;
}
.play-area section span{
  display: block;
  height: 90px;
  width: 90px;
  margin: 2px;
  color: #56baed;
  font-size: 40px;
  line-height: 80px;
  text-align: center;
  border-radius: 5px;
  background: #fff;
}

.result-box{
  padding: 25px 20px;
  border-radius: 5px;
  max-width: 400px;
  width: 100%;
  opacity: 0;
  text-align: center;
  background: #fff;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0.9);
}
.result-box.show{
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}
.result-box .won-text{
  font-size: 30px;
  font-weight: 500;
  display: flex;
  justify-content: center;
}
.result-box .won-text p{
  font-weight: 600;
  margin: 0 5px;
}
.result-box .btn{
  width: 100%;
  margin-top: 25px;
  display: flex;
  justify-content: center;
}
.btn button{
  font-size: 18px;
  font-weight: 500;
  padding: 8px 20px;
  border: none;
  background: #56baed;
  border-radius: 5px;
  color: #fff;
  outline: none;
  cursor: pointer;
  transition: all 0.3s ease;
}

Last, create a JavaScript file with the name of script.js and paste the given codes in your JavaScript file. Remember, you’ve to create a file with .js extension.

//I've tried to explain each JavaScript line with comments....Hope you'll understand

//selecting all required elements
const selectBox = document.querySelector(".select-box"),
selectBtnX = selectBox.querySelector(".options .playerX"),
selectBtnO = selectBox.querySelector(".options .playerO"),
playBoard = document.querySelector(".play-board"),
players = document.querySelector(".players"),
allBox = document.querySelectorAll("section span"),
resultBox = document.querySelector(".result-box"),
wonText = resultBox.querySelector(".won-text"),
replayBtn = resultBox.querySelector("button");

window.onload = ()=>{ //once window loaded
    for (let i = 0; i < allBox.length; i++) { //add onclick attribute in all available span
       allBox[i].setAttribute("onclick", "clickedBox(this)");
    }
}

selectBtnX.onclick = ()=>{
    selectBox.classList.add("hide"); //hide select box
    playBoard.classList.add("show"); //show the playboard section
}

selectBtnO.onclick = ()=>{ 
    selectBox.classList.add("hide"); //hide select box
    playBoard.classList.add("show"); //show the playboard section
    players.setAttribute("class", "players active player"); //set class attribute in players with players active player values
}

let playerXIcon = "fas fa-times"; //class name of fontawesome cross icon
let playerOIcon = "far fa-circle"; //class name of fontawesome circle icon
let playerSign = "X"; //this is a global variable beacuse we've used this variable inside multiple functions
let runBot = true; //this also a global variable with boolen value..we used this variable to stop the bot once match won by someone or drawn

// user click function
function clickedBox(element){
    if(players.classList.contains("player")){
        playerSign = "O"; //if player choose (O) then change playerSign to O
        element.innerHTML = `<i class="${playerOIcon}"></i>`; //adding circle icon tag inside user clicked element/box
        players.classList.add("active"); ///add active class in players
        element.setAttribute("id", playerSign); //set id attribute in span/box with player choosen sign
    }else{
        element.innerHTML = `<i class="${playerXIcon}"></i>`; //adding cross icon tag inside user clicked element/box
        players.classList.add("active"); //add active class in players
        element.setAttribute("id", playerSign); //set id attribute in span/box with player choosen sign
    }
    selectWinner(); //caliing selectWinner function
    element.style.pointerEvents = "none"; //once user select any box then that box can'be clicked again
    playBoard.style.pointerEvents = "none"; //add pointerEvents none to playboard so user can't immediately click on any other box until bot select
    let randomTimeDelay = ((Math.random() * 1000) + 200).toFixed(); //generating random number so bot will randomly delay to select unselected box
    setTimeout(()=>{
        bot(); //calling bot function
    }, randomTimeDelay); //passing random delay value
}

// bot auto select function
function bot(){
    let array = []; //creating empty array...we'll store unclicked boxes index
    if(runBot){ //if runBot is true
        playerSign = "O"; //change the playerSign to O so if player has chosen X then bot will O
        for (let i = 0; i < allBox.length; i++) {
            if(allBox[i].childElementCount == 0){ //if the box/span has no children means <i> tag
                array.push(i); //inserting unclicked boxes number/index inside array
            }
        }
        let randomBox = array[Math.floor(Math.random() * array.length)]; //getting random index from array so bot will select random unselected box
        if(array.length > 0){ //if array length is greater than 0
            if(players.classList.contains("player")){ 
                playerSign = "X"; //if player has chosen O then bot will X
                allBox[randomBox].innerHTML = `<i class="${playerXIcon}"></i>`; //adding cross icon tag inside bot selected element
                players.classList.remove("active"); //remove active class in players
                allBox[randomBox].setAttribute("id", playerSign); //set id attribute in span/box with player choosen sign
            }else{
                allBox[randomBox].innerHTML = `<i class="${playerOIcon}"></i>`; //adding circle icon tag inside bot selected element
                players.classList.remove("active"); //remove active class in players
                allBox[randomBox].setAttribute("id", playerSign); //set id attribute in span/box with player choosen sign
            }
            selectWinner(); //calling selectWinner function
        }
        allBox[randomBox].style.pointerEvents = "none"; //once bot select any box then user can't click on that box
        playBoard.style.pointerEvents = "auto"; //add pointerEvents auto in playboard so user can again click on box
        playerSign = "X"; //if player has chosen X then bot will be O right then we change the playerSign again to X so user will X because above we have changed the playerSign to O for bot
    }
}

function getIdVal(classname){
    return document.querySelector(".box" + classname).id; //return id value
}
function checkIdSign(val1, val2, val3, sign){ //checking all id value is equal to sign (X or O) or not if yes then return true
    if(getIdVal(val1) == sign && getIdVal(val2) == sign && getIdVal(val3) == sign){
        return true;
    }
}
function selectWinner(){ //if the one of following winning combination match then select the winner
    if(checkIdSign(1,2,3,playerSign) || checkIdSign(4,5,6, playerSign) || checkIdSign(7,8,9, playerSign) || checkIdSign(1,4,7, playerSign) || checkIdSign(2,5,8, playerSign) || checkIdSign(3,6,9, playerSign) || checkIdSign(1,5,9, playerSign) || checkIdSign(3,5,7, playerSign)){
        runBot = false; //passing the false boolen value to runBot so bot won't run again
        bot(); //calling bot function
        setTimeout(()=>{ //after match won by someone then hide the playboard and show the result box after 700ms
            resultBox.classList.add("show");
            playBoard.classList.remove("show");
        }, 700); //1s = 1000ms
        wonText.innerHTML = `Player <p>${playerSign}</p> won the game!`; //displaying winning text with passing playerSign (X or O)
    }else{ //if all boxes/element have id value and still no one win then draw the match
        if(getIdVal(1) != "" && getIdVal(2) != "" && getIdVal(3) != "" && getIdVal(4) != "" && getIdVal(5) != "" && getIdVal(6) != "" && getIdVal(7) != "" && getIdVal(8) != "" && getIdVal(9) != ""){
            runBot = false; //passing the false boolen value to runBot so bot won't run again
            bot(); //calling bot function
            setTimeout(()=>{ //after match drawn then hide the playboard and show the result box after 700ms
                resultBox.classList.add("show");
                playBoard.classList.remove("show");
            }, 700); //1s = 1000ms
            wonText.textContent = "Match has been drawn!"; //displaying draw match text
        }
    }
}

replayBtn.onclick = ()=>{
    window.location.reload(); //reload the current page on replay button click
}

That’s all, now you’ve successfully created a Tic Tac Toe Game using HTML CSS & JavaScript. If your code does not work or you’ve faced any error/problem then please download the source code files from the given download button. It’s free and a .zip file will be downloaded then you’ve to extract it.

 


Previous articleResponsive Filterable Image Gallery using HTML CSS & JavaScript
Next articleResponsive Image Lightbox using HTML CSS & JavaScript
CodingNepal is a blog where we post blogs related to HTML CSS JavaScript & PHP along with creative coding stuff and free source code files.

18 COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here