"use client"; import { useState, useEffect, useCallback, useRef } from "react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { motion, AnimatePresence } from "framer-motion"; import { Play, Trophy, Users, Zap, Brain, Globe, Eye, BookOpen, Star, Clock, Target, Ghost, Coffee, Zap as PowerZap, Book, Camera, PenTool, Volume2, VolumeX } from "lucide-react"; // Types type Operation = "+" | "-" | "×" | "÷"; type GameMode = | "speedrun" | "pvp" | "memory" | "equationBuilder" | "blindSolve" | "dailyPuzzle" | "teamBattle"; type MathProblem = { operand1: number; operand2: number; operation: Operation; answer: number; }; type PlayerStats = { score: number; streak: number; maxStreak: number; problemsSolved: number; problemsCorrect: number; accuracy: number; }; type PowerUp = { id: string; name: string; description: string; icon: JSX.Element; active: boolean; duration: number; // in seconds }; type Tier = "Bronze" | "Silver" | "Gold" | "Platinum" | "Diamond"; // Game data const TIER_COLORS: Record = { Bronze: "text-amber-800", Silver: "text-gray-400", Gold: "text-yellow-500", Platinum: "text-blue-400", Diamond: "text-purple-400" }; const POWER_UPS: PowerUp[] = [ { id: "freeze-time", name: "Freeze Time", description: "5 extra seconds", icon: , active: false, duration: 5 }, { id: "second-chance", name: "Second Chance", description: "Undo one wrong answer", icon: , active: false, duration: 0 }, { id: "double-points", name: "Double Points", description: "10s multiplier", icon: , active: false, duration: 10 } ]; const TRIVIA_QUESTIONS = [ { question: "Who invented the equals sign?", answer: "Robert Recorde" }, { question: "What is the only even prime number?", answer: "2" }, { question: "How many sides does a hexagon have?", answer: "6" }, { question: "What is the value of Pi to 3 decimal places?", answer: "3.141" }, { question: "What is the Roman numeral for 1000?", answer: "M" } ]; export default function NumBlitzApp() { // Game state const [gameMode, setGameMode] = useState(null); const [timeLeft, setTimeLeft] = useState(30); const [isActive, setIsActive] = useState(false); const [currentProblem, setCurrentProblem] = useState(null); const [userAnswer, setUserAnswer] = useState(""); const [playerStats, setPlayerStats] = useState({ score: 0, streak: 0, maxStreak: 0, problemsSolved: 0, problemsCorrect: 0, accuracy: 0 }); const [feedback, setFeedback] = useState<{ type: "correct" | "incorrect"; message: string } | null>(null); const [gameOver, setGameOver] = useState(false); const [opponentScore, setOpponentScore] = useState(0); const [tier, setTier] = useState("Bronze"); const [powerUps, setPowerUps] = useState(POWER_UPS); const [activePowerUp, setActivePowerUp] = useState(null); const [triviaQuestion, setTriviaQuestion] = useState(""); const [triviaAnswer, setTriviaAnswer] = useState(""); const [showTrivia, setShowTrivia] = useState(false); const [fatigueData, setFatigueData] = useState([]); const [dailyChallengeActive, setDailyChallengeActive] = useState(false); const [dailyChallengeTime, setDailyChallengeTime] = useState("18:00 UTC"); const [storyProgress, setStoryProgress] = useState(0); const [storyUnlocked, setStoryUnlocked] = useState(false); // Refs const timerRef = useRef(null); const fatigueTimerRef = useRef(null); // Generate math problem const generateProblem = useCallback((): MathProblem => { const operations: Operation[] = ["+", "-", "×", "÷"]; const operation = operations[Math.floor(Math.random() * operations.length)]; let operand1: number; let operand2: number; switch (operation) { case "+": operand1 = Math.floor(Math.random() * 50) + 1; operand2 = Math.floor(Math.random() * 50) + 1; break; case "-": operand1 = Math.floor(Math.random() * 50) + 1; operand2 = Math.floor(Math.random() * operand1) + 1; break; case "×": operand1 = Math.floor(Math.random() * 12) + 1; operand2 = Math.floor(Math.random() * 12) + 1; break; case "÷": operand2 = Math.floor(Math.random() * 12) + 1; operand1 = operand2 * (Math.floor(Math.random() * 12) + 1); break; default: operand1 = 1; operand2 = 1; } let answer: number; switch (operation) { case "+": answer = operand1 + operand2; break; case "-": answer = operand1 - operand2; break; case "×": answer = operand1 * operand2; break; case "÷": answer = operand1 / operand2; break; default: answer = 0; } return { operand1, operand2, operation, answer }; }, []); // Format problem for display const formatProblem = (problem: MathProblem): string => { return `${problem.operand1} ${problem.operation} ${problem.operand2} = ?`; }; // Handle timer useEffect(() => { if (isActive && timeLeft > 0) { timerRef.current = setInterval(() => { setTimeLeft((time) => { if (time <= 1) { setIsActive(false); setGameOver(true); return 0; } return time - 1; }); }, 1000); } else if (timerRef.current) { clearInterval(timerRef.current); } return () => { if (timerRef.current) clearInterval(timerRef.current); }; }, [isActive, timeLeft]); // Fatigue tracking useEffect(() => { if (isActive && !fatigueTimerRef.current) { fatigueTimerRef.current = setInterval(() => { setFatigueData(prev => { const newData = [...prev, playerStats.accuracy]; if (newData.length > 20) newData.shift(); return newData; }); }, 5000); } else if (!isActive && fatigueTimerRef.current) { clearInterval(fatigueTimerRef.current); fatigueTimerRef.current = null; } return () => { if (fatigueTimerRef.current) { clearInterval(fatigueTimerRef.current); fatigueTimerRef.current = null; } }; }, [isActive, playerStats.accuracy]); // Handle answer submission const handleSubmit = useCallback(() => { if (!userAnswer || !currentProblem || !isActive) return; const answer = parseFloat(userAnswer); const isCorrect = answer === currentProblem.answer; if (isCorrect) { const newStreak = playerStats.streak + 1; const points = activePowerUp?.id === "double-points" ? 20 * newStreak : 10 * newStreak; setPlayerStats(prev => ({ ...prev, streak: newStreak, maxStreak: Math.max(prev.maxStreak, newStreak), score: prev.score + points, problemsCorrect: prev.problemsCorrect + 1, problemsSolved: prev.problemsSolved + 1, accuracy: prev.problemsSolved > 0 ? Math.round(((prev.problemsCorrect + 1) / (prev.problemsSolved + 1)) * 100) : 100 })); setFeedback({ type: "correct", message: "Correct!" }); // Check for story unlock if (newStreak % 5 === 0) { setStoryUnlocked(true); setStoryProgress(prev => prev + 1); } } else { setPlayerStats(prev => ({ ...prev, streak: 0, problemsSolved: prev.problemsSolved + 1, accuracy: prev.problemsSolved > 0 ? Math.round((prev.problemsCorrect / (prev.problemsSolved + 1)) * 100) : 0 })); setFeedback({ type: "incorrect", message: `Incorrect! Answer: ${currentProblem.answer}` }); } // Generate new problem setCurrentProblem(generateProblem()); setUserAnswer(""); // Clear feedback after delay setTimeout(() => setFeedback(null), 1000); // Handle PVP mode if (gameMode === "pvp") { // Simulate opponent scoring if (Math.random() > 0.5) { setOpponentScore(prev => prev + 10); } } }, [userAnswer, currentProblem, isActive, playerStats, activePowerUp, gameMode, generateProblem]); // Handle key presses const handleKeyPress = useCallback((key: string) => { if (!isActive) return; if (key === "Enter") { handleSubmit(); } else if (key === "Backspace") { setUserAnswer(prev => prev.slice(0, -1)); } else if (/^[0-9.-]$/.test(key)) { setUserAnswer(prev => prev + key); } }, [isActive, handleSubmit]); // Keyboard event listener useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { handleKeyPress(e.key); }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); }, [handleKeyPress]); // Start game const startGame = (mode: GameMode) => { setGameMode(mode); setIsActive(true); setGameOver(false); setTimeLeft(mode === "pvp" ? 60 : 30); setPlayerStats({ score: 0, streak: 0, maxStreak: 0, problemsSolved: 0, problemsCorrect: 0, accuracy: 100 }); setOpponentScore(0); setCurrentProblem(generateProblem()); setUserAnswer(""); setFeedback(null); setStoryUnlocked(false); setFatigueData([]); // Set daily challenge flag if (mode === "dailyPuzzle") { setDailyChallengeActive(true); } else { setDailyChallengeActive(false); } // Show trivia occasionally if (Math.random() > 0.7) { const randomTrivia = TRIVIA_QUESTIONS[Math.floor(Math.random() * TRIVIA_QUESTIONS.length)]; setTriviaQuestion(randomTrivia.question); setTriviaAnswer(randomTrivia.answer); setShowTrivia(true); setTimeout(() => setShowTrivia(false), 5000); } }; // Activate power-up const activatePowerUp = (powerUp: PowerUp) => { if (powerUp.active) return; setActivePowerUp(powerUp); setPowerUps(prev => prev.map(p => p.id === powerUp.id ? { ...p, active: true } : p ) ); // Apply power-up effects if (powerUp.id === "freeze-time") { setTimeLeft(prev => prev + powerUp.duration); } // Deactivate after duration if (powerUp.duration > 0) { setTimeout(() => { setActivePowerUp(null); setPowerUps(prev => prev.map(p => p.id === powerUp.id ? { ...p, active: false } : p ) ); }, powerUp.duration * 1000); } }; // Reset game const resetGame = () => { setGameMode(null); setIsActive(false); setGameOver(false); setTimeLeft(30); setCurrentProblem(null); setUserAnswer(""); setFeedback(null); setOpponentScore(0); setDailyChallengeActive(false); setShowTrivia(false); }; // Render game screen based on mode const renderGameScreen = () => { if (!gameMode) return null; return (
{/* Header */}
TIME
{timeLeft}s
SCORE
{playerStats.score}
STREAK
{playerStats.streak}
{gameMode === "pvp" && (
OPPONENT
{opponentScore}
)}
TIER
{tier}
{/* Daily Challenge Banner */} {dailyChallengeActive && (
DAILY CHALLENGE ACTIVE
Solve as many as you can! Ends at {dailyChallengeTime}
)} {/* Trivia Question */} {showTrivia && (
Math Trivia
{triviaQuestion}
)}
{/* Problem Display */}
{currentProblem ? formatProblem(currentProblem) : "Loading..."}
setUserAnswer(e.target.value)} className="w-full p-4 text-2xl text-center bg-gray-800 border-2 border-gray-700 rounded-lg focus:border-blue-500 focus:outline-none" placeholder="Enter answer" disabled={!isActive} /> {feedback && ( {feedback.message} )}
{/* Power-ups */}
{powerUps.map((powerUp) => ( ))}
{/* Active Power-up Indicator */} {activePowerUp && (
{activePowerUp.name} Active!
)}
{/* Keypad */}
{[1, 2, 3, 4, 5, 6, 7, 8, 9, "-", 0, "."].map((key) => ( ))}
{/* Action Buttons */}
{/* Story Unlock */} {storyUnlocked && (
Story Unlocked!
You've helped the Math Hero progress in their journey!
)}
); }; // Render game over screen const renderGameOverScreen = () => { return (
{gameMode === "pvp" ? "Battle Results" : "Game Over!"}
{playerStats.score}
Score
{playerStats.maxStreak}
Max Streak
{playerStats.problemsCorrect}
Correct
{playerStats.accuracy}%
Accuracy
{/* AI Tutor Feedback */}

AI Tutor Feedback

{playerStats.accuracy < 70 ? "You're doing great! Focus on the operations you find challenging." : playerStats.maxStreak > 10 ? "High streaks! Try increasing the difficulty for more challenge." : "Good performance! Keep practicing to improve your speed."}

{/* Fatigue Meter */} {fatigueData.length > 0 && (

Brain Fatigue Meter

{fatigueData.map((value, index) => (
))}

{fatigueData[fatigueData.length - 1] < 80 ? "Consider taking a break to maintain peak performance." : "You're maintaining strong focus!"}

)} {/* Action Buttons */}
); }; // Render main menu const renderMainMenu = () => { return (
NumBlitz: Math Mastery Arena

Sharpen your math skills with lightning-fast challenges

{/* Stats Preview */}
Current Tier
{tier}
Story Progress
{storyProgress}/20
); }; return (
{gameOver ? ( {renderGameOverScreen()} ) : gameMode ? ( {renderGameScreen()} ) : ( {renderMainMenu()} )} {/* Footer */}
NumBlitz: Math Mastery Arena • Sharpen your mind, one equation at a time
); }