<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">// Variables globales
let currentLevel = 1;
let score = 0;            // Puntaje del juego principal
let minigameScore = 0;    // Puntaje del minijuego
let lives = 3;
let gameActive = false;
let minigameActive = false;

// Arreglo para almacenar las estrellas activas
let activeStars = [];

// Variables para control de la nave
let keysPressed = {};
let shipSpeed = 5;

// Variables para control de la velocidad de las estrellas
let starSpeed = 1; // Velocidad inicial de las estrellas
let baseStarSpeed = 1; // Velocidad base para reiniciar
let scoreIncrement = 0; // Puntos acumulados desde el Ãºltimo incremento de velocidad

// Variables de sonido
let shootSound = new Audio('../../gameMate/soundvideoGames/coin.mp3');
let hitSound = new Audio('../../../sonidoGames/coin_1.mp3');
let wrongSound = new Audio('../../gameMate/soundvideoGames/wrong_1.mp3');

// Referencias a elementos del DOM
const startScreen = document.getElementById('start-screen');
const startButton = document.getElementById('start-button');
const gameDiv = document.getElementById('game');
const levelDiv = document.getElementById('level');
const questionDiv = document.getElementById('question');
const optionsDiv = document.getElementById('options');
const scoreDiv = document.getElementById('score');
const minigameScoreDiv = document.getElementById('minigame-score');
const gameOverModal = document.getElementById('game-over-modal');
const finalScore = document.getElementById('final-score');
const playAgainButton = document.getElementById('play-again-button');
const playMinigameButton = document.getElementById('play-minigame-button');
const minigameDiv = document.getElementById('minigame');
const ship = document.getElementById('ship');
const livesDiv = document.getElementById('lives');

// Referencias a los botones de control mÃ³vil
const leftButton = document.getElementById('left-button');
const rightButton = document.getElementById('right-button');
const shootButton = document.getElementById('shoot-button');

// Eventos
startButton.addEventListener('click', startGame);
playAgainButton.addEventListener('click', restartGame);
playMinigameButton.addEventListener('click', startMinigame);

// FunciÃ³n para iniciar el juego
function startGame() {
    startScreen.style.display = 'none';
    gameDiv.style.display = 'block';
    currentLevel = 1;
    score = 0;
    updateScore();
    loadLevel(currentLevel);
}

// FunciÃ³n para cargar el nivel
function loadLevel(level) {
    levelDiv.textContent = `Nivel ${level}`;
    generateQuestion(level);
}

// FunciÃ³n para generar preguntas basadas en el nivel
function generateQuestion(level) {
    let question, correctAnswer, options;

    switch(level) {
        case 1:
            // Producto de bases iguales: a^n * a^m = a^(n+m)
            {
                let base = getRandomInt(2, 20);
                let exp1 = getRandomInt(1, 20);
                let exp2 = getRandomInt(1, 20);
                question = `${base}&lt;sup&gt;${exp1}&lt;/sup&gt; Ã— ${base}&lt;sup&gt;${exp2}&lt;/sup&gt; = ?`;
                correctAnswer = `${base}&lt;sup&gt;${exp1 + exp2}&lt;/sup&gt;`;
                options = generateOptions(correctAnswer, base, exp1 + exp2);
            }
            break;
        case 2:
            // Cociente de bases iguales: a^n / a^m = a^(n-m)
            {
                let base = getRandomInt(2, 20);
                let exp1 = getRandomInt(5, 20);
                let exp2 = getRandomInt(1, 20);
                question = `${base}&lt;sup&gt;${exp1}&lt;/sup&gt; Ã· ${base}&lt;sup&gt;${exp2}&lt;/sup&gt; = ?`;
                correctAnswer = `${base}&lt;sup&gt;${exp1 - exp2}&lt;/sup&gt;`;
                options = generateOptions(correctAnswer, base, exp1 - exp2);
            }
            break;
        case 3:
            // Potencia de una potencia: (a^n)^m = a^(n*m)
            {
                let base = getRandomInt(2, 20);
                let exp1 = getRandomInt(1, 20);
                let exp2 = getRandomInt(1, 20);
                question = `(${base}&lt;sup&gt;${exp1}&lt;/sup&gt;)&lt;sup&gt;${exp2}&lt;/sup&gt; = ?`;
                correctAnswer = `${base}&lt;sup&gt;${exp1 * exp2}&lt;/sup&gt;`;
                options = generateOptions(correctAnswer, base, exp1 * exp2);
            }
            break;
        case 4:
            // Exponente negativo: a^-n = 1/a^n
            {
                let base = getRandomInt(2, 20);
                let exp = getRandomInt(1, 20);
                question = `${base}&lt;sup&gt;-${exp}&lt;/sup&gt; = ?`;
                correctAnswer = `1/${base}&lt;sup&gt;${exp}&lt;/sup&gt;`;
                options = [
                    correctAnswer,
                    `${base}&lt;sup&gt;${exp}&lt;/sup&gt;`,
                    `${base}&lt;sup&gt;-${exp}&lt;/sup&gt;`,
                    `1/${base}&lt;sup&gt;-${exp}&lt;/sup&gt;`
                ];
            }
            break;
            case 5:
                // NotaciÃ³n cientÃ­fica
                {
                    let exponent = getRandomInt(2, 5);
                    let mantissa = parseFloat((Math.random() * 9 + 1).toFixed(2)); // Mantisa entre 1 y 10
                    let number = mantissa * Math.pow(10, exponent);
                    question = `Escribe ${number.toLocaleString()} en notaciÃ³n cientÃ­fica`;
                    correctAnswer = `${mantissa.toFixed(2)} Ã— 10&lt;sup&gt;${exponent}&lt;/sup&gt;`;
                    options = generateScientificNotationOptions(mantissa, exponent);
                }
                break;
                case 6:
                    // Producto de decimales en notaciÃ³n cientÃ­fica
                    {
                        let num1 = getRandomDecimal([0.02, 0.006, 0.008]);
                        let num2 = getRandomDecimal([0.02, 0.006, 0.008]);
                        question = `${num1} Ã— ${num2} = ? (Escribe la respuesta en notaciÃ³n cientÃ­fica)`;
                        let product = num1 * num2;
                        let exponent = Math.floor(Math.log10(product));
                        let mantissa = product / Math.pow(10, exponent);
                        correctAnswer = `${mantissa.toFixed(2)} Ã— 10&lt;sup&gt;${exponent}&lt;/sup&gt;`;
                        options = generateScientificNotationOptions(mantissa, exponent);
                    }
                    break;
                case 7:
            // 10 ejercicios combinados
            {
                let randomLevel = getRandomInt(1, 6);
                generateQuestion(randomLevel);
                return;
            }
            break;
        default:
            endGame();
            return;
    }

    // Mostrar pregunta y opciones
    questionDiv.innerHTML = question;
    optionsDiv.innerHTML = '';
    shuffle(options).forEach(option =&gt; {
        let button = document.createElement('button');
        button.innerHTML = option;
        button.addEventListener('click', () =&gt; checkAnswer(option, correctAnswer));
        optionsDiv.appendChild(button);
    });
}

// FunciÃ³n para verificar la respuesta
function checkAnswer(selected, correct) {
    if (selected === correct) {
        score += 10;
        // Opcional: Puedes agregar retroalimentaciÃ³n positiva aquÃ­
    } else {
        score -= 5;
        // Opcional: Puedes agregar retroalimentaciÃ³n negativa aquÃ­
    }
    updateScore();
    if (score &gt;= 100) {
        currentLevel++;
        if (currentLevel &gt; 7) {
            endGame();
        } else {
            score = 0;
            updateScore();
            loadLevel(currentLevel);
        }
    } else {
        generateQuestion(currentLevel);
    }
}

// FunciÃ³n para actualizar el puntaje
function updateScore() {
    scoreDiv.textContent = `PuntuaciÃ³n: ${score}`;
}

// FunciÃ³n para terminar el juego principal
function endGame() {
    gameDiv.style.display = 'none';
    gameOverModal.style.display = 'block';
    finalScore.textContent = `PuntuaciÃ³n Final: ${score}`;
    if (currentLevel &gt; 7) {
        playMinigameButton.style.display = 'inline-block';
    } else {
        playMinigameButton.style.display = 'none';
    }
}

// FunciÃ³n para reiniciar el juego
function restartGame() {
    gameOverModal.style.display = 'none';
    startScreen.style.display = 'block';
}

// FunciÃ³n para iniciar el minijuego
function startMinigame() {
    gameOverModal.style.display = 'none';
    minigameDiv.style.display = 'block';
    lives = 3;
    updateLives();
    minigameActive = true;
    ship.style.left = '375px'; // Centrar la nave al iniciar
    activeStars = []; // Reiniciar arreglo de estrellas activas
    minigameScore = 0; // Reiniciar puntuaciÃ³n del minijuego
    starSpeed = baseStarSpeed; // Reiniciar velocidad de las estrellas
    scoreIncrement = 0; // Reiniciar incremento de puntuaciÃ³n
    updateMinigameScore();
    initMinigame();
}

// FunciÃ³n para actualizar las vidas
function updateLives() {
    livesDiv.textContent = `Vidas: ${lives}`;
}

// FunciÃ³n para actualizar la puntuaciÃ³n del minijuego
function updateMinigameScore() {
    minigameScoreDiv.textContent = `PuntuaciÃ³n: ${minigameScore}`;
}

// Inicializar minijuego
function initMinigame() {
    document.addEventListener('keydown', keyDownHandler);
    document.addEventListener('keyup', keyUpHandler);
    addMobileControls(); // Agregar controles mÃ³viles
    moveShip(); // Iniciar movimiento de la nave
    generateStars();
}

// Manejadores de eventos para las teclas
function keyDownHandler(e) {
    keysPressed[e.key] = true;
}

function keyUpHandler(e) {
    keysPressed[e.key] = false;

    // Permitir disparar nuevamente cuando se suelta la barra espaciadora
    if (e.key === ' ' || e.key === 'Spacebar') {
        keysPressed['canShoot'] = true;
    }
}

// Mover la nave de forma continua
function moveShip() {
    if (!minigameActive) return;

    let left = parseInt(ship.style.left);

    if (keysPressed['ArrowLeft'] &amp;&amp; left &gt; 0) {
        ship.style.left = (left - shipSpeed) + 'px';
    }
    if (keysPressed['ArrowRight'] &amp;&amp; left &lt; (800 - ship.offsetWidth)) {
        ship.style.left = (left + shipSpeed) + 'px';
    }
    if ((keysPressed[' '] || keysPressed['Spacebar']) &amp;&amp; keysPressed['canShoot'] !== false) {
        shoot();
        keysPressed['canShoot'] = false; // Evitar disparos continuos
    }

    requestAnimationFrame(moveShip);
}

// Disparar
function shoot() {
    if (!minigameActive) return;

    // Reproducir sonido de disparo
    shootSound.currentTime = 0;
    shootSound.play();

    let bullet = document.createElement('div');
    bullet.className = 'bullet';
    bullet.style.left = (parseInt(ship.style.left) + 22) + 'px';
    bullet.style.bottom = '60px';
    minigameDiv.appendChild(bullet);

    let bulletInterval = setInterval(() =&gt; {
        if (!minigameActive) {
            bullet.remove();
            clearInterval(bulletInterval);
            return;
        }
        let stars = document.getElementsByClassName('star');
        for (let star of stars) {
            let starNumberElement = star.querySelector('.star-number');
            let number = parseInt(starNumberElement.textContent);
            if (isColliding(bullet, star)) {
                if (number % 3 === 0) {
                    star.remove();
                    removeStarFromActive(star);
                    minigameScore += 10;
                    scoreIncrement += 10;
                    updateMinigameScore();
                    adjustStarSpeed();

                    // Reproducir sonido al acertar
                    hitSound.currentTime = 0;
                    hitSound.play();
                } else {
                    lives--;
                    updateLives();
                    checkMinigameOver();
                    star.remove();
                    removeStarFromActive(star);

                    // Reproducir sonido al fallar
                    wrongSound.currentTime = 0;
                    wrongSound.play();
                }
                bullet.remove();
                clearInterval(bulletInterval);
                return;
            }
        }
        let bottom = parseInt(bullet.style.bottom);
        if (bottom &lt; 600) {
            bullet.style.bottom = (bottom + 10) + 'px';
        } else {
            bullet.remove();
            clearInterval(bulletInterval);
        }
    }, 20);
}

// Ajustar la velocidad de las estrellas
function adjustStarSpeed() {
    if (scoreIncrement &gt;= 20) {
        starSpeed += 0.5; // Incrementar la velocidad de las estrellas
        scoreIncrement = 0; // Reiniciar el contador de puntos
    }
}

// Generar estrellas
function generateStars() {
    let starInterval = setInterval(() =&gt; {
        if (!minigameActive) {
            clearInterval(starInterval);
            return;
        }

        let star = document.createElement('div');
        star.className = 'star';
        let number = getRandomInt(1, 900);
        // Envolvemos el nÃºmero en un span
        star.innerHTML = '&lt;span class="star-number"&gt;' + number + '&lt;/span&gt;';

        // Evitar solapamiento de estrellas
        let starLeftPosition = getNonOverlappingPosition();
        if (starLeftPosition === null) {
            // No hay espacio para nuevas estrellas sin solapamiento
            return;
        }

        star.style.left = starLeftPosition + 'px';
        star.style.top = '0px';
        minigameDiv.appendChild(star);
        activeStars.push(star);

        let starFall = setInterval(() =&gt; {
            if (!minigameActive) {
                star.remove();
                clearInterval(starFall);
                return;
            }
            if (isColliding(ship, star)) {
                let starNumberElement = star.querySelector('.star-number');
                let num = parseInt(starNumberElement.textContent);
                if (num % 3 !== 0) {
                    lives--;
                    updateLives();
                    checkMinigameOver();

                    // Reproducir sonido al colisionar con estrella incorrecta
                    wrongSound.currentTime = 0;
                    wrongSound.play();
                }
                star.remove();
                removeStarFromActive(star);
                clearInterval(starFall);
                return;
            }
            let top = parseInt(star.style.top);
            if (top &lt; 580) {
                star.style.top = (top + starSpeed) + 'px';
            } else {
                // Eliminar la estrella si sale del Ã¡rea de juego
                star.remove();
                removeStarFromActive(star);
                clearInterval(starFall);
            }
        }, 20);
    }, 1000);
}

// Obtener una posiciÃ³n que no se superponga con estrellas existentes
function getNonOverlappingPosition() {
    let maxAttempts = 10;
    let attempt = 0;
    let position = null;

    while (attempt &lt; maxAttempts) {
        let left = getRandomInt(0, 740); // 800 (ancho del juego) - 60 (ancho de la estrella)
        let overlap = false;

        for (let star of activeStars) {
            let starLeft = parseInt(star.style.left);
            if (Math.abs(left - starLeft) &lt; 60) { // 60px es el nuevo ancho de la estrella
                overlap = true;
                break;
            }
        }

        if (!overlap) {
            position = left;
            break;
        }

        attempt++;
    }

    return position;
}

// Eliminar estrella del arreglo de estrellas activas
function removeStarFromActive(star) {
    activeStars = activeStars.filter(s =&gt; s !== star);
}

// Verificar colisiÃ³n
function isColliding(a, b) {
    let aRect = a.getBoundingClientRect();
    let bRect = b.getBoundingClientRect();

    return !(
        ((aRect.top + aRect.height) &lt; (bRect.top)) ||
        (aRect.top &gt; (bRect.top + bRect.height)) ||
        ((aRect.left + aRect.width) &lt; bRect.left) ||
        (aRect.left &gt; (bRect.left + bRect.width))
    );
}

// Verificar si el minijuego ha terminado
function checkMinigameOver() {
    if (lives &lt;= 0) {
        endMinigame();
    }
}

// Terminar minijuego
function endMinigame() {
    minigameActive = false;
    minigameDiv.style.display = 'none';
    gameOverModal.style.display = 'block';
    playMinigameButton.style.display = 'none';
    document.removeEventListener('keydown', keyDownHandler);
    document.removeEventListener('keyup', keyUpHandler);
    removeMobileControls(); // Remover controles mÃ³viles

    // Actualizar el puntaje final con el puntaje del minijuego
    finalScore.textContent = `PuntuaciÃ³n Final del Minijuego: ${minigameScore}`;

    // Limpiar estrellas y balas restantes
    let stars = document.getElementsByClassName('star');
    while (stars[0]) {
        stars[0].parentNode.removeChild(stars[0]);
    }
    let bullets = document.getElementsByClassName('bullet');
    while (bullets[0]) {
        bullets[0].parentNode.removeChild(bullets[0]);
    }

    activeStars = [];
}

// Funciones para controles mÃ³viles
function addMobileControls() {
    // Eventos para el botÃ³n izquierdo
    leftButton.addEventListener('touchstart', leftButtonTouchStart);
    leftButton.addEventListener('touchend', leftButtonTouchEnd);
    leftButton.addEventListener('touchstart', (e) =&gt; e.preventDefault());

    // Eventos para el botÃ³n derecho
    rightButton.addEventListener('touchstart', rightButtonTouchStart);
    rightButton.addEventListener('touchend', rightButtonTouchEnd);
    rightButton.addEventListener('touchstart', (e) =&gt; e.preventDefault());

    // Eventos para el botÃ³n de disparo
    shootButton.addEventListener('touchstart', shootButtonTouchStart);
    shootButton.addEventListener('touchend', shootButtonTouchEnd);
    shootButton.addEventListener('touchstart', (e) =&gt; e.preventDefault());
}

function removeMobileControls() {
    // Remover eventos del botÃ³n izquierdo
    leftButton.removeEventListener('touchstart', leftButtonTouchStart);
    leftButton.removeEventListener('touchend', leftButtonTouchEnd);

    // Remover eventos del botÃ³n derecho
    rightButton.removeEventListener('touchstart', rightButtonTouchStart);
    rightButton.removeEventListener('touchend', rightButtonTouchEnd);

    // Remover eventos del botÃ³n de disparo
    shootButton.removeEventListener('touchstart', shootButtonTouchStart);
    shootButton.removeEventListener('touchend', shootButtonTouchEnd);
}

// Manejadores para los botones mÃ³viles
function leftButtonTouchStart() {
    keysPressed['ArrowLeft'] = true;
}

function leftButtonTouchEnd() {
    keysPressed['ArrowLeft'] = false;
}

function rightButtonTouchStart() {
    keysPressed['ArrowRight'] = true;
}

function rightButtonTouchEnd() {
    keysPressed['ArrowRight'] = false;
}

function shootButtonTouchStart() {
    if (minigameActive &amp;&amp; keysPressed['canShoot'] !== false) {
        shoot();
        keysPressed['canShoot'] = false;
    }
}

function shootButtonTouchEnd() {
    keysPressed['canShoot'] = true;
}

// Funciones utilitarias
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
}

function getRandomDecimal(array) {
    return array[Math.floor(Math.random() * array.length)];
}

function generateOptions(correct, base, exponent) {
    let options = [correct];
    options.push(`${base}&lt;sup&gt;${exponent + getRandomInt(1, 3)}&lt;/sup&gt;`);
    options.push(`${base}&lt;sup&gt;${exponent - getRandomInt(1, 3)}&lt;/sup&gt;`);
    options.push(`${base}&lt;sup&gt;${exponent + getRandomInt(4, 6)}&lt;/sup&gt;`);
    return shuffle(options);
}

function shuffle(array) {
    for (let i = array.length - 1; i &gt; 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
    return array;
}

/**
 * Genera opciones para una pregunta de notaciÃ³n cientÃ­fica.
 * Solo una opciÃ³n es correcta (mantisa entre 1 y 10).
 * Las demÃ¡s opciones representan el mismo nÃºmero pero con mantisas fuera de este rango.
 * @param {number} mantissa - La mantisa correcta (entre 1 y 10).
 * @param {number} exponent - El exponente correcto.
 * @returns {Array} - Arreglo de opciones (una correcta y tres incorrectas).
 */
function generateScientificNotationOptions(mantissa, exponent) {
    const correctAnswer = `${mantissa.toFixed(2)} Ã— 10&lt;sup&gt;${exponent}&lt;/sup&gt;`;
    const options = [correctAnswer];

    // OpciÃ³n Incorrecta 1: Mantisa multiplicada por 10, exponente disminuido en 1
    const wrongOption1 = `${(mantissa * 10).toFixed(2)} Ã— 10&lt;sup&gt;${exponent - 3}&lt;/sup&gt;`;
    options.push(wrongOption1);

    // OpciÃ³n Incorrecta 2: Mantisa dividida por 10, exponente incrementado en 1
    const wrongOption2 = `${(mantissa / 10).toFixed(2)} Ã— 10&lt;sup&gt;${exponent + 2}&lt;/sup&gt;`;
    options.push(wrongOption2);

    // OpciÃ³n Incorrecta 3: Otra variaciÃ³n incorrecta (mantisa multiplicada por 100, exponente disminuido en 2)
    const wrongOption3 = `${(mantissa * 100).toFixed(2)} Ã— 10&lt;sup&gt;${exponent - 4}&lt;/sup&gt;`;
    options.push(wrongOption3);

    // Mezclar las opciones para aleatorizar su orden
    return shuffle(options);
}</pre></body></html>