Skip to content

Commit 9a3fc36

Browse files
committed
feat: implement Number Sliding Puzzle game with move tracking and win detection
1 parent d98a13f commit 9a3fc36

2 files changed

Lines changed: 228 additions & 0 deletions

File tree

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import random
2+
3+
print("🧩 Emoji Sliding Puzzle Game 🧩")
4+
print("Arrange the numbers in correct order!\n")
5+
6+
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 0]
7+
8+
random.shuffle(numbers)
9+
10+
puzzle = [
11+
numbers[0:3],
12+
numbers[3:6],
13+
numbers[6:9]
14+
]
15+
16+
moves = 0
17+
def display_puzzle():
18+
print("\n🎮 Current Puzzle:\n")
19+
for row in puzzle:
20+
for item in row:
21+
if item == 0:
22+
print("⬜", end=" ")
23+
else:
24+
print(f"{item}️⃣", end=" ")
25+
print()
26+
27+
def find_positions(choice):
28+
empty_row = 0
29+
empty_col = 0
30+
number_row = -1
31+
number_col = -1
32+
33+
for i in range(3):
34+
for j in range(3):
35+
if puzzle[i][j] == 0:
36+
empty_row = i
37+
empty_col = j
38+
if puzzle[i][j] == choice:
39+
number_row = i
40+
number_col = j
41+
return number_row, number_col, empty_row, empty_col
42+
43+
44+
def move_tile(choice):
45+
global moves
46+
number_row, number_col, empty_row, empty_col = find_positions(choice)
47+
48+
if number_row == -1:
49+
print("⚠️ Number not found!")
50+
return
51+
if (
52+
abs(number_row - empty_row) == 1
53+
and number_col == empty_col
54+
) or (
55+
abs(number_col - empty_col) == 1
56+
and number_row == empty_row
57+
):
58+
59+
puzzle[empty_row][empty_col] = choice
60+
puzzle[number_row][number_col] = 0
61+
moves += 1
62+
print("✅ Tile moved successfully!")
63+
64+
else:
65+
print("❌ Invalid move! Tile must be next to empty space.")
66+
67+
def check_win():
68+
winning_puzzle = [
69+
[1, 2, 3],
70+
[4, 5, 6],
71+
[7, 8, 0]
72+
]
73+
return puzzle == winning_puzzle
74+
75+
def init():
76+
global moves
77+
while True:
78+
display_puzzle()
79+
print(f"\n🔄 Moves: {moves}")
80+
if check_win():
81+
print("\n🎉 Congratulations! You solved the puzzle!")
82+
break
83+
try:
84+
choice = int(input("\n🎯 Enter number to move: "))
85+
except ValueError:
86+
print("❌ Please enter a valid number!")
87+
continue
88+
move_tile(choice)
89+
print("\n👋 Thanks for playing Emoji Sliding Puzzle!\n")
90+
91+
init()

web-app/js/projects.js

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function getProjectHTML(projectName) {
2222
'tower-of-hanoi': getTowerOfHanoiHTML(),
2323
'snake-game': getsnakeGameHTML(),
2424
'password-forge': getPasswordForgeHTML(),
25+
'number-sliding-puzzle': getNumberSlidingPuzzleHTML(),
2526
};
2627

2728
return projects[projectName] || '<h2>Project Coming Soon!</h2>';
@@ -48,6 +49,7 @@ function initializeProject(projectName) {
4849
'morse-code': initMorseCode,
4950
'tower-of-hanoi': initTowerOfHanoi,
5051
'snake-game': initSnakeGame,
52+
'number-sliding-puzzle': initNumberSlidingPuzzle,
5153
};
5254

5355
if (initializers[projectName]) {
@@ -4940,4 +4942,139 @@ function initPasswordForge() {
49404942
result.textContent = "❌ Password does not meet all rules!";
49414943
}
49424944
});
4945+
}
4946+
4947+
// ============================================
4948+
// 🧩 NUMBER SLIDING PUZZLE (NEW ADDED GAME)
4949+
// ============================================
4950+
4951+
function getNumberSlidingPuzzleHTML() {
4952+
return `
4953+
<div class="project-content">
4954+
<h2>🧩 Number Sliding Puzzle</h2>
4955+
4956+
<div class="game-container">
4957+
<p>Arrange numbers from 1 to 8 in order</p>
4958+
4959+
<div id="puzzleBoard" class="puzzle-board"></div>
4960+
4961+
<p>Moves: <span id="moveCount">0</span></p>
4962+
4963+
<button id="resetPuzzle" class="btn-reset">Restart Game</button>
4964+
4965+
<div id="winMessage"></div>
4966+
</div>
4967+
</div>
4968+
`;
4969+
}
4970+
4971+
// ============================================
4972+
// 🧠 NUMBER SLIDING PUZZLE LOGIC
4973+
// ============================================
4974+
4975+
function initNumberSlidingPuzzle() {
4976+
let moves = 0;
4977+
let puzzle = [];
4978+
4979+
function chunk(arr) {
4980+
return [
4981+
arr.slice(0, 3),
4982+
arr.slice(3, 6),
4983+
arr.slice(6, 9)
4984+
];
4985+
}
4986+
4987+
function shuffle() {
4988+
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 0];
4989+
4990+
do {
4991+
for (let i = arr.length - 1; i > 0; i--) {
4992+
const j = Math.floor(Math.random() * (i + 1));
4993+
[arr[i], arr[j]] = [arr[j], arr[i]];
4994+
}
4995+
} while (JSON.stringify(chunk(arr)) === JSON.stringify([
4996+
[1,2,3],
4997+
[4,5,6],
4998+
[7,8,0]
4999+
]));
5000+
5001+
return chunk(arr);
5002+
}
5003+
5004+
function render() {
5005+
const board = document.getElementById("puzzleBoard");
5006+
const moveText = document.getElementById("moveCount");
5007+
5008+
board.innerHTML = "";
5009+
moveText.textContent = moves;
5010+
5011+
puzzle.forEach((row, i) => {
5012+
row.forEach((val, j) => {
5013+
const div = document.createElement("div");
5014+
div.className = "tile";
5015+
5016+
if (val === 0) {
5017+
div.classList.add("empty");
5018+
} else {
5019+
div.textContent = val;
5020+
div.onclick = () => moveTile(i, j);
5021+
}
5022+
5023+
board.appendChild(div);
5024+
});
5025+
});
5026+
5027+
if (isWin()) {
5028+
document.getElementById("winMessage").textContent =
5029+
"🎉 Puzzle Solved!";
5030+
}
5031+
}
5032+
5033+
function findEmpty() {
5034+
for (let i = 0; i < 3; i++) {
5035+
for (let j = 0; j < 3; j++) {
5036+
if (puzzle[i][j] === 0) return [i, j];
5037+
}
5038+
}
5039+
}
5040+
5041+
function moveTile(i, j) {
5042+
const [ei, ej] = findEmpty();
5043+
5044+
const isAdjacent =
5045+
(Math.abs(i - ei) === 1 && j === ej) ||
5046+
(Math.abs(j - ej) === 1 && i === ei);
5047+
5048+
if (!isAdjacent) return;
5049+
5050+
[puzzle[i][j], puzzle[ei][ej]] = [0, puzzle[i][j]];
5051+
moves++;
5052+
render();
5053+
}
5054+
5055+
function isWin() {
5056+
let expected = 1;
5057+
5058+
for (let i = 0; i < 3; i++) {
5059+
for (let j = 0; j < 3; j++) {
5060+
if (i === 2 && j === 2) {
5061+
if (puzzle[i][j] !== 0) return false;
5062+
} else {
5063+
if (puzzle[i][j] !== expected++) return false;
5064+
}
5065+
}
5066+
}
5067+
return true;
5068+
}
5069+
5070+
function resetGame() {
5071+
moves = 0;
5072+
puzzle = shuffle();
5073+
document.getElementById("winMessage").textContent = "";
5074+
render();
5075+
}
5076+
5077+
document.getElementById("resetPuzzle").onclick = resetGame;
5078+
5079+
resetGame();
49435080
}

0 commit comments

Comments
 (0)