Skip to content

Commit

Permalink
Merge pull request #4514 from Anshika-17/main
Browse files Browse the repository at this point in the history
Puzzle game Added
  • Loading branch information
kunjgit authored Jun 16, 2024
2 parents 472c939 + 54271ee commit e7f7b52
Show file tree
Hide file tree
Showing 9 changed files with 414 additions and 3 deletions.
3 changes: 3 additions & 0 deletions Games/puzzle-game/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"liveServer.settings.port": 5501
}
27 changes: 27 additions & 0 deletions Games/puzzle-game/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# **Sliding Puzzle Game**

---

## **Description 📃**
Sliding Puzzle is a classic brain teaser game where the objective is to arrange a set of tiles or squares in a specific order by sliding them around a fixed grid. The game starts with the tiles in a scrambled state, and the player must rearrange them to match a target pattern or image.

## **Functionalities 🎮**
- Randomized initial tile configuration
- Sliding tiles by clicking or tapping on adjacent empty spaces
- Tracking the number of moves made by the player
- Ability to reset the game to the initial scrambled state
- Providing visual feedback on the progress towards the solved state

## **How to Play? 🕹️**
1. The game board consists of a grid of square tiles, with one tile missing to create an empty space.
2. The tiles are initially arranged in a scrambled order.
3. To move a tile, click or tap on the tile adjacent to the empty space. The selected tile will slide into the empty space.
4. Continue sliding the tiles around the grid until the tiles are arranged in the correct order or pattern.
5. The goal is to rearrange the tiles to match the target configuration as quickly as possible, using the fewest number of moves.
6. If you get stuck, you can reset the game to start over from the initial scrambled state.

## **Screenshots 📸**


## **Working Video 📹**

Binary file added Games/puzzle-game/favicon.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 57 additions & 0 deletions Games/puzzle-game/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sliding Puzzle Game</title>
<meta name="title" content="Sliding Puzzle Game">
<meta name="description" content="Sliding Puzzle Game, slide boxes">
<meta property="og:type" content="website">
<meta property="og:url" content="https://kostad02.github.io/Sliding-Puzzle-Game-JS">
<meta property="og:title" content="Sliding Puzzle Game">
<meta property="og:description" content="Sliding Puzzle Game, slide boxes">
<meta property="og:image" content="https://media.istockphoto.com/id/1391097609/vector/seamless-puzzle-piece-background-pattern.jpg?s=612x612&w=0&k=20&c=p1HdhY7QKCn4fDxI3EvPo2P5HHf04b3OPkzcSAnM5pM=">
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="https://kostad02.github.io/Sliding-Puzzle-Game-JS">
<meta property="twitter:title" content="Sliding Puzzle Game">
<meta property="twitter:description" content="Sliding Puzzle Game, slide boxes">
<meta property="twitter:image" content="https://media.istockphoto.com/id/1391097609/vector/seamless-puzzle-piece-background-pattern.jpg?s=612x612&w=0&k=20&c=p1HdhY7QKCn4fDxI3EvPo2P5HHf04b3OPkzcSAnM5pM=">
<link href="https://fonts.googleapis.com/css2?family=Montserrat&display=swap" rel="stylesheet">
<link rel="shortcut icon" href="./favicon.jpg" type="image/x-icon">
<link rel="stylesheet" href="./style.css">
</head>
<body>
<main>
<section class="container">
<h1 class="title">Sliding Puzzle Game</h1>
<div class="puzzle-board">
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile"></div>
<div class="puzzle-tile empty-tile" id="tile-empty"></div>
</div>
<div class="buttons">
<button class="easyBtn">Easy</button>
<button class="mediumBtn">Medium</button>
<button class="hardBtn">Hard</button>
<button class="shuffleBtn">Shuffle</button>
</div>
</section>
</main>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script src="./main.js"></script>
</body>
</html>
182 changes: 182 additions & 0 deletions Games/puzzle-game/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
const emptyTile = document.querySelector('#tile-empty');
const shuffleBtn = document.querySelector('.shuffleBtn');
const easyBtn = document.querySelector('.easyBtn');
const mediumBtn = document.querySelector('.mediumBtn');
const hardBtn = document.querySelector('.hardBtn');
const board = document.querySelector('.puzzle-board');
let tiles = document.querySelectorAll('.puzzle-tile');
let tilePositions = [];

let emptyTileIndex = 15;
let boardSize = 4;
let draggedTileIndex = 0;
let dragOverTileIndex = 0;

easyBtn.addEventListener('click', () => {
initGame(8);
});

mediumBtn.addEventListener('click', () => {
initGame(15);
});

hardBtn.addEventListener('click', () => {
initGame(24);
});

shuffleBtn.addEventListener('click', () => {
shuffleBoxes();
});

initGame();

function initGame(cube = 15) {
resetConfig();
initDefaultValues(cube);
initCubesHTML();
initStyles();
initTilePositions();
renderTiles();
initDragFunctions();
shuffleBoxes();
}

function initCubesHTML() {
board.innerHTML = "";
for (let i = 0; i < emptyTileIndex + 1; i++) {
if (i + 1 === emptyTileIndex) {
board.innerHTML += `
<div class="puzzle-tile empty-tile" id="tile-empty"></div>
`;
} else {
board.innerHTML += `
<div class="puzzle-tile"></div>
`;
}
}
tiles = document.querySelectorAll('.puzzle-tile');
}

function initStyles() {
if (emptyTileIndex === 8 || emptyTileIndex === 15 || emptyTileIndex === 24) {
const size = emptyTileIndex === 8 ? 3 : emptyTileIndex === 15 ? 4 : 5;
board.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
board.style.gridTemplateRows = `repeat(${size}, 1fr)`;
} else {
resetConfig();
initGame();
}
}

function initDefaultValues(cube) {
emptyTileIndex = cube;
boardSize = Math.sqrt(cube + 1);
draggedTileIndex = 0;
dragOverTileIndex = 0;
}

function resetConfig() {
emptyTileIndex = 15;
draggedTileIndex = 0;
dragOverTileIndex = 0;
boardSize = 4;
tiles = document.querySelectorAll('.puzzle-tile');
}

function initTilePositions() {
tilePositions = [];
for (let i = 0; i < emptyTileIndex + 1; i++) {
if (i === emptyTileIndex) {
tilePositions.push('');
} else {
tilePositions.push(i + 1);
}
}
}

function shuffleBoxes() {
for (let i = tilePositions.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[tilePositions[i], tilePositions[j]] = [tilePositions[j], tilePositions[i]];
}
renderTiles();
}

function initDragFunctions() {
tiles.forEach(tile => {
tile.addEventListener('dragstart', function () {
this.classList.add('dragging');
draggedTileIndex = Array.from(tiles).indexOf(this);
if (this.classList.contains('empty-tile')) {
draggedTileIndex = emptyTileIndex;
}
});
tile.addEventListener('dragover', function (event) {
event.preventDefault();
this.classList.add('drag-over');
dragOverTileIndex = Array.from(tiles).indexOf(this);
});
tile.addEventListener('dragenter', function (event) {
event.preventDefault();
});
tile.addEventListener('dragleave', function () {
this.classList.remove('drag-over');
});
tile.addEventListener('drop', function () {
const isAdjacent = (draggedTileIndex === dragOverTileIndex - 1 || draggedTileIndex === dragOverTileIndex + 1 ||
draggedTileIndex === dragOverTileIndex - boardSize || draggedTileIndex === dragOverTileIndex + boardSize);
if (draggedTileIndex !== undefined && dragOverTileIndex !== undefined && draggedTileIndex !== dragOverTileIndex && isAdjacent) {
const draggedTileIsTitled = !tiles[draggedTileIndex].classList.contains('empty-tile');
const dropTargetIsTitled = !tiles[dragOverTileIndex].classList.contains('empty-tile');
if ((draggedTileIsTitled && dropTargetIsTitled) || (!draggedTileIsTitled && !dropTargetIsTitled)) {
return;
}
[tilePositions[draggedTileIndex], tilePositions[dragOverTileIndex]] = [tilePositions[dragOverTileIndex], tilePositions[draggedTileIndex]];
renderTiles();
}
this.classList.remove('drag-over');
checkWin();
});
tile.addEventListener('dragend', function () {
this.classList.remove('dragging');
});
});
}

function checkWin() {
let isWon = true;
const size = boardSize * boardSize;
for (let i = 1; i <= size; i++) {
if (i !== tilePositions[i - 1]) {
if (i === size && tilePositions[i - 1] === '') {
continue;
}
isWon = false;
break;
}
}
if (isWon) {
displayAlert('Congrats', 'success', 'you won game');
initGame(emptyTileIndex);
}
}

function renderTiles() {
for (let i = 0; i < tiles.length; i++) {
const tile = tiles[i];
const tileNumber = tilePositions[i];
tile.innerText = tileNumber;
tile.setAttribute('draggable', true);
tile.classList.remove('empty-tile');
if (tileNumber === '') {
tile.innerText = '';
tile.setAttribute('draggable', false);
tile.classList.add('empty-tile');
emptyTileIndex = i;
}
}
}

function displayAlert(title, icon, text) {
Swal.fire({ title, icon, text });
}
Loading

0 comments on commit e7f7b52

Please sign in to comment.