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 != "";
});
}