97 lines
2.4 KiB
JavaScript
97 lines
2.4 KiB
JavaScript
const SIZE = 4;
|
|
const boardDiv = document.getElementById('board');
|
|
const statusDiv = document.getElementById('status');
|
|
const restartBtn = document.getElementById('restart-btn');
|
|
let board, won;
|
|
|
|
function initGame() {
|
|
board = [];
|
|
won = false;
|
|
let numbers = Array.from({length: SIZE*SIZE}, (_, i) => i);
|
|
do {
|
|
shuffle(numbers);
|
|
} while(!isSolvable(numbers));
|
|
// Llenar el tablero
|
|
for (let r=0; r<SIZE; r++) {
|
|
let row = [];
|
|
for (let c=0; c<SIZE; c++)
|
|
row.push(numbers[r*SIZE + c]);
|
|
board.push(row);
|
|
}
|
|
statusDiv.textContent = "Ordena las fichas del 1 al 15";
|
|
renderBoard();
|
|
}
|
|
|
|
function shuffle(array) {
|
|
for (let i = array.length - 1; i > 0; i--) {
|
|
const j = Math.floor(Math.random() * (i + 1));
|
|
[array[i], array[j]] = [array[j], array[i]];
|
|
}
|
|
}
|
|
|
|
// Verifica si el puzzle es resoluble (paridad)
|
|
function isSolvable(arr) {
|
|
let invCount = 0;
|
|
for (let i = 0; i < arr.length; i++) {
|
|
if (arr[i] === 0) continue;
|
|
for (let j = i+1; j < arr.length; j++) {
|
|
if (arr[j] !== 0 && arr[i] > arr[j]) invCount++;
|
|
}
|
|
}
|
|
let emptyRow = Math.floor(arr.indexOf(0) / SIZE);
|
|
return (invCount + emptyRow) % 2 === 0;
|
|
}
|
|
|
|
function renderBoard() {
|
|
boardDiv.innerHTML = '';
|
|
for (let r = 0; r < SIZE; r++) {
|
|
for (let c = 0; c < SIZE; c++) {
|
|
const val = board[r][c];
|
|
const tile = document.createElement('div');
|
|
tile.className = 'tile' + (val === 0 ? ' empty' : '');
|
|
tile.textContent = val === 0 ? '' : val;
|
|
if (val !== 0 && !won) {
|
|
tile.onclick = () => moveTile(r, c);
|
|
}
|
|
boardDiv.appendChild(tile);
|
|
}
|
|
}
|
|
if (checkWin() && !won) {
|
|
won = true;
|
|
statusDiv.textContent = "¡Felicidades! Puzzle resuelto 🎉";
|
|
}
|
|
}
|
|
|
|
function moveTile(r, c) {
|
|
let neighbours = [
|
|
[r-1, c],
|
|
[r+1, c],
|
|
[r, c-1],
|
|
[r, c+1]
|
|
];
|
|
for (let [nr, nc] of neighbours) {
|
|
if (nr >=0 && nr < SIZE && nc >=0 && nc < SIZE && board[nr][nc] === 0) {
|
|
// Intercambia
|
|
[board[nr][nc], board[r][c]] = [board[r][c], board[nr][nc]];
|
|
renderBoard();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
function checkWin() {
|
|
let n = 1;
|
|
for (let r = 0; r < SIZE; r++) {
|
|
for (let c = 0; c < SIZE; c++) {
|
|
if (r === SIZE-1 && c === SIZE-1) {
|
|
if (board[r][c] !== 0) return false;
|
|
} else {
|
|
if (board[r][c] !== n++) return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
restartBtn.onclick = initGame;
|
|
initGame(); |