Create and solve image puzzle
HTML
<div class="game-container">
<h2>đź§© Robotime Puzzle Challenge</h2>
<div id="overlay">
<div id="countdown">3</div>
</div>
<div class="info-bar">
<div>⏱ Time: <span id="timer">0</span>s</div>
</div>
<div id="puzzle"></div>
<button id="restartBtn">Shuffle Again</button>
</div>
CSS
body{
font-family:Arial,sans-serif;
text-align:center;
background:#f5f5f5;
margin:20px;
}
.game-container{
max-width:700px;
margin:auto;
}
.info-bar{
margin:15px 0;
font-size:20px;
font-weight:bold;
}
#puzzle{
width:500px;
height:500px;
margin:auto;
display:grid;
grid-template-columns:repeat(5,1fr);
grid-template-rows:repeat(5,1fr);
gap:2px;
border:4px solid #444;
background:#444;
}
.tile{
cursor:pointer;
background-size:500px 500px;
border:none;
user-select:none;
transition:transform .15s;
}
.tile:hover{
transform:scale(1.03);
}
.selected{
outline:4px solid #ffcc00;
}
#restartBtn{
margin-top:20px;
padding:10px 25px;
font-size:16px;
cursor:pointer;
}
#overlay{
position:fixed;
inset:0;
background:rgba(0,0,0,.8);
display:flex;
justify-content:center;
align-items:center;
z-index:999;
}
#countdown{
color:white;
font-size:120px;
font-weight:bold;
}
JavaScript
const imageUrl =
"https://community.robotime.com/uploads/default/original/3X/3/e/3ed4a8377800a78a093cd15744700c924d78b162.jpeg";
const size = 5;
const totalPieces = size * size;
const puzzle = document.getElementById("puzzle");
const timerEl = document.getElementById("timer");
const overlay = document.getElementById("overlay");
const countdownEl = document.getElementById("countdown");
const restartBtn = document.getElementById("restartBtn");
let pieces = [];
let selectedTile = null;
let timer = 0;
let timerInterval = null;
function createPieces() {
pieces = [];
for (let i = 0; i < totalPieces; i++) {
pieces.push(i);
}
shuffle(pieces);
renderPuzzle();
}
function shuffle(arr) {
for (let i = arr.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
function renderPuzzle() {
puzzle.innerHTML = "";
pieces.forEach((pieceIndex, currentIndex) => {
const tile = document.createElement("div");
tile.className = "tile";
const row = Math.floor(pieceIndex / size);
const col = pieceIndex % size;
tile.style.backgroundImage = `url(${imageUrl})`;
tile.style.backgroundPosition =
`-${col * 100}px -${row * 100}px`;
tile.dataset.index = currentIndex;
tile.addEventListener("click", () => handleTileClick(tile));
puzzle.appendChild(tile);
});
}
function handleTileClick(tile) {
if (!timerInterval) return;
if (!selectedTile) {
selectedTile = tile;
tile.classList.add("selected");
return;
}
if (selectedTile === tile) {
tile.classList.remove("selected");
selectedTile = null;
return;
}
const firstIndex =
parseInt(selectedTile.dataset.index);
const secondIndex =
parseInt(tile.dataset.index);
[pieces[firstIndex], pieces[secondIndex]] =
[pieces[secondIndex], pieces[firstIndex]];
selectedTile = null;
...