-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
124 lines (103 loc) 路 3.44 KB
/
Copy pathscript.js
File metadata and controls
124 lines (103 loc) 路 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
let moves = 0;
let puzzleState = [];
let history = [];
const targetState = [1, 2, 3, 4, 5, 6, 7, 8, null];
const puzzleContainer = document.getElementById('puzzle');
const targetContainer = document.getElementById('target');
const moveCountEl = document.getElementById('moveCount');
const winMessage = document.getElementById('winMessage');
const finalMovesEl = document.getElementById('finalMoves');
function createTile(value, isTarget = false) {
const tile = document.createElement('div');
if (isTarget) {
tile.className = value === null ? 'mini-tile mini-empty' : 'mini-tile';
if (value !== null) tile.textContent = value;
} else {
tile.className = value === null ? 'tile empty' : 'tile';
if (value !== null) tile.textContent = value;
}
return tile;
}
function renderGrid(container, state, isTarget = false) {
container.innerHTML = '';
state.forEach((value, index) => {
const tile = createTile(value, isTarget);
if (!isTarget && value !== null) {
tile.addEventListener('click', () => moveTile(index));
}
container.appendChild(tile);
});
}
function findEmpty() {
return puzzleState.indexOf(null);
}
function isAdjacent(a, b) {
const rowA = Math.floor(a / 3), colA = a % 3;
const rowB = Math.floor(b / 3), colB = b % 3;
return Math.abs(rowA - rowB) + Math.abs(colA - colB) === 1;
}
function saveHistory() {
history.push([...puzzleState]);
if (history.length > 30) history.shift();
}
function moveTile(index) {
const emptyIndex = findEmpty();
if (!isAdjacent(index, emptyIndex)) return;
saveHistory();
[puzzleState[index], puzzleState[emptyIndex]] = [puzzleState[emptyIndex], puzzleState[index]];
moves++;
moveCountEl.textContent = moves;
renderGrid(puzzleContainer, puzzleState);
checkWin();
}
function checkWin() {
if (puzzleState.every((val, i) => val === targetState[i])) {
finalMovesEl.textContent = moves;
setTimeout(() => {
winMessage.style.display = 'block';
}, 300);
}
}
function shuffle(array) {
let arr = [...array];
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
function startGame() {
moves = 0;
history = [];
moveCountEl.textContent = '0';
winMessage.style.display = 'none';
do {
puzzleState = shuffle(targetState);
} while (JSON.stringify(puzzleState) === JSON.stringify(targetState));
renderGrid(targetContainer, targetState, true);
renderGrid(puzzleContainer, puzzleState);
}
// Buttons
document.getElementById('newGameBtn').addEventListener('click', startGame);
document.getElementById('resetBtn').addEventListener('click', () => {
if (history.length > 0) {
puzzleState = [...history[history.length - 1]];
moves = Math.max(0, moves - 1);
moveCountEl.textContent = moves;
renderGrid(puzzleContainer, puzzleState);
}
});
document.getElementById('undoBtn').addEventListener('click', () => {
if (history.length > 0) {
puzzleState = history.pop();
moves = Math.max(0, moves - 1);
moveCountEl.textContent = moves;
renderGrid(puzzleContainer, puzzleState);
}
});
// Keyboard shortcut
document.addEventListener('keydown', (e) => {
if (e.key.toLowerCase() === 'r') startGame();
});
// Start the game
window.onload = startGame;