Memory Puzzle

copy code

Memory Puzzle

CODE:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Enhanced Memory Game</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        #game-container {
            text-align: center;
            background-color: white;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }
        #grid {
            display: inline-grid;
            gap: 10px;
            margin-top: 20px;
        }
        .tile {
            width: 60px;
            height: 60px;
            background-color: #ddd;
            border: 2px solid #999;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        .tile:hover:not(.clicked):not(.wrong) {
            transform: scale(1.05);
        }
        .tile.active {
            background-color: #4CAF50;
            box-shadow: 0 0 10px #4CAF50;
        }
        .tile.clicked {
            background-color: #2196F3;
            box-shadow: 0 0 10px #2196F3;
            cursor: not-allowed;
        }
        .tile.wrong {
            background-color: #FF5722;
            box-shadow: 0 0 10px #FF5722;
            cursor: not-allowed;
        }
        #message {
            margin-top: 20px;
            font-size: 18px;
            font-weight: bold;
            color: #333;
        }
        #start-button {
            margin-top: 20px;
            padding: 10px 20px;
            font-size: 16px;
            cursor: pointer;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
            transition: background-color 0.3s ease;
        }
        #start-button:hover {
            background-color: #45a049;
        }
        #info-container {
            display: flex;
            justify-content: space-between;
            margin-top: 10px;
            font-size: 16px;
        }
        #timer {
            font-size: 24px;
            font-weight: bold;
            color: #333;
        }
        #timer-bar {
            width: 100%;
            height: 10px;
            background-color: #ddd;
            margin-top: 5px;
            border-radius: 5px;
            overflow: hidden;
        }
        #timer-progress {
            height: 100%;
            width: 100%;
            background-color: #4CAF50;
            transition: width 0.1s linear;
        }
        #level-display {
            font-size: 20px;
            font-weight: bold;
            color: #333;
            margin-top: 10px;
        }
        .life-icon {
            font-size: 24px;
            color: #FF5722;
            margin: 0 2px;
        }
        #congrats-container {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0,0,0,0.8);
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            z-index: 1000;
            opacity: 0;
            transition: opacity 0.5s ease;
        }
        #congrats-message {
            font-size: 48px;
            color: white;
            margin-bottom: 20px;
            text-align: center;
        }
        #fireworks {
            position: absolute;
            width: 100%;
            height: 100%;
            pointer-events: none;
        }
    </style>
</head>
<body>
    <div id="game-container">
        <h1>Enhanced Memory Game</h1>
        <div id="level-display">Level: 1</div>
        <div id="info-container">
            <div id="lives">
                <div>Big Lives: <span id="big-lives"></span></div>
                <div>Level Lives: <span id="level-lives"></span></div>
            </div>
            <div id="remaining-squares">Squares Left: 0</div>
        </div>
        <div id="timer">Time: <span id="timer-value">0</span>s</div>
        <div id="timer-bar"><div id="timer-progress"></div></div>
        <button id="start-button">Start Game</button>
        <div id="grid"></div>
        <div id="message"></div>
    </div>
    <div id="congrats-container">
        <div id="fireworks"></div>
        <div id="congrats-message">Congratulations!<br>You've completed all levels!</div>
        <button id="restart-button" style="font-size: 24px; padding: 10px 20px;">Play Again</button>
    </div>

    <script>
        const grid = document.getElementById('grid');
        const message = document.getElementById('message');
        const startButton = document.getElementById('start-button');
        const bigLivesDisplay = document.getElementById('big-lives');
        const levelLivesDisplay = document.getElementById('level-lives');
        const timerDisplay = document.getElementById('timer-value');
        const timerProgress = document.getElementById('timer-progress');
        const levelDisplay = document.getElementById('level-display');
        const remainingSquaresDisplay = document.getElementById('remaining-squares');
        const congratsContainer = document.getElementById('congrats-container');
        const restartButton = document.getElementById('restart-button');
        const fireworksContainer = document.getElementById('fireworks');

        let level = 1;
        let gridSize = 2;
        let sequence = [];
        let userClicks = [];
        let gameStatus = 'waiting'; // 'waiting', 'showing', 'input', 'success', 'fail'
        let bigLives = 3;
        let levelLives = 3;
        let timerInterval;
        let remainingSquares = 0;

        const levelConfig = [
            {level: 1, gridSize: 2, squares: 1}, {level: 2, gridSize: 3, squares: 2},
            {level: 3, gridSize: 3, squares: 3}, {level: 4, gridSize: 3, squares: 4},
            {level: 5, gridSize: 4, squares: 5}, {level: 6, gridSize: 4, squares: 6},
            {level: 7, gridSize: 4, squares: 7}, {level: 8, gridSize: 4, squares: 8},
            {level: 9, gridSize: 4, squares: 9}, {level: 10, gridSize: 5, squares: 10},
            {level: 11, gridSize: 5, squares: 11}, {level: 12, gridSize: 5, squares: 12},
            {level: 13, gridSize: 5, squares: 13}, {level: 14, gridSize: 5, squares: 14},
            {level: 15, gridSize: 5, squares: 15}, {level: 16, gridSize: 5, squares: 16},
            {level: 17, gridSize: 6, squares: 17}, {level: 18, gridSize: 6, squares: 18},
            {level: 19, gridSize: 6, squares: 19}, {level: 20, gridSize: 6, squares: 20},
            {level: 21, gridSize: 6, squares: 21}, {level: 22, gridSize: 6, squares: 22},
            {level: 23, gridSize: 6, squares: 23}, {level: 24, gridSize: 6, squares: 24},
            {level: 25, gridSize: 6, squares: 25}, {level: 26, gridSize: 7, squares: 26}
        ];

        startButton.addEventListener('click', startGame);
        restartButton.addEventListener('click', startGame);

        function startGame() {
            level = 1;
            bigLives = 3;
            levelLives = 3;
            startButton.style.display = 'none';
            congratsContainer.style.opacity = '0';
            setTimeout(() => {
                congratsContainer.style.display = 'none';
            }, 500);
            initializeGame();
        }

        function initializeGame() {
            const config = levelConfig[level - 1];
            gridSize = config.gridSize;
            
            grid.innerHTML = '';
            grid.style.gridTemplateColumns = `repeat(${gridSize}, 1fr)`;
            for (let i = 0; i < gridSize * gridSize; i++) {
                const tile = document.createElement('div');
                tile.className = 'tile';
                tile.dataset.index = i;
                tile.addEventListener('click', () => tileClick(i));
                grid.appendChild(tile);
            }
            updateLivesDisplay();
            updateLevelDisplay();
            generateSequence();
        }

        function generateSequence() {
            sequence = [];
            const config = levelConfig[level - 1];
            const totalTiles = gridSize * gridSize;
            for (let i = 0; i < config.squares; i++) {
                let randomIndex;
                do {
                    randomIndex = Math.floor(Math.random() * totalTiles);
                } while (sequence.includes(randomIndex));
                sequence.push(randomIndex);
            }
            remainingSquares = sequence.length;
            updateRemainingSquaresDisplay();
            showSequence();
        }

        function showSequence() {
            gameStatus = 'showing';
            message.textContent = 'Watch the sequence...';
            sequence.forEach(tileIndex => {
                const tile = grid.children[tileIndex];
                tile.classList.add('active');
            });

            const memorizationTime = Math.round(1050 * levelConfig[level - 1].squares * 0.7); // 30% shorter
            let timeLeft = memorizationTime / 1000;

            startTimer(timeLeft);

            setTimeout(() => {
                sequence.forEach(tileIndex => {
                    const tile = grid.children[tileIndex];
                    tile.classList.remove('active');
                });
                gameStatus = 'input';
                message.textContent = 'Your turn! Click the highlighted squares.';
                userClicks = [];
                clearInterval(timerInterval);
                timerDisplay.textContent = '0';
                timerProgress.style.width = '0%';
            }, memorizationTime);
        }

        function startTimer(duration) {
            let timeLeft = duration;
            timerInterval = setInterval(() => {
                timerDisplay.textContent = timeLeft.toFixed(1);
                timerProgress.style.width = `${(timeLeft / duration) * 100}%`;
                timeLeft -= 0.1;
                if (timeLeft < 0) {
                    clearInterval(timerInterval);
                }
            }, 100);
        }

        function tileClick(index) {
            if (gameStatus !== 'input') return;

            const tile = grid.children[index];
            
            if (tile.classList.contains('clicked') || tile.classList.contains('wrong')) {
                return;
            }

            if (sequence.includes(index)) {
                userClicks.push(index);
                tile.classList.add('clicked');
                remainingSquares--;
                updateRemainingSquaresDisplay();
                
                if (userClicks.length === sequence.length) {
                    nextLevel();
                }
            } else {
                tile.classList.add('wrong');
                levelLives--;
                updateLivesDisplay();
                
                if (levelLives === 0) {
                    bigLives--;
                    updateLivesDisplay();
                    if (bigLives === 0) {
                        gameOver();
                    } else {
                        retryLevel();
                    }
                } else {
                    message.textContent = `Wrong! Try again. ${levelLives} level ${levelLives === 1 ? 'life' : 'lives'} left.`;
                }
            }
        }

        function nextLevel() {
            level++;
            userClicks = [];
            gameStatus = 'waiting';
            message.textContent = `Great! Proceeding to level ${level}`;
            levelLives = 3;
            updateLivesDisplay();
            updateLevelDisplay();
            
            if (level > levelConfig.length) {
                winGame();
            } else {
                setTimeout(initializeGame, 1500);
            }
        }

        function retryLevel() {
            userClicks = [];
            gameStatus = 'waiting';
            message.textContent = `You lost a big life. Retrying level ${level}`;
            levelLives = 3;
            updateLivesDisplay();
            setTimeout(() => {
                resetUserInput();
                generateSequence();
            }, 1500);
        }

        function resetUserInput() {
            userClicks = [];
            remainingSquares = sequence.length;
            updateRemainingSquaresDisplay();
            Array.from(grid.children).forEach(tile => {
                tile.classList.remove('clicked');
                tile.classList.remove('wrong');
            });
        }

        function gameOver() {
            gameStatus = 'fail';
            message.textContent = 'Game Over! You ran out of lives.';
            startButton.style.display = 'inline-block';
            startButton.textContent = 'Play Again';
        }

        function winGame() {
            gameStatus = 'success';
            showCongratulations();
        }

        function showCongratulations() {
            congratsContainer.style.display = 'flex';
            setTimeout(() => {
                congratsContainer.style.opacity = '1';
            }, 50);
            createFireworks();
        }

        function createFireworks() {
            for (let i = 0; i < 50; i++) {
                setTimeout(() => {
                    const firework = document.createElement('div');
                    firework.style.position = 'absolute';
                    firework.style.width = '5px';
                    firework.style.height = '5px';
                    firework.style.borderRadius = '50%';
                    firework.style.backgroundColor = getRandomColor();
                    firework.style.left = Math.random() * 100 + '%';
                    firework.style.top = Math.random() * 100 + '%';
                    firework.style.transform = 'scale(0)';
                    firework.style.transition = 'transform 0.5s ease-out';
                    fireworksContainer.appendChild(firework);

                    setTimeout(() => {
                        firework.style.transform = 'scale(1)';
                    }, 50);

                    setTimeout(() => {
                        firework.remove();
                    }, 1000);
                }, i * 100);
            }
        }

        function getRandomColor() {
            const r = Math.floor(Math.random() * 256);
            const g = Math.floor(Math.random() * 256);
            const b = Math.floor(Math.random() * 256);
            return `rgb(${r},${g},${b})`;
        }

        function updateLivesDisplay() {
            bigLivesDisplay.innerHTML = 'đź’š'.repeat(bigLives) + 'đź–¤'.repeat(3 - bigLives);
            levelLivesDisplay.innerHTML = 'đź’š'.repeat(levelLives) + 'đź–¤'.repeat(3 - levelLives);
        }

        function updateLevelDisplay() {
            levelDisplay.textContent = `Level: ${level}`;
        }

        function updateRemainingSquaresDisplay() {
            remainingSquaresDisplay.textContent = `Squares Left: ${remainingSquares}`;
        }

        // Start the game when the page loads
        window.addEventListener('load', () => {
            startButton.style.display = 'inline-block';
            congratsContainer.style.display = 'none';
        });
    </script>
</body>
</html>