Changed around line 1
+ class PuzzleGame {
+ constructor() {
+ this.container = document.getElementById('puzzle-container');
+ this.tiles = Array.from({length: 9}, (_, i) => i);
+ this.moves = 0;
+ this.movesDisplay = document.getElementById('moves');
+ this.winMessage = document.getElementById('win-message');
+ this.finalMovesDisplay = document.getElementById('final-moves');
+
+ this.initializeGame();
+ this.bindEvents();
+ }
+
+ initializeGame() {
+ this.moves = 0;
+ this.updateMovesDisplay();
+ this.randomizePuzzle();
+ this.renderPuzzle();
+ }
+
+ randomizePuzzle() {
+ do {
+ for (let i = this.tiles.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [this.tiles[i], this.tiles[j]] = [this.tiles[j], this.tiles[i]];
+ }
+ } while (!this.isSolvable());
+ }
+
+ isSolvable() {
+ let inversions = 0;
+ const tiles = this.tiles.filter(t => t !== 0);
+
+ for (let i = 0; i < tiles.length - 1; i++) {
+ for (let j = i + 1; j < tiles.length; j++) {
+ if (tiles[i] > tiles[j]) inversions++;
+ }
+ }
+
+ return inversions % 2 === 0;
+ }
+
+ renderPuzzle() {
+ this.container.innerHTML = '';
+ this.tiles.forEach((tile, index) => {
+ const tileElement = document.createElement('div');
+ tileElement.className = `puzzle-tile ${tile === 0 ? 'empty' : ''}`;
+ if (tile !== 0) {
+ tileElement.textContent = tile;
+ }
+ tileElement.dataset.index = index;
+ this.container.appendChild(tileElement);
+ });
+ }
+
+ isMovable(index) {
+ const emptyIndex = this.tiles.indexOf(0);
+ const row = Math.floor(index / 3);
+ const emptyRow = Math.floor(emptyIndex / 3);
+ const col = index % 3;
+ const emptyCol = emptyIndex % 3;
+
+ return (Math.abs(row - emptyRow) + Math.abs(col - emptyCol)) === 1;
+ }
+
+ moveTile(index) {
+ if (this.isMovable(index)) {
+ const emptyIndex = this.tiles.indexOf(0);
+ [this.tiles[index], this.tiles[emptyIndex]] = [this.tiles[emptyIndex], this.tiles[index]];
+ this.moves++;
+ this.updateMovesDisplay();
+ this.renderPuzzle();
+
+ if (this.checkWin()) {
+ this.showWinMessage();
+ }
+ }
+ }
+
+ updateMovesDisplay() {
+ this.movesDisplay.textContent = `Moves: ${this.moves}`;
+ }
+
+ checkWin() {
+ return this.tiles.every((tile, index) => {
+ return index === 8 ? tile === 0 : tile === index + 1;
+ });
+ }
+
+ showWinMessage() {
+ this.finalMovesDisplay.textContent = this.moves;
+ this.winMessage.classList.remove('hidden');
+ setTimeout(() => {
+ this.winMessage.classList.add('visible');
+ }, 100);
+ }
+
+ bindEvents() {
+ this.container.addEventListener('click', (e) => {
+ const tile = e.target.closest('.puzzle-tile');
+ if (tile && !tile.classList.contains('empty')) {
+ this.moveTile(parseInt(tile.dataset.index));
+ }
+ });
+
+ document.getElementById('reset-button').addEventListener('click', () => {
+ this.initializeGame();
+ });
+
+ document.getElementById('play-again').addEventListener('click', () => {
+ this.winMessage.classList.remove('visible');
+ setTimeout(() => {
+ this.winMessage.classList.add('hidden');
+ this.initializeGame();
+ }, 300);
+ });
+
+ // Change theme color periodically
+ setInterval(() => {
+ document.documentElement.style.setProperty('--primary-hue',
+ Math.floor(Math.random() * 360));
+ }, 10000);
+ }
+ }
+
+ document.addEventListener('DOMContentLoaded', () => {
+ new PuzzleGame();
+ });