Sudoku Puzzle Game using JavaScript

Sudoku Puzzle Game using JavaScript

February 13, 2023


Learn How to Build Sudoku Puzzle Game using JavaScript

today I'm going to teach you how to make Sudoku Puzzle Game using JavaScript. 

Step 1) Add HTML:

Example

Convert Fahrenheit to Celsius

<div class="container">
   <h1>Sudoku</h1>
   <div class="mistake">Mistake: <span id="mistake">0</span>/3</div>
   <div id="gameBoard"></div>
   <div id="digits"></div>
   <div id="delete">
      <i class="fa fa-trash"></i>
   </div>
</div>



Step 2) Add CSS:

Example

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
} 
@import url('https://fonts.googleapis.com/css2?family=Anton&family=Roboto:wght@100;400;700&family=Rubik+Bubbles&display=swap');
 *{
     box-sizing: border-box;
}
 body{
     font-family: 'Anton', sans-serif;
}
 .container{
     height: 100vh;
     width: 100%;
     text-align: center;
}
 .container h1{
     font-size: 40px;
     padding-top: 20px;
}
 .container .mistake{
     background: rgb(76,204,255);
     padding: 10px;
     width: 60vmin;
     font-size: 24px;
     margin: 20px auto;
     color: #fff;
     border-radius: 10px;
     border: 2px solid #000;
}
 #gameBoard{
     height: 60vmin;
     width: 60vmin;
     background: #fff;
     margin: 0 auto;
     display: flex;
     flex-wrap: wrap;
     border: 3px solid #000;
}
 .tile{
     height: calc(100% / 9);
     width: calc(100% / 9);
     border: 1px solid #ccc;
     font-size: 30px;
     display: flex;
     justify-content: center;
     align-items: center;
     background: #fff;
}
 .filled{
     background: #f2f2f2;
}
 .select-tile{
     background: rgba(76,204,255, 0.5);
}
 #digits{
     width: 60vmin;
     display: flex;
     margin: 20px auto;
}
 #digits .tile{
     background: rgb(76,204,255);
     border-radius: 10px;
     border: 1px solid #000;
     color: #fff;
     cursor: pointer;
}
 .border-right{
     border-right: 2px solid #000;
}
 .border-bottom{
     border-bottom: 2px solid #000;
}
 #delete{
     color: #f00;
     font-size: 30px;
     cursor: pointer;
}
 .danger{
     color: #f00;
}
 @media (max-width:600px) {
     .tile{
         font-size: 18px;
    }
}
 @media (max-width:400px) {
     .tile{
         font-size: 16px;
    }
}



Step 3) Add JavaScript:

Example

const gameBoard = document.querySelector("#gameBoard");
const digits = document.querySelector("#digits");
const deleteNum = document.querySelector("#delete");
const mistake = document.querySelector("#mistake");
let lastSelected = null;
let error = 0;

//puzzle
const puzzle = [
   "8-6-1----",
   "--3-64-9-",
   "9-----816",
   "-8-396---",
   "7-2-4-3-9",
   "---572-8-",
   "521-----4",
   "-3-75-2--",
   "----2-1-5",
];

//puzzle solution
const solution = [
   "856917423",
   "213864597",
   "947235816",
   "185396724",
   "762148359",
   "394572681",
   "521683974",
   "439751268",
   "678429135",
];

//when window load puzzle create
window.onload = (() => {
   for (let i = 0; i < 9; i++) {
      for (let j = 0; j < 9; j++) {
         const div = document.createElement("div");
         div.classList.add("tile");
         div.addEventListener("click", selectTile);
         div.setAttribute("row", i);
         div.setAttribute("col", j);


         if (puzzle[i][j] != "-") {
            div.innerText = puzzle[i][j];
            div.classList.add("filled");
         }

         if (i == 2 || i == 5) {
            div.classList.add("border-bottom");
         }

         if (j == 2 || j == 5) {
            div.classList.add("border-right");
         }
         gameBoard.appendChild(div);
      }
   }

   // creating digits
   for (let i = 0; i < 9; i++) {
      const div = document.createElement("div");
      div.classList.add("tile");
      div.addEventListener("click", addNumber);
      div.innerText = i + 1;
      div.style.height = gameBoard.querySelector(".tile").clientHeight + "px";
      digits.appendChild(div);
   }
});

//select Tile
function selectTile() {
   if (lastSelected != null) {
      lastSelected.classList.remove("select-tile");
   }
   lastSelected = this;
   lastSelected.classList.add("select-tile");
}

//add digits (0-9) to Tile
function addNumber() {
   if (lastSelected.innerText == "" || lastSelected.classList.contains("danger")) {
      lastSelected.innerText = this.innerText;
   }

   let row = lastSelected.getAttribute("row");
   let col = lastSelected.getAttribute("col");
   if (solution[row][col] == lastSelected.innerText) {
      lastSelected.classList.remove("danger");

   } else {
      lastSelected.classList.add("danger");
      addErrorandDisplay();
   }

   if (error > 2) {
      alert("You Lost!");
      location.reload();
   }

   if (isAllTilesFilled()) {
      const allTiles = gameBoard.querySelectorAll(".tile");
      let userAnswer = [...allTiles].map((tile) => {
         return tile.innerText;
      });
      let num = 0;
      for (let i = 0; i < 9; i++) {
         for (let j = 0; j < 9; j++) {
            if (solution[i][j] != userAnswer[num]) {
               allTiles[num].classList.add("danger");
            }
            num++
         }
      }

      let dangerClass = [...allTiles].some((tile) => {
         return tile.classList.contains("danger");
      });

      if (dangerClass) {
         if (error > 2) {
            alert("you lost!");
            location.reload();
         }
      } else {
         alert("Congratuations! You win the puzzle!");
      }
   }
}

//delete number of Tile
deleteNum.onclick = () => {
   if (!lastSelected.classList.contains("filled")) {
      lastSelected.innerText = "";

   }
}

//check again any wrong numbers in any tile
function addErrorandDisplay() {
   error++;
   mistake.innerText = error;
}

//check all tiles filled or not
function isAllTilesFilled() {
   const allTiles = gameBoard.querySelectorAll(".tile");
   return [...allTiles].every((tile) => {
      return tile.innerText != "";
   });
}
Try this code