```react import React, { useState, useEffect, useCallback, useRef } from 'react'; import { X, Play, Trophy, ChevronRight, RotateCcw, MonitorPlay, Eye, Volume2 } from 'lucide-react'; // --- MOTOR DE AUDIO AVANZADO (Estilo TV) --- const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); const playDing = () => { if (audioCtx.state === 'suspended') audioCtx.resume(); const osc = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); osc.type = 'sine'; osc.frequency.setValueAtTime(880, audioCtx.currentTime); // Nota A5 (Campana) osc.frequency.exponentialRampToValueAtTime(440, audioCtx.currentTime + 0.5); gainNode.gain.setValueAtTime(0.5, audioCtx.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 1); osc.connect(gainNode); gainNode.connect(audioCtx.destination); osc.start(); osc.stop(audioCtx.currentTime + 1); }; const playBuzz = () => { if (audioCtx.state === 'suspended') audioCtx.resume(); const osc1 = audioCtx.createOscillator(); const osc2 = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); osc1.type = 'sawtooth'; osc2.type = 'square'; osc1.frequency.setValueAtTime(150, audioCtx.currentTime); osc2.frequency.setValueAtTime(155, audioCtx.currentTime); gainNode.gain.setValueAtTime(0.4, audioCtx.currentTime); gainNode.gain.setValueAtTime(0.4, audioCtx.currentTime + 0.5); gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.8); osc1.connect(gainNode); osc2.connect(gainNode); gainNode.connect(audioCtx.destination); osc1.start(); osc2.start(); osc1.stop(audioCtx.currentTime + 0.8); osc2.stop(audioCtx.currentTime + 0.8); }; // --- FUNCIONES DE AYUDA --- const normalizeString = (str) => { return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").trim(); }; // --- DATOS DEL JUEGO --- const QUESTIONS = [ { question: "Menciona algo que la gente pierde a menudo.", answers: [ { text: "LAS LLAVES", points: 42, match: ["llaves", "llave"] }, { text: "EL CELULAR", points: 25, match: ["celular", "telefono", "movil", "cel"] }, { text: "LA CARTERA", points: 15, match: ["cartera", "billetera", "dinero", "monedero"] }, { text: "EL CONTROL REMOTO", points: 10, match: ["control", "control remoto", "tele"] }, { text: "LA PACIENCIA", points: 5, match: ["paciencia", "cabeza", "calma"] }, { text: "LOS LENTES", points: 3, match: ["lentes", "gafas", "anteojos"] } ] }, { question: "¿Qué le pones a los tacos?", answers: [ { text: "SALSA", points: 45, match: ["salsa", "salsas", "picante"] }, { text: "LIMÓN", points: 28, match: ["limon", "limones"] }, { text: "CILANTRO Y CEBOLLA", points: 15, match: ["cilantro", "cebolla", "verdura"] }, { text: "GUACAMOLE", points: 8, match: ["guacamole", "aguacate"] }, { text: "SAL", points: 4, match: ["sal"] } ] }, { question: "Una excusa para no ir a trabajar.", answers: [ { text: "ESTOY ENFERMO", points: 40, match: ["enfermo", "salud", "me siento mal", "gripe"] }, { text: "FALLECIMIENTO", points: 20, match: ["murio", "fallecimiento", "velorio", "familiar"] }, { text: "TRÁFICO / CHOQUE", points: 15, match: ["trafico", "choque", "accidente", "carro"] }, { text: "PROBLEMA EN CASA", points: 12, match: ["fuga", "tuberia", "casa", "gas"] }, { text: "NO SONÓ LA ALARMA", points: 8, match: ["alarma", "dormido"] }, { text: "TEMA DE HIJOS", points: 5, match: ["hijo", "hijos", "escuela"] } ] }, { question: "Menciona algo que haces cuando no puedes dormir.", answers: [ { text: "VER EL CELULAR", points: 35, match: ["celular", "redes sociales", "telefono", "facebook", "tiktok"] }, { text: "VER LA TELE", points: 28, match: ["tele", "television", "series", "netflix"] }, { text: "LEER", points: 18, match: ["leer", "libro", "lectura"] }, { text: "TOMAR AGUA / LECHE", points: 10, match: ["agua", "leche", "tomar", "beber"] }, { text: "DAR VUELTAS", points: 6, match: ["vueltas", "dar vueltas", "pensar"] }, { text: "CONTAR OVEJAS", points: 3, match: ["ovejas", "contar"] } ] } ]; export default function App() { const [gameState, setGameState] = useState('setup'); const [teams, setTeams] = useState({ team1: { name: 'Familia 1', score: 0 }, team2: { name: 'Familia 2', score: 0 } }); const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0); const [revealedAnswers, setRevealedAnswers] = useState([]); const [roundPoints, setRoundPoints] = useState(0); const [strikes, setStrikes] = useState(0); const [guess, setGuess] = useState(""); const [showStrikeGraphic, setShowStrikeGraphic] = useState(0); const currentQuestion = QUESTIONS[currentQuestionIndex]; const inputRef = useRef(null); const initAudio = () => { if (audioCtx.state === 'suspended') { audioCtx.resume(); } }; const handleStartGame = (e) => { e.preventDefault(); initAudio(); const t1Name = e.target.team1.value || 'Familia 1'; const t2Name = e.target.team2.value || 'Familia 2'; setTeams({ team1: { name: t1Name.toUpperCase(), score: 0 }, team2: { name: t2Name.toUpperCase(), score: 0 } }); setGameState('playing'); resetRound(); }; const resetRound = () => { setRevealedAnswers([]); setRoundPoints(0); setStrikes(0); setGuess(""); setShowStrikeGraphic(0); if(inputRef.current) inputRef.current.focus(); }; const handleRevealAnswer = (index, isManualReveal = false) => { if (!revealedAnswers.includes(index)) { playDing(); const newRevealed = [...revealedAnswers, index]; setRevealedAnswers(newRevealed); if (!isManualReveal) { setRoundPoints(prev => prev + currentQuestion.answers[index].points); } } }; const triggerStrikeGraphic = (currentStrikeCount) => { setShowStrikeGraphic(currentStrikeCount); setTimeout(() => { setShowStrikeGraphic(0); if(inputRef.current) inputRef.current.focus(); }, 2000); }; const handleStrike = () => { playBuzz(); setGuess(""); const newStrikes = strikes + 1; if (newStrikes <= 3) { setStrikes(newStrikes); triggerStrikeGraphic(newStrikes); } else { triggerStrikeGraphic(3); } }; const handleGuessSubmit = (e) => { e.preventDefault(); if (!guess.trim()) return; const normalizedGuess = normalizeString(guess); let foundIndex = -1; for (let i = 0; i < currentQuestion.answers.length; i++) { const ans = currentQuestion.answers[i]; if (ans.match.includes(normalizedGuess) || normalizeString(ans.text) === normalizedGuess || (normalizedGuess.length >= 4 && normalizeString(ans.text).includes(normalizedGuess))) { foundIndex = i; break; } } if (foundIndex !== -1) { if (!revealedAnswers.includes(foundIndex)) { handleRevealAnswer(foundIndex); } } else { handleStrike(); } setGuess(""); }; const awardPointsToTeam = (teamKey) => { setTeams(prev => ({ ...prev, [teamKey]: { ...prev[teamKey], score: prev[teamKey].score + roundPoints } })); setRoundPoints(0); }; const handleNextQuestion = () => { if (currentQuestionIndex < QUESTIONS.length - 1) { setCurrentQuestionIndex(prev => prev + 1); resetRound(); } else { setGameState('winner'); } }; const handleRestart = () => { setGameState('setup'); setCurrentQuestionIndex(0); resetRound(); }; // --- RENDERIZADO DE PANTALLAS --- const renderSetup = () => (

100 Mexicanos
Dijeron

VERSIÓN DE TELEVISIÓN

); const renderGame = () => { // Preparar el tablero para siempre tener 8 casillas const boardAnswers = [...currentQuestion.answers]; while (boardAnswers.length < 8) { boardAnswers.push(null); } return (
{/* --- HEADER / SCOREBOARD --- */}
{/* TEAM 1 */}

{teams.team1.name}

{teams.team1.score}
{/* BANK / CENTER */}
{roundPoints}
{/* TEAM 2 */}

{teams.team2.name}

{teams.team2.score}
{/* --- MAIN STAGE (PREGUNTA + TABLERO) --- */}
{/* BANNER DE LA PREGUNTA */}

{currentQuestion.question}

{/* EL TABLERO CLÁSICO */}
{/* Línea divisoria central estética */}
{boardAnswers.map((answer, index) => { const isRevealed = revealedAnswers.includes(index); // Si la casilla no tiene respuesta (es de relleno) if (!answer) { return (
); } // Casillas reales return (
{/* FRENTE (Oculto) */}
{index + 1}
{/* RESPALDO (Revelado) */}
{answer.text}
{answer.points}
); })}
{/* --- GRÁFICO DE STRIKES (CRUCES GIGANTES) --- */} {showStrikeGraphic > 0 && (
{Array.from({ length: showStrikeGraphic }).map((_, i) => (
))}
)} {/* --- PANEL DE PRESENTADOR (Abajo) --- */}
); }; const renderWinner = () => { const winner = teams.team1.score > teams.team2.score ? teams.team1 : teams.team2.score > teams.team1.score ? teams.team2 : { name: '¡EMPATE!', score: teams.team1.score }; return (

Familia Ganadora

{winner.name}

{winner.score} PTS
); }; if (gameState === 'setup') return renderSetup(); if (gameState === 'playing') return renderGame(); if (gameState === 'winner') return renderWinner(); } ```