Skip to content

Commit 7c5d733

Browse files
Merge branch 'main' into feat-port-war-card-game
2 parents ea6d09b + daecca7 commit 7c5d733

8 files changed

Lines changed: 501 additions & 4 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ deactivate
240240

241241
## 🌐 Web App Catalog
242242

243-
The browser app currently exposes 38 projects:
243+
The browser app currently exposes 39 projects:
244244

245245
### Games
246246

@@ -263,6 +263,7 @@ The browser app currently exposes 38 projects:
263263
- Word Scramble
264264
- Spot the Difference
265265
- War Card Game
266+
- Number Sliding Puzzle
266267

267268
### Math
268269

@@ -294,7 +295,6 @@ The browser app currently exposes 38 projects:
294295

295296
These standalone Python project files do not have a browser counterpart yet and are good future-port candidates:
296297

297-
- [games/Number-Sliding-Puzzle/Number-Sliding-Puzzle.py](games/Number-Sliding-Puzzle/Number-Sliding-Puzzle.py)
298298
- [games/Reverse-Hangman-Game/Reverse-Hangman-Game.py](games/Reverse-Hangman-Game/Reverse-Hangman-Game.py)
299299
- [math/Happy-Number/Happy-Number.py](math/Happy-Number/Happy-Number.py)
300300
- [math/Matrix-Calculator/Matrix-Calculator.py](math/Matrix-Calculator/Matrix-Calculator.py)

games/Number-Sliding-Puzzle/Number-Sliding-Puzzle.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,37 @@
88
from utils.validation import get_int, get_yes_no
99

1010

11+
def is_solvable(numbers):
12+
"""
13+
Determines if the 8-puzzle board configuration is solvable.
14+
An 8-puzzle (3x3 grid) is solvable if the number of inversions is even.
15+
The blank tile (0) is ignored when counting inversions.
16+
"""
17+
# Filter out the blank tile(0)
18+
19+
tiles = [n for n in numbers if n != 0]
20+
inversions = 0
21+
for i in range(len(tiles)):
22+
for j in range(i + 1, len(tiles)):
23+
if tiles[i] > tiles[j]:
24+
inversions += 1
25+
26+
# return True if inversions count is even, False otherwise
27+
28+
return inversions % 2 == 0
29+
30+
1131
def main():
1232
print("🧩 Emoji Sliding Puzzle Game 🧩")
1333

1434
while True:
1535
print("Arrange the numbers in correct order!\n")
1636

1737
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 0]
18-
random.shuffle(numbers)
38+
while True:
39+
random.shuffle(numbers)
40+
if is_solvable(numbers) and numbers != [1, 2, 3, 4, 5, 6, 7, 8, 0]:
41+
break
1942

2043
puzzle = [
2144
numbers[0:3],
38.1 KB
Loading

web-app/games.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,25 @@
329329
<section class="projects-section" aria-label="Game Projects">
330330
<div class="container">
331331
<div class="projects-grid" id="projectsGrid">
332+
<div
333+
class="project-card"
334+
data-category="games"
335+
data-project="number-sliding-puzzle"
336+
>
337+
<img
338+
class="card-banner"
339+
src="assets/banners/number-sliding-puzzle.webp"
340+
alt="Number Sliding Puzzle"
341+
loading="lazy"
342+
/ loading="lazy">
343+
<div class="card-actions">
344+
<button class="btn-play" aria-label="Play Number Sliding Puzzle">Try It</button>
345+
</div>
346+
347+
<h3>Number Sliding Puzzle</h3>
348+
<p>Arrange numbers in ascending order by sliding them!</p>
349+
</div>
350+
332351
<div
333352
class="project-card"
334353
data-category="games"
@@ -712,6 +731,7 @@ <h3>Word Scramble</h3>
712731
<script defer src="js/projects/word-scramble.js"></script>
713732
<script defer src="js/projects/snake.js"></script>
714733
<script defer src="js/projects/spot-the-difference.js"></script>
734+
<script defer src="js/projects/number-sliding-puzzle.js"></script>
715735
<script defer src="js/projects.js"></script>
716736
<script defer src="https://unpkg.com/lucide@latest/dist/umd/lucide.js"></script>
717737
<script defer type="module" src="js/main.js"></script>

web-app/generate_banners.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,18 @@ def generate_banner(name, category, filename):
100100
y = 120 + (i // 2) * 120
101101
v_draw.rounded_rectangle([x, y, x + 140, y + 90], radius=12, fill=(255,255,255,8), outline=color_accent, width=2)
102102
v_draw.text((x + 70, y + 45), val, fill=color_accent, anchor="mm")
103+
elif "sliding" in n_lower or "puzzle" in n_lower:
104+
# Draw a 3x3 grid with sliding numbers
105+
for i in range(9):
106+
if i == 8: # Empty space
107+
continue
108+
r_idx = i // 3
109+
c_idx = i % 3
110+
x = 240 + c_idx * 110
111+
y = 120 + r_idx * 75
112+
val = str(i + 1)
113+
v_draw.rounded_rectangle([x, y, x + 90, y + 60], radius=10, fill=(255,255,255,12), outline=color_accent, width=2)
114+
v_draw.text((x + 45, y + 30), val, fill=color_accent, anchor="mm")
103115
elif "fibonacci" in n_lower:
104116
# Draw golden spiral
105117
cx, cy = 400, 225
@@ -534,6 +546,7 @@ def draw_o(ox, oy):
534546
("Progress Tracker", "utilities", "progress-tracker.webp"),
535547
("Reverse Hangman", "games", "reverse-hangman.webp"),
536548
("Chess Game", "games", "chess.webp"),
549+
("Number Sliding Puzzle", "games", "number-sliding-puzzle.webp"),
537550

538551
# MATH
539552
("AP/GP/AGP/HP Recognizer", "math", "progression-recognizer.webp"),

web-app/index.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,7 @@ <h3>Legal</h3>
873873
<script defer type="module" src="js/main.js"></script>
874874
<script defer src="js/hero-canvas.js"></script>
875875
<script defer src="js/projects/war-card-game.js"></script>
876+
<script defer src="js/projects/number-sliding-puzzle.js"></script>
876877
<script>
877878
lucide.createIcons();
878879
</script>
@@ -886,6 +887,13 @@ <h3>Legal</h3>
886887
// ALL projects from your js/projects/ folder
887888
const projectsData = [
888889
// GAMES (20+)
890+
{
891+
project: "number-sliding-puzzle",
892+
title: "Number Sliding Puzzle",
893+
category: "games",
894+
desc: "Arrange tiles in order by sliding them into empty space",
895+
tags: "game,puzzle,sliding,numbers",
896+
},
889897
{
890898
project: "2048-game",
891899
title: "2048 Game",

web-app/js/projects.js

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,13 @@ const projectInstructions = {
16041604
"The player with the higher card rank wins the round and gets a point.",
16051605
"Ace is the highest, 2 is the lowest.",
16061606
"Play continues until all cards are drawn. The player with the most points wins!"
1607+
"number-sliding-puzzle": {
1608+
title: "🧩 How to Play Number Sliding Puzzle",
1609+
steps: [
1610+
"Use arrow keys (← ↑ → ↓) or click/tap on tiles next to the empty space to slide them.",
1611+
"Arrange the numbers in ascending order from 1 to 8, with the blank space at the bottom right.",
1612+
"A moves counter keeps track of your steps.",
1613+
"Click the Reset button to restart the game."
16071614
]
16081615
},
16091616
"2048-game": {
@@ -1740,6 +1747,16 @@ const projectInstructions = {
17401747
"Beat the dealer to win"
17411748
]
17421749
},
1750+
"reverse-hangman": {
1751+
title: "🤖 How to Play Reverse Hangman",
1752+
steps: [
1753+
"Think of a secret word from the dictionary (40+ words available)",
1754+
"The AI tries to guess your word using letter frequency analysis",
1755+
"Tell the AI if its guess is correct or not",
1756+
"AI gets 8 attempts max — can you beat the computer?",
1757+
"Watch the hangman visual feedback as AI guesses"
1758+
]
1759+
},
17431760

17441761
// MATH
17451762
"calculator": {
@@ -1843,6 +1860,16 @@ const projectInstructions = {
18431860
"Click Recognize to identify the sequence type"
18441861
]
18451862
},
1863+
"matrix-calculator": {
1864+
title: "🧮 How to Use Matrix Calculator",
1865+
steps: [
1866+
"Select matrix dimensions (rows × columns)",
1867+
"Enter values into each cell",
1868+
"Choose operation: Addition, Subtraction, Multiplication, Transpose, Determinant, Rank, or Inverse",
1869+
"Click Calculate to see the result",
1870+
"Determinant & Inverse work only for square matrices"
1871+
]
1872+
},
18461873

18471874
// UTILITIES
18481875
"color-palette": {
@@ -1920,7 +1947,17 @@ const projectInstructions = {
19201947
"Mark projects as complete",
19211948
"See your progress over time"
19221949
]
1923-
}
1950+
},
1951+
"unit-converter": {
1952+
title: "📏 How to Use Unit Converter",
1953+
steps: [
1954+
"Select conversion category (Length, Mass, Temperature, etc.)",
1955+
"Choose input and output units",
1956+
"Enter the value to convert",
1957+
"Result appears instantly",
1958+
"Supports multiple unit types"
1959+
]
1960+
}
19241961
};
19251962

19261963
function getProjectInstructions(projectName) {
@@ -3140,6 +3177,7 @@ function initializeProject(projectName) {
31403177
"resume-analyzer": "initResumeAnalyzer",
31413178
"caesar-cipher": "initCaesarCipher",
31423179
"war-card-game": "initWarCardGame"
3180+
"number-sliding-puzzle": "initNumberSlidingPuzzle"
31433181
};
31443182

31453183
const initializerName = initializers[projectName];

0 commit comments

Comments
 (0)