import React, { useState, useEffect, useRef } from 'react'; import { Timer, Zap, CheckCircle2, XCircle, RotateCcw, Trophy, Settings, Activity } from 'lucide-react'; // Utility to generate a base number with statistical preference to 1-10 const generateBaseNumber = () => { // 75% chance to get a number between 1 and 10 const preferSmall = Math.random() < 0.75; if (preferSmall) { return Math.floor(Math.random() * 10) + 1; // 1 to 10 } else { return Math.floor(Math.random() * 10) + 11; // 11 to 20 } }; export default function MathGame() { const [gameState, setGameState] = useState('menu'); // 'menu', 'playing', 'summary' // Game Settings const [mode, setMode] = useState('power'); const [timeLimit, setTimeLimit] = useState(60); // in seconds const [powerMin, setPowerMin] = useState(2); const [powerMax, setPowerMax] = useState(2); // Active Game State const [score, setScore] = useState(0); const [timeLeft, setTimeLeft] = useState(0); const [currentQuestion, setCurrentQuestion] = useState(null); const [inputValue, setInputValue] = useState(''); const [history, setHistory] = useState([]); // Visual feedback state const [feedback, setFeedback] = useState(null); // 'correct' | 'incorrect' | null const inputRef = useRef(null); // Focus input automatically when playing useEffect(() => { if (gameState === 'playing' && inputRef.current) { inputRef.current.focus(); } }, [gameState, currentQuestion]); // Timer logic useEffect(() => { let timer; if (gameState === 'playing' && timeLeft > 0) { timer = setInterval(() => { setTimeLeft((prev) => { if (prev <= 1) { endGame(); return 0; } return prev - 1; }); }, 1000); } return () => clearInterval(timer); }, [gameState, timeLeft]); const generateQuestion = () => { const base = generateBaseNumber(); const power = Math.floor(Math.random() * (powerMax - powerMin + 1)) + powerMin; const answer = Math.pow(base, power); setCurrentQuestion({ base, power, answer }); }; const startGame = () => { setScore(0); setTimeLeft(timeLimit); setHistory([]); setFeedback(null); setInputValue(''); generateQuestion(); setGameState('playing'); }; const endGame = () => { setGameState('summary'); }; const handlePowerMinChange = (e) => { const val = parseInt(e.target.value) || 1; setPowerMin(val); if (val > powerMax) setPowerMax(val); }; const handlePowerMaxChange = (e) => { const val = parseInt(e.target.value) || 1; setPowerMax(val); if (val < powerMin) setPowerMin(val); }; const handleSubmit = (e) => { e.preventDefault(); if (!inputValue.trim() || !currentQuestion) return; const userAnswer = parseInt(inputValue, 10); const isCorrect = userAnswer === currentQuestion.answer; if (isCorrect) { setScore(s => s + 1); setFeedback('correct'); } else { setFeedback('incorrect'); } // Add to history setHistory(prev => [...prev, { ...currentQuestion, userAnswer, isCorrect }]); // Briefly show feedback then next question setTimeout(() => setFeedback(null), 300); setInputValue(''); generateQuestion(); }; // --- RENDERERS --- const renderMenu = () => (
Test your mental calculation limits
Set both to the same number for a specific power (e.g., ^2), or different numbers for a random range (e.g., ^2 to ^5).
Press Enter to submit
Here is how you performed.