Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Infinite Algebra Game</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| @keyframes pulse { | |
| 0%, 100% { transform: scale(1); } | |
| 50% { transform: scale(1.05); } | |
| } | |
| .pulse-animation { | |
| animation: pulse 1.5s infinite; | |
| } | |
| .fade-in { | |
| animation: fadeIn 0.5s ease-in-out; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .shake { | |
| animation: shake 0.5s; | |
| } | |
| @keyframes shake { | |
| 0%, 100% { transform: translateX(0); } | |
| 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); } | |
| 20%, 40%, 60%, 80% { transform: translateX(5px); } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gradient-to-br from-indigo-900 to-purple-800 min-h-screen text-white font-sans"> | |
| <div class="container mx-auto px-4 py-8 max-w-3xl"> | |
| <header class="text-center mb-8"> | |
| <h1 class="text-4xl font-bold mb-2">∞ Infinite Algebra Game</h1> | |
| <p class="text-xl opacity-80">Solve algebra problems as they get progressively harder!</p> | |
| </header> | |
| <div class="bg-white/10 backdrop-blur-md rounded-xl shadow-2xl overflow-hidden transition-all duration-300"> | |
| <!-- Game Stats --> | |
| <div class="flex justify-between items-center p-6 border-b border-white/10"> | |
| <div class="text-center"> | |
| <div class="text-sm opacity-70">Level</div> | |
| <div class="text-2xl font-bold" id="level">1</div> | |
| </div> | |
| <div class="text-center"> | |
| <div class="text-sm opacity-70">Score</div> | |
| <div class="text-2xl font-bold" id="score">0</div> | |
| </div> | |
| <div class="text-center"> | |
| <div class="text-sm opacity-70">Streak</div> | |
| <div class="text-2xl font-bold" id="streak">0</div> | |
| </div> | |
| </div> | |
| <!-- Game Area --> | |
| <div class="p-8 text-center"> | |
| <div class="mb-8"> | |
| <div class="text-lg mb-2 opacity-80">Solve for x:</div> | |
| <div class="text-5xl font-bold mb-6 fade-in" id="problem">2x + 5 = 15</div> | |
| <div class="max-w-xs mx-auto relative"> | |
| <input type="number" id="answer" class="w-full bg-white/20 border border-white/30 rounded-lg py-4 px-6 text-2xl text-center focus:outline-none focus:ring-2 focus:ring-purple-400 transition" placeholder="Your answer" autofocus> | |
| <button id="submit-btn" class="mt-4 bg-purple-600 hover:bg-purple-500 text-white font-bold py-3 px-8 rounded-full transition-all duration-200 transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-purple-400 focus:ring-opacity-50"> | |
| Submit <i class="fas fa-arrow-right ml-2"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div id="feedback" class="h-8 mb-4"></div> | |
| <div class="bg-white/10 rounded-lg p-4 text-left hidden" id="hint-box"> | |
| <div class="flex items-start"> | |
| <div class="mr-3 text-purple-300 text-xl"><i class="fas fa-lightbulb"></i></div> | |
| <div> | |
| <div class="font-bold mb-1">Hint</div> | |
| <div id="hint-text">Remember to isolate x by performing inverse operations on both sides of the equation.</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Game Controls --> | |
| <div class="p-6 border-t border-white/10 flex justify-between"> | |
| <button id="hint-btn" class="text-purple-300 hover:text-purple-200 transition flex items-center"> | |
| <i class="fas fa-lightbulb mr-2"></i> Get Hint | |
| </button> | |
| <button id="new-game-btn" class="text-white/70 hover:text-white transition flex items-center"> | |
| <i class="fas fa-redo mr-2"></i> New Game | |
| </button> | |
| </div> | |
| </div> | |
| <!-- How to Play --> | |
| <div class="mt-8 bg-white/10 backdrop-blur-md rounded-xl p-6"> | |
| <h2 class="text-xl font-bold mb-4 flex items-center"> | |
| <i class="fas fa-question-circle mr-2"></i> How to Play | |
| </h2> | |
| <ul class="space-y-2"> | |
| <li class="flex items-start"> | |
| <i class="fas fa-check-circle text-purple-300 mr-2 mt-1"></i> | |
| <span>Solve the algebra equation for x</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <i class="fas fa-check-circle text-purple-300 mr-2 mt-1"></i> | |
| <span>Type your answer in the box and press Submit</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <i class="fas fa-check-circle text-purple-300 mr-2 mt-1"></i> | |
| <span>Problems get harder as you level up</span> | |
| </li> | |
| <li class="flex items-start"> | |
| <i class="fas fa-check-circle text-purple-300 mr-2 mt-1"></i> | |
| <span>Correct answers give you points and increase your streak</span> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| <script> | |
| // Game state | |
| const gameState = { | |
| level: 1, | |
| score: 0, | |
| streak: 0, | |
| currentProblem: null, | |
| correctAnswer: null, | |
| hintShown: false | |
| }; | |
| // DOM elements | |
| const elements = { | |
| level: document.getElementById('level'), | |
| score: document.getElementById('score'), | |
| streak: document.getElementById('streak'), | |
| problem: document.getElementById('problem'), | |
| answer: document.getElementById('answer'), | |
| submitBtn: document.getElementById('submit-btn'), | |
| feedback: document.getElementById('feedback'), | |
| hintBox: document.getElementById('hint-box'), | |
| hintText: document.getElementById('hint-text'), | |
| hintBtn: document.getElementById('hint-btn'), | |
| newGameBtn: document.getElementById('new-game-btn') | |
| }; | |
| // Initialize game | |
| function initGame() { | |
| gameState.level = 1; | |
| gameState.score = 0; | |
| gameState.streak = 0; | |
| gameState.hintShown = false; | |
| updateUI(); | |
| generateProblem(); | |
| elements.answer.value = ''; | |
| elements.answer.focus(); | |
| elements.feedback.innerHTML = ''; | |
| elements.hintBox.classList.add('hidden'); | |
| } | |
| // Update UI with current game state | |
| function updateUI() { | |
| elements.level.textContent = gameState.level; | |
| elements.score.textContent = gameState.score; | |
| elements.streak.textContent = gameState.streak; | |
| } | |
| // Generate a new algebra problem based on current level | |
| function generateProblem() { | |
| let a, b, c, equation, answer; | |
| // Adjust problem difficulty based on level | |
| if (gameState.level <= 3) { | |
| // Simple equations: ax + b = c | |
| a = getRandomInt(1, 5); | |
| b = getRandomInt(1, 10); | |
| c = a * getRandomInt(1, 10) + b; | |
| equation = `${a}x + ${b} = ${c}`; | |
| answer = (c - b) / a; | |
| } else if (gameState.level <= 6) { | |
| // Equations with subtraction: ax - b = c | |
| a = getRandomInt(1, 8); | |
| b = getRandomInt(1, 15); | |
| c = a * getRandomInt(1, 10) - b; | |
| equation = `${a}x - ${b} = ${c}`; | |
| answer = (c + b) / a; | |
| } else if (gameState.level <= 9) { | |
| // Equations with multiplication coefficients: a(bx + c) = d | |
| a = getRandomInt(2, 5); | |
| b = getRandomInt(1, 5); | |
| c = getRandomInt(1, 10); | |
| const d = a * (b * getRandomInt(1, 10) + c); | |
| equation = `${a}(${b}x + ${c}) = ${d}`; | |
| answer = (d / a - c) / b; | |
| } else if (gameState.level <= 12) { | |
| // Equations with division: (ax + b)/c = d | |
| a = getRandomInt(1, 5); | |
| b = getRandomInt(1, 10); | |
| c = getRandomInt(2, 5); | |
| const d = Math.floor((a * getRandomInt(1, 10) + b) / c); | |
| equation = `(${a}x + ${b})/${c} = ${d}`; | |
| answer = (d * c - b) / a; | |
| } else { | |
| // More complex equations with multiple operations | |
| const operation = getRandomInt(1, 3); | |
| switch(operation) { | |
| case 1: | |
| // ax + b = cx + d | |
| a = getRandomInt(1, 6); | |
| b = getRandomInt(1, 15); | |
| c = getRandomInt(1, 6); | |
| const d = (a - c) * getRandomInt(1, 10) + b; | |
| equation = `${a}x + ${b} = ${c}x + ${d}`; | |
| answer = (d - b) / (a - c); | |
| break; | |
| case 2: | |
| // a(x + b) = c(x - d) | |
| a = getRandomInt(2, 5); | |
| b = getRandomInt(1, 5); | |
| c = getRandomInt(2, 5); | |
| const e = getRandomInt(1, 5); | |
| const f = (a * (e + b)) / c + e; | |
| equation = `${a}(x + ${b}) = ${c}(x - ${e})`; | |
| answer = f; | |
| break; | |
| case 3: | |
| // (ax + b)/(cx + d) = e | |
| a = getRandomInt(1, 4); | |
| b = getRandomInt(1, 8); | |
| c = getRandomInt(1, 4); | |
| const g = getRandomInt(1, 3); | |
| const h = getRandomInt(1, 5); | |
| const i = (a * h + b) / (c * h + g); | |
| equation = `(${a}x + ${b})/(${c}x + ${g}) = ${i}`; | |
| answer = h; | |
| break; | |
| } | |
| } | |
| gameState.currentProblem = equation; | |
| gameState.correctAnswer = answer; | |
| gameState.hintShown = false; | |
| // Add fade-in animation | |
| elements.problem.classList.remove('fade-in'); | |
| void elements.problem.offsetWidth; // Trigger reflow | |
| elements.problem.classList.add('fade-in'); | |
| elements.problem.textContent = equation; | |
| elements.hintBox.classList.add('hidden'); | |
| // Generate hint based on problem type | |
| generateHint(equation, answer); | |
| } | |
| // Generate a hint for the current problem | |
| function generateHint(equation, answer) { | |
| let hint = ""; | |
| if (equation.includes('+') && !equation.includes('(') && !equation.includes('/')) { | |
| hint = `To solve ${equation}, subtract the constant term from both sides, then divide by the coefficient of x.`; | |
| } else if (equation.includes('-') && !equation.includes('(') && !equation.includes('/')) { | |
| hint = `To solve ${equation}, add the constant term to both sides, then divide by the coefficient of x.`; | |
| } else if (equation.includes('(') && equation.includes(')') && !equation.includes('/')) { | |
| hint = `First, distribute the multiplication across the parentheses in ${equation}, then combine like terms and solve as usual.`; | |
| } else if (equation.includes('/')) { | |
| hint = `For ${equation}, start by eliminating the denominator by multiplying both sides by it, then proceed to solve the resulting equation.`; | |
| } else { | |
| hint = `Combine like terms in ${equation} to isolate x on one side of the equation, then solve for x.`; | |
| } | |
| elements.hintText.textContent = hint; | |
| } | |
| // Check the user's answer | |
| function checkAnswer() { | |
| const userAnswer = parseFloat(elements.answer.value); | |
| if (isNaN(userAnswer)) { | |
| showFeedback('Please enter a valid number', 'error'); | |
| elements.answer.classList.add('shake'); | |
| setTimeout(() => elements.answer.classList.remove('shake'), 500); | |
| return; | |
| } | |
| // Round to 2 decimal places for comparison | |
| const roundedUserAnswer = Math.round(userAnswer * 100) / 100; | |
| const roundedCorrectAnswer = Math.round(gameState.correctAnswer * 100) / 100; | |
| if (roundedUserAnswer === roundedCorrectAnswer) { | |
| // Correct answer | |
| gameState.score += gameState.level * 10; | |
| gameState.streak += 1; | |
| // Bonus for streak | |
| if (gameState.streak >= 3) { | |
| gameState.score += gameState.streak * 5; | |
| } | |
| // Level up every 3 correct answers | |
| if (gameState.streak % 3 === 0) { | |
| gameState.level += 1; | |
| } | |
| updateUI(); | |
| showFeedback(`Correct! x = ${roundedCorrectAnswer}`, 'success'); | |
| // Add celebration effect | |
| elements.problem.classList.add('pulse-animation'); | |
| setTimeout(() => { | |
| elements.problem.classList.remove('pulse-animation'); | |
| generateProblem(); | |
| elements.answer.value = ''; | |
| elements.answer.focus(); | |
| }, 1000); | |
| } else { | |
| // Wrong answer | |
| gameState.streak = 0; | |
| updateUI(); | |
| showFeedback(`Incorrect. Try again!`, 'error'); | |
| elements.answer.classList.add('shake'); | |
| setTimeout(() => elements.answer.classList.remove('shake'), 500); | |
| elements.answer.select(); | |
| } | |
| } | |
| // Show feedback message | |
| function showFeedback(message, type) { | |
| elements.feedback.innerHTML = ''; | |
| const feedbackEl = document.createElement('div'); | |
| feedbackEl.className = `px-4 py-2 rounded-lg font-medium fade-in ${type === 'success' ? 'bg-green-500/20 text-green-200' : 'bg-red-500/20 text-red-200'}`; | |
| feedbackEl.textContent = message; | |
| elements.feedback.appendChild(feedbackEl); | |
| // Remove feedback after 3 seconds | |
| setTimeout(() => { | |
| feedbackEl.classList.remove('fade-in'); | |
| feedbackEl.classList.add('opacity-0', 'transition-opacity', 'duration-300'); | |
| setTimeout(() => { | |
| if (elements.feedback.contains(feedbackEl)) { | |
| elements.feedback.removeChild(feedbackEl); | |
| } | |
| }, 300); | |
| }, 3000); | |
| } | |
| // Show hint | |
| function showHint() { | |
| if (!gameState.hintShown) { | |
| elements.hintBox.classList.remove('hidden'); | |
| gameState.hintShown = true; | |
| // Penalize for using hint | |
| gameState.score = Math.max(0, gameState.score - 5); | |
| updateUI(); | |
| } | |
| } | |
| // Helper function to get random integer | |
| function getRandomInt(min, max) { | |
| return Math.floor(Math.random() * (max - min + 1)) + min; | |
| } | |
| // Event listeners | |
| elements.submitBtn.addEventListener('click', checkAnswer); | |
| elements.answer.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') { | |
| checkAnswer(); | |
| } | |
| }); | |
| elements.hintBtn.addEventListener('click', showHint); | |
| elements.newGameBtn.addEventListener('click', initGame); | |
| // Start the game | |
| initGame(); | |
| </script> | |
| </body> | |
| </html> |