document.addEventListener('DOMContentLoaded', () => { // Game state let gameState = { score: 0, level: 1, moves: 0, boardSize: 4, tiles: [], matchedPairs: 0, firstSelected: null, secondSelected: null, waiting: false, hintActive: false }; // DOM elements const gameBoard = document.querySelector('custom-game-board'); const scorePanel = document.querySelector('custom-score-panel'); const newGameBtn = document.getElementById('newGameBtn'); const hintBtn = document.getElementById('hintBtn'); // Initialize game function initGame() { // Add visual feedback newGameBtn.innerHTML = 'Creating...'; setTimeout(() => { gameState = { score: 0, level: 1, moves: 0, boardSize: 4, tiles: generateTiles(4), matchedPairs: 0, firstSelected: null, secondSelected: null, waiting: false, hintActive: false }; // Set up event listener for tile clicks gameBoard.addEventListener('tile-click', (e) => { handleTileClick(e.detail.index); }); updateScorePanel(); renderBoard(); // Add success animation newGameBtn.innerHTML = 'New Puzzle'; newGameBtn.classList.add('bg-green-500'); setTimeout(() => { newGameBtn.classList.remove('bg-green-500'); newGameBtn.classList.add('bg-purple-600'); }, 1000); // Play sound for feedback if (typeof Audio !== 'undefined') { const audio = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-positive-interface-beep-221.mp3'); audio.volume = 0.3; audio.play(); } }, 500); } // Generate tiles for the board function generateTiles(size) { const totalPairs = (size * size) / 2; const symbols = []; // Generate unique symbols for (let i = 0; i < totalPairs; i++) { symbols.push(String.fromCharCode(65 + i)); symbols.push(String.fromCharCode(65 + i)); } // Shuffle the symbols return shuffleArray(symbols); } // Fisher-Yates shuffle algorithm function shuffleArray(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]]; } return array; } // Render the game board function renderBoard() { gameBoard.setAttribute('size', gameState.boardSize); gameBoard.setAttribute('tiles', JSON.stringify(gameState.tiles)); } // Update score panel function updateScorePanel() { scorePanel.setAttribute('score', gameState.score); scorePanel.setAttribute('level', gameState.level); scorePanel.setAttribute('moves', gameState.moves); } // Handle tile click function handleTileClick(index) { if (gameState.waiting || gameState.tiles[index] === null || index === gameState.firstSelected) { return; } if (gameState.firstSelected === null) { gameState.firstSelected = index; gameBoard.setAttribute('selected', index.toString()); } else { gameState.secondSelected = index; gameState.moves++; checkForMatch(); } } // Check if the selected tiles match function checkForMatch() { const firstIndex = gameState.firstSelected; const secondIndex = gameState.secondSelected; if (gameState.tiles[firstIndex] === gameState.tiles[secondIndex]) { // Match found gameState.tiles[firstIndex] = null; gameState.tiles[secondIndex] = null; gameState.matchedPairs++; gameState.score += 10 * gameState.level; // Check for level completion if (gameState.matchedPairs === (gameState.boardSize * gameState.boardSize) / 2) { setTimeout(() => { levelUp(); }, 1000); } gameBoard.setAttribute('matched', `${firstIndex},${secondIndex}`); } else { // No match gameState.waiting = true; setTimeout(() => { gameBoard.removeAttribute('selected'); gameState.waiting = false; }, 1000); } gameState.firstSelected = null; gameState.secondSelected = null; updateScorePanel(); } // Level up the game function levelUp() { gameState.level++; gameState.boardSize = Math.min(8, gameState.boardSize + 2); // Max size 8x8 gameState.tiles = generateTiles(gameState.boardSize); gameState.matchedPairs = 0; updateScorePanel(); renderBoard(); } // Give hint function giveHint() { if (gameState.hintActive) return; gameState.hintActive = true; hintBtn.classList.add('bg-purple-600'); // Find first unmatched pair let firstUnmatched = null; for (let i = 0; i < gameState.tiles.length; i++) { if (gameState.tiles[i] !== null) { if (firstUnmatched === null) { firstUnmatched = i; } else if (gameState.tiles[i] === gameState.tiles[firstUnmatched]) { gameBoard.setAttribute('hint', `${firstUnmatched},${i}`); break; } } } setTimeout(() => { gameBoard.removeAttribute('hint'); gameState.hintActive = false; hintBtn.classList.remove('bg-purple-600'); }, 2000); } // Event listeners newGameBtn.addEventListener('click', initGame); hintBtn.addEventListener('click', giveHint); // Initialize the game initGame(); });