// Variables globales let currentLevel = 1; let timeLeft = 120; let score = 0; let correctAnswer; let questionList = []; let timerInterval; const levelSelect = document.getElementById("level-select"); const infoDiv = document.getElementById("info"); const scoreDiv = document.getElementById("score"); const clock = document.getElementById("clock"); const r = document.getElementById("r"); const optionsDiv = document.getElementById("options"); const resultsDiv = document.getElementById("results"); const questionDiv = document.getElementById("question"); // Para nivel 10 let summands = [9, 6, 3, 5]; let summandIndex = 0; let summandCount = 0; // Inicia el juego function startGame(level) { infoDiv.innerHTML = `Nivel ${level}`; currentLevel = level; timeLeft = 120; score = 0; questionList = []; optionsDiv.style.display = "grid"; resultsDiv.style.display = "none"; levelSelect.style.display = "none"; clock.style.display = "block"; r.style.display = "flex"; scoreDiv.innerHTML = score; generateQuestion(); startTimer(); } // Genera una pregunta function generateQuestion() { let num1, num2, num3, operator, questionText, wrongOptions = []; switch (currentLevel) { // Niveles 1-21 (mismos que antes) case 1: operator = '+'; num1 = Math.floor(Math.random() * 5) + 1; num2 = Math.floor(Math.random() * (6 - num1)); correctAnswer = num1 + num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 10); break; case 2: operator = '-'; num1 = Math.floor(Math.random() * 4) + 1; num2 = Math.floor(Math.random() * (num1 + 1)); correctAnswer = num1 - num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 10); break; case 3: operator = '+'; num1 = Math.floor(Math.random() * 4) + 1; num2 = Math.floor(Math.random() * 5) + 1; correctAnswer = num1 + num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 10); break; case 4: operator = '-'; num1 = Math.floor(Math.random() * 6) + 1; num2 = Math.floor(Math.random() * (num1 + 1)); correctAnswer = num1 - num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 10); break; case 5: operator = '+'; num1 = Math.floor(Math.random() * 4) + 1; num2 = Math.floor(Math.random() * 9) + 1; correctAnswer = num1 + num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 10); break; case 6: operator = '-'; num1 = Math.floor(Math.random() * 10) + 1; num2 = Math.floor(Math.random() * (num1 + 1)); correctAnswer = num1 - num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 10); break; case 7: operator = '+'; let validNum1 = [4, 5, 8, 9]; num1 = validNum1[Math.floor(Math.random() * validNum1.length)]; num2 = Math.floor(Math.random() * 8) + 2; correctAnswer = num1 + num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 20); break; case 8: operator = '-'; num1 = Math.floor(Math.random() * 6) + 5; num2 = Math.floor(Math.random() * (num1 - 2)) + 2; correctAnswer = num1 - num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 10); break; case 9: operator = '×'; if (Math.random() > 0.5) { num1 = Math.floor(Math.random() * 5) + 1; num2 = Math.floor(Math.random() * 9) + 1; } else { num1 = Math.floor(Math.random() * 9) + 1; num2 = Math.floor(Math.random() * 5) + 1; } correctAnswer = num1 * num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 45); break; case 10: operator = '+'; num1 = summands[summandIndex]; num2 = Math.floor(Math.random() * 8) + 2; correctAnswer = num1 + num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 18); summandCount++; if (summandCount === 15) { summandIndex++; summandCount = 0; } if (summandIndex === summands.length) { summandIndex = 0; } break; case 11: operator = '-'; num1 = Math.floor(Math.random() * 11) + 7; num2 = Math.floor(Math.random() * (num1 - 2)) + 2; correctAnswer = num1 - num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, num1); break; case 12: operator = '×'; if (Math.random() > 0.5) { num1 = Math.floor(Math.random() * 9) + 1; num2 = Math.floor(Math.random() * 9) + 1; } else { num1 = Math.floor(Math.random() * 9) + 1; num2 = Math.floor(Math.random() * 9) + 1; } correctAnswer = num1 * num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 45); break; case 13: operator = '÷'; num1 = Math.floor(Math.random() * 9) + 1; num2 = Math.floor(Math.random() * 9) + 1; let product13 = num1 * num2; let divisor13 = Math.random() > 0.5 ? num1 : num2; correctAnswer = product13 / divisor13; questionText = `${product13} ${operator} ${divisor13} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 1, 9, true); break; case 14: operator = '+'; if (score < 15) { num1 = 7; num2 = Math.floor(Math.random() * 7) + 3; } else if (score < 30) { num1 = 9; num2 = Math.floor(Math.random() * 8) + 2; } else if (score < 45) { num1 = 6; num2 = Math.floor(Math.random() * 8) + 2; } else { num1 = 8; num2 = Math.floor(Math.random() * 8) + 2; } correctAnswer = num1 + num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 20); break; case 15: operator = '-'; num1 = Math.floor(Math.random() * 16) + 4; num2 = Math.floor(Math.random() * 8) + 2; while (num1 - num2 < 0) { num1 = Math.floor(Math.random() * 16) + 4; num2 = Math.floor(Math.random() * 8) + 2; } correctAnswer = num1 - num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 20); break; case 16: operator = '×'; if (Math.random() > 0.5) { num1 = Math.floor(Math.random() * 9) + 1; num2 = Math.floor(Math.random() * 9) + 1; } else { num1 = Math.floor(Math.random() * 9) + 1; num2 = Math.floor(Math.random() * 9) + 1; } correctAnswer = num1 * num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 45); break; case 17: operator = '÷'; let factor17a = Math.floor(Math.random() * 8) + 2; let factor17b = Math.floor(Math.random() * 8) + 2; num1 = factor17a * factor17b; num2 = Math.random() > 0.5 ? factor17a : factor17b; correctAnswer = num1 / num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 1, 81, true); break; case 18: operator = '+'; num1 = Math.floor(Math.random() * 9) + 11; num2 = Math.floor(Math.random() * 8) + 2; correctAnswer = num1 + num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 28); break; case 19: operator = '-'; num1 = Math.floor(Math.random() * 9) + 11; num2 = Math.floor(Math.random() * 8) + 2; while (num1 - num2 < 0) { num1 = Math.floor(Math.random() * 9) + 11; num2 = Math.floor(Math.random() * 8) + 2; } correctAnswer = num1 - num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 20); break; case 20: operator = '×'; if (Math.random() > 0.5) { num1 = Math.floor(Math.random() * 9) + 1; num2 = Math.floor(Math.random() * 9) + 1; } else { num1 = Math.floor(Math.random() * 9) + 1; num2 = Math.floor(Math.random() * 9) + 1; } correctAnswer = num1 * num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 45); break; case 21: operator = '÷'; let factor21a = Math.floor(Math.random() * 8) + 2; let factor21b = Math.floor(Math.random() * 8) + 2; num1 = factor21a * factor21b; num2 = Math.random() > 0.5 ? factor21a : factor21b; correctAnswer = num1 / num2; questionText = `${num1} ${operator} ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 1, 81, true); break; // Nuevos niveles 22-30 case 22: // Suma de 3 números hasta 30 operator = '+'; num1 = Math.floor(Math.random() * 9) + 5; num2 = Math.floor(Math.random() * 9) + 5; num3 = Math.floor(Math.random() * 9) + 5; correctAnswer = num1 + num2 + num3; questionText = `${num1} + ${num2} + ${num3} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 10, 40); break; case 23: // Resta con números de 2 cifras operator = '-'; num1 = Math.floor(Math.random() * 50) + 20; num2 = Math.floor(Math.random() * 20) + 5; correctAnswer = num1 - num2; questionText = `${num1} - ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0, 50); break; case 24: // Multiplicación 2 cifras × 1 cifra operator = '×'; num1 = Math.floor(Math.random() * 90) + 10; num2 = Math.floor(Math.random() * 8) + 2; correctAnswer = num1 * num2; questionText = `${num1} × ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 20, 900); break; case 25: // División con dividendos de 2 cifras operator = '÷'; num2 = Math.floor(Math.random() * 8) + 2; correctAnswer = Math.floor(Math.random() * 9) + 2; num1 = num2 * correctAnswer; questionText = `${num1} ÷ ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 1, 50, true); break; case 26: // Sumas con decimales (1 decimal) operator = '+'; num1 = (Math.floor(Math.random() * 9) + 1) + (Math.floor(Math.random() * 9) / 10); num2 = (Math.floor(Math.random() * 9) + 1) + (Math.floor(Math.random() * 9) / 10); correctAnswer = Math.round((num1 + num2) * 10) / 10; questionText = `${num1.toFixed(1)} + ${num2.toFixed(1)} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 1, 20, false, 1); break; case 27: // Restas con decimales operator = '-'; num1 = (Math.floor(Math.random() * 9) + 5) + (Math.floor(Math.random() * 9) / 10); num2 = (Math.floor(Math.random() * 5) + 1) + (Math.floor(Math.random() * 9) / 10); correctAnswer = Math.round((num1 - num2) * 10) / 10; questionText = `${num1.toFixed(1)} - ${num2.toFixed(1)} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 0.1, 15, false, 1); break; case 28: // Multiplicación con decimales operator = '×'; num1 = (Math.floor(Math.random() * 8) + 2) + (Math.floor(Math.random() * 5) / 10); num2 = Math.floor(Math.random() * 8) + 2; correctAnswer = Math.round((num1 * num2) * 10) / 10; questionText = `${num1.toFixed(1)} × ${num2} = ?`; wrongOptions = generateWrongOptions(correctAnswer, 5, 100, false, 1); break; case 29: // Potencias cuadradas operator = '²'; num1 = Math.floor(Math.random() * 10) + 2; correctAnswer = num1 * num1; questionText = `${num1}² = ?`; wrongOptions = generateWrongOptions(correctAnswer, 4, 144, true); break; case 30: // Operaciones combinadas (2 operaciones) let ops = ['+', '-', '×']; let op1 = ops[Math.floor(Math.random() * ops.length)]; let op2 = ops[Math.floor(Math.random() * ops.length)]; num1 = Math.floor(Math.random() * 8) + 2; num2 = Math.floor(Math.random() * 8) + 2; num3 = Math.floor(Math.random() * 5) + 1; // Prioridad de operadores let tempResult = op1 === '×' ? num1 * num2 : (op1 === '+' ? num1 + num2 : num1 - num2); correctAnswer = op2 === '×' ? tempResult * num3 : (op2 === '+' ? tempResult + num3 : tempResult - num3); questionText = `${num1} ${op1} ${num2} ${op2} ${num3} = ?`; wrongOptions = generateWrongOptions(correctAnswer, -20, 50, true); break; } questionList.push(questionText); questionDiv.innerText = questionText; generateOptions(wrongOptions); } function generateWrongOptions(correct, min, max, integerOnly = false, decimals = 0) { let wrong = []; for (let i = 0; i < 2; i++) { let offset = (Math.random() > 0.5 ? 1 : -1) * (Math.floor(Math.random() * 3) + 1); let incorrect = decimals > 0 ? Math.round((correct + offset) * Math.pow(10, decimals)) / Math.pow(10, decimals) : correct + offset; if (incorrect >= min && incorrect <= max && (!integerOnly || Number.isInteger(incorrect))) { wrong.push(incorrect); } else { i--; } } return wrong; } function generateOptions(wrongOptions) { let options = [correctAnswer, ...wrongOptions]; options.sort(() => Math.random() - 0.5); optionsDiv.innerHTML = ''; options.forEach(option => { let button = document.createElement('button'); button.innerText = typeof option === 'number' && option % 1 !== 0 ? option.toFixed(1) : option; button.className = 'option'; button.onclick = () => handleAnswer(option, button); optionsDiv.appendChild(button); }); } function handleAnswer(answer, button) { if (answer === correctAnswer) { score++; button.classList.add("correct"); setTimeout(() => button.classList.remove("correct"), 1000); } else { score--; button.classList.add("incorrect"); setTimeout(() => button.classList.remove("incorrect"), 1000); } score = Math.max(0, score); scoreDiv.innerHTML = score; setTimeout(() => { if (timeLeft > 0) { generateQuestion(); } }, 500); } function startTimer() { clearInterval(timerInterval); timerInterval = setInterval(() => { if (timeLeft <= 0) { clearInterval(timerInterval); showResults(); } else { let minutes = Math.floor(timeLeft / 60); let seconds = timeLeft % 60; clock.innerText = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; timeLeft--; } }, 1000); } function showResults() { resultsDiv.style.display = "block"; resultsDiv.innerText = `¡Tiempo! Tu puntuación final: ${score} puntos`; optionsDiv.style.display = "none"; levelSelect.style.display = "grid"; clock.style.display = "none"; } function generatePDF() { const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); // Título doc.setFontSize(20); doc.setFont('helvetica', 'bold'); doc.text('Fast Math - Cálculo Mental', 105, 20, { align: 'center' }); // Información doc.setFontSize(12); doc.setFont('helvetica', 'normal'); doc.text(`Nivel: ${currentLevel}`, 20, 35); doc.text(`Fecha: ___________`, 20, 42); doc.text(`Nombre: ___________________________________`, 20, 49); // Preguntas doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.text('Ejercicios:', 20, 60); doc.setFontSize(12); doc.setFont('helvetica', 'normal'); let x = 20; let y = 70; let counter = 0; questionList.slice(0, 60).forEach((question, index) => { let cleanedQuestion = question.replace(" = ?", ""); doc.text(`${index + 1}. ${cleanedQuestion} = ______`, x, y); counter++; y += 8; // Nueva columna después de 25 ejercicios if (counter === 25) { x = 110; y = 70; } // Nueva página después de 50 ejercicios if (counter === 50) { doc.addPage(); x = 20; y = 20; } }); // Footer doc.setFontSize(10); doc.setTextColor(150); doc.text('Generado con Fast Math - Olesur.com', 105, 285, { align: 'center' }); // Descargar PDF doc.save(`FastMath-Nivel${currentLevel}.pdf`); alert('✅ PDF generado y descargado'); } � 2025 olesur.com