const SUBJECTS=[ {id:"lengua",name:"Lengua y Literatura",games:[ {id:"predicado",glyph:"PN",name:"Predicado nominal o verbal",area:"La oración simple",t:1}, {id:"complementos",glyph:"CD",name:"Complementos del verbo",area:"CD, CI, CC y atributo",t:2}, {id:"ortografia",glyph:"h",name:"Ortografía h, ll/y, x",area:"¿Cómo se escribe?",t:2}, {id:"rima",glyph:"♪",name:"Rima consonante o asonante",area:"Métrica",t:3}]}, {id:"mates",name:"Matemáticas",games:[ {id:"potencias",glyph:"aⁿ",name:"Propiedades de las potencias",area:"Producto, cociente y potencia",t:1}, {id:"proporcion",glyph:"∝",name:"Proporcionalidad directa e inversa",area:"Regla de tres",t:1}, {id:"algebra",glyph:"3x",name:"Expresiones algebraicas",area:"Valor numérico y monomios",t:2}, {id:"ecuaciones2",glyph:"x²",name:"Ecuaciones de segundo grado",area:"Soluciones enteras",t:2}, {id:"sistemas",glyph:"{ }",name:"Sistemas de ecuaciones",area:"Dos incógnitas",t:2}, {id:"volumen",glyph:"cm³",name:"Volumen de cuerpos",area:"Prismas, cubos y pirámides",t:3}, {id:"probabilidad",glyph:"P",name:"Probabilidad",area:"Regla de Laplace",t:3}]}, {id:"naturales",name:"Física y Química",games:[ {id:"magnitudes",glyph:"SI",name:"Magnitudes y unidades",area:"Sistema Internacional",t:1}, {id:"cambios",glyph:"⚗",name:"Cambio físico o químico",area:"La materia y sus cambios",t:2}]}, {id:"sociales",name:"Geografía e Historia",games:[ {id:"siglos",glyph:"XV",name:"¿En qué siglo?",area:"Cronología",t:1}, {id:"arte",glyph:"⛪",name:"¿Románico o gótico?",area:"Arte medieval",t:2}]}, {id:"english",name:"English",games:[ {id:"grammar",glyph:"B1",name:"Grammar practice",area:"A2-B1 level",t:0}]} ]; const HELP={predicado:"¿El verbo es copulativo (ser, estar, parecer) con atributo?",complementos:"¿Qué función cumple el grupo marcado?",ortografia:"Toca la palabra bien escrita.",rima:"Compara los sonidos desde la última vocal tónica.", potencias:"Aplica las propiedades de las potencias.",proporcion:"¿Es directa o inversa?",algebra:"Sustituye o agrupa términos semejantes.",ecuaciones2:"Busca dos números que sumen y multipliquen lo que indica la ecuación.", sistemas:"Resuelve por reducción o sustitución.",volumen:"Área de la base × altura (÷ 3 en la pirámide).",probabilidad:"Casos favorables entre casos posibles.",magnitudes:"¿Cuál es su unidad en el SI?", cambios:"¿Se forman sustancias nuevas?",siglos:"Los años 1 a 100 son el siglo I.",arte:"Fíjate en arcos, bóvedas, muros y luz.",grammar:"Choose the correct option."}; const PRED=[["Mi hermano es médico.","nominal"],["La sopa está fría.","nominal"],["Los niños parecen cansados.","nominal"],["Esta película es muy divertida.","nominal"],["El examen fue fácil.","nominal"],["Pedro está enfermo.","nominal"],["La casa parece antigua.","nominal"], ["Marta lee una novela.","verbal"],["El tren llegó tarde.","verbal"],["Mis padres están en casa.","verbal"],["Lucía escribió una carta.","verbal"],["Ellos fueron al cine.","verbal"],["Mis abuelos viven en Cuenca.","verbal"],["El partido es a las cinco.","verbal"]]; const PREDWHY={"Mis padres están en casa.":"«Estar» + lugar no lleva atributo: es predicado verbal.","Ellos fueron al cine.":"«Fueron» es del verbo «ir», no de «ser».","El partido es a las cinco.":"«Ser» significa aquí «tener lugar»: no hay atributo."}; const FUNCS=["complemento directo","complemento indirecto","complemento circunstancial","atributo"]; const COMPL=[["Lucía compró *un libro*.","complemento directo"],["*La* vi ayer en el parque.","complemento directo"],["Pedro lee *el periódico* cada mañana.","complemento directo"],["Saludé *a Laura*.","complemento directo"], ["Envié una postal *a mis abuelos*.","complemento indirecto"],["*Le* conté un secreto.","complemento indirecto"],["Regaló flores *a su abuela*.","complemento indirecto"], ["Estudiamos *por la tarde*.","complemento circunstancial"],["Corre *muy deprisa*.","complemento circunstancial"],["Comimos paella *con los primos*.","complemento circunstancial"], ["Mi tía es *profesora*.","atributo"],["El cielo está *nublado*.","atributo"],["Mis vecinos parecen *simpáticos*.","atributo"]]; const COMPLWHY={"Saludé *a Laura*.":"Con persona, el CD lleva «a». Prueba: «La saludé».","*La* vi ayer en el parque.":"«La» es pronombre de CD.","*Le* conté un secreto.":"«Le» es pronombre de CI."}; const ORTO=[["hierba","ierba"],["ahorro","aorro"],["deshacer","desacer"],["hueco","ueco"],["ahogar","aogar"],["huésped","uésped"], ["llover","yover"],["ayer","aller"],["desayuno","desalluno"],["caballo","cabayo"],["llave","yave"],["playa","plalla"],["yema","llema"], ["examen","esamen"],["extranjero","estranjero"],["exacto","esacto"],["texto","testo"],["explicar","esplicar"]]; const RIMAS=[["canción","corazón","consonante"],["flores","colores","consonante"],["luna","cuna","consonante"],["cielo","suelo","consonante"],["noche","coche","consonante"],["luz","cruz","consonante"],["sueño","pequeño","consonante"], ["casa","mañana","asonante"],["rosa","hoja","asonante"],["playa","casa","asonante"],["viento","tiempo","asonante"],["amigo","libro","asonante"],["tarde","calle","asonante"],["verde","siempre","asonante"]]; const UNITS=["metro (m)","kilogramo (kg)","segundo (s)","kelvin (K)","amperio (A)","mol (mol)","metro por segundo (m/s)","newton (N)","julio (J)","pascal (Pa)","metro cúbico (m³)","candela (cd)"]; const MAGS=[["Longitud","metro (m)"],["Masa","kilogramo (kg)"],["Tiempo","segundo (s)"],["Temperatura","kelvin (K)"],["Intensidad de corriente","amperio (A)"],["Cantidad de sustancia","mol (mol)"],["Intensidad luminosa","candela (cd)"], ["Velocidad","metro por segundo (m/s)"],["Fuerza","newton (N)"],["Energía","julio (J)"],["Presión","pascal (Pa)"],["Volumen","metro cúbico (m³)"]]; const CAMBIOS=[["Se funde un cubito de hielo.","físico"],["Se quema un papel.","químico"],["Un clavo se oxida.","químico"],["Disolvemos azúcar en agua.","físico"],["Cocinamos un huevo.","químico"],["Se rompe un vaso.","físico"], ["La leche se convierte en yogur.","químico"],["El agua de un charco se evapora.","físico"],["Una manzana cortada se pone marrón.","químico"],["Doblamos una lata.","físico"],["La madera arde en la chimenea.","químico"],["Mezclamos arena y sal.","físico"]]; const ARTE=[["Arco de medio punto","románico"],["Arco apuntado","gótico"],["Grandes vidrieras de colores","gótico"],["Muros gruesos y ventanas pequeñas","románico"],["Bóveda de crucería","gótico"],["Bóveda de cañón","románico"], ["Arbotantes y contrafuertes exteriores","gótico"],["Interiores oscuros y recogidos","románico"],["La catedral de León","gótico"],["Pinturas murales de figuras rígidas (Taüll)","románico"],["Rosetones","gótico"],["Iglesias de pequeño tamaño en el Camino de Santiago","románico"]]; const GRAMMAR=[["If it rains tomorrow, we ___ stay at home.","will",["would","are"]],["The Mona Lisa ___ painted by Leonardo da Vinci.","was",["is","has"]],["This is the girl ___ won the competition.","who",["which","whose"]], ["I ___ never been to Ireland.","have",["has","am"]],["I ___ him yesterday at the station.","saw",["have seen","see"]],["Look at those clouds! It ___ rain.","is going to",["will to","goes to"]], ["She's been studying English ___ three years.","for",["since","during"]],["You ___ smoke here. It's forbidden.","mustn't",["don't have to","needn't"]],["If I ___ rich, I would travel around the world.","were",["am","will be"]], ["The book ___ I bought is very interesting.","that",["who","what"]],["They ___ dinner when I arrived.","were having",["had","have had"]],["English ___ in many countries.","is spoken",["speaks","is speaking"]]]; const $=s=>document.querySelector(s); const board=$("#board"); const rand=(a,b)=>a+Math.floor(Math.random()*(b-a+1)); const pick=a=>a[rand(0,a.length-1)]; const shuffle=a=>{a=[...a];for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]]}return a}; const esc=s=>String(s).replace(/[&<>"]/g,c=>({"&":"&","<":"<",">":">",'"':"""}[c])); const fmt=n=>{const r=Math.round(n*1000)/1000;let [i,d]=String(r).split(".");if(i.length>4)i=i.replace(/\B(?=(\d{3})+(?!\d))/g,".");return d?i+","+d:i}; const ALL=SUBJECTS.flatMap(s=>s.games.map(g=>({...g,subject:s}))); const TRIM=["Todo el curso","1.er trimestre","2.º trimestre","3.er trimestre"]; let current="predicado", soundOn=true, actx=null, trim=0; function tone(ok){ if(!soundOn) return; try{ actx=actx||new (window.AudioContext||window.webkitAudioContext)(); (ok?[660,880]:[220]).forEach((f,i)=>{const o=actx.createOscillator(),g=actx.createGain();o.type="sine";o.frequency.value=f; const t=actx.currentTime+i*.11;g.gain.setValueAtTime(.0001,t);g.gain.exponentialRampToValueAtTime(.16,t+.02);g.gain.exponentialRampToValueAtTime(.0001,t+.25); o.connect(g).connect(actx.destination);o.start(t);o.stop(t+.27)}); }catch(e){} } function shake(el){el.classList.remove("shake");void el.offsetWidth;el.classList.add("shake")} function renderNav(){ $("#trims").innerHTML=TRIM.map((t,k)=>``).join(""); document.querySelectorAll("#trims button").forEach(b=>b.onclick=()=>{trim=+b.dataset.t;renderNav()}); $("#games").innerHTML=SUBJECTS.map(s=>{const gs=s.games.filter(g=>!trim||g.t===0||g.t===trim).sort((a,b)=>a.t-b.t); return `
Nada este trimestre
`}${esc(s).replace("___",' ? ')}
`,answer:ok,opts:shuffle([ok,...bad]),txt:true, after:()=>`${esc(s).replace("___",`${esc(ok)}`)}
`}} function pickOpts(ok,all,n=3){return shuffle([ok,...shuffle(all.filter(x=>x!==ok)).slice(0,n-1)])} function rightTri(a,b,c,ask){ const lab=(v,k)=>k===ask?"?":`${v} cm`; return ``; } /* ---------- Preguntas ---------- */ function makeQ(id,used){ if(id==="predicado"){const [s,t]=listQ(PRED,used);return {scene:`${esc(s)}
`,answer:"predicado "+t,opts:["predicado nominal","predicado verbal"],txt:true, why:PREDWHY[s]||(t==="nominal"?"Verbo copulativo + atributo.":"El núcleo es un verbo predicativo.")};} if(id==="complementos"){const [s,f]=listQ(COMPL,used);return {scene:`${sentenceHtml(s)}
`,answer:f,opts:pickOpts(f,FUNCS),txt:true,why:COMPLWHY[s]||""};} if(id==="ortografia"){const [ok,bad]=listQ(ORTO,used);return {scene:`¿Cuál está bien escrita?
`,answer:ok,opts:shuffle([ok,bad]),txt:true};} if(id==="rima"){const [a,b,t]=listQ(RIMAS,used);return {scene:`${esc(a)} · ${esc(b)}
`,answer:"rima "+t,opts:["rima consonante","rima asonante"],txt:true, why:t==="consonante"?"Coinciden vocales y consonantes desde la última vocal tónica.":"Solo coinciden las vocales desde la última vocal tónica."};} if(id==="potencias"){ const b=rand(2,9),m=rand(2,7),n=rand(3,6),k=rand(0,2); if(k===0) return {scene:`${b}${m} · ${b}${n} = ?
`,answer:b+sup(m+n),opts:shuffle([b+sup(m+n),b+sup(m*n),(b*b)+sup(m+n)]),why:"Misma base: se suman los exponentes."}; if(k===1){const M=m+n;return {scene:`${b}${M} : ${b}${n} = ?
`,answer:b+sup(m),opts:shuffle([b+sup(m),b+sup(M+n),b+sup(M*n)]),why:"Misma base: se restan los exponentes."};} return {scene:`(${b}${m})${n} = ?
`,answer:b+sup(m*n),opts:shuffle([b+sup(m*n),b+sup(m+n),(b*n)+sup(m)]),why:"Potencia de una potencia: se multiplican los exponentes."}; } if(id==="proporcion"){ if(Math.random()<.5){const w=pick([2,3,4,6]),d=pick([6,8,12,24]),w2=pick([2,3,4,6,8,12].filter(x=>x!==w&&(w*d)%x===0)),r=w*d/w2; return {scene:`${w} pintores tardan ${d} días en pintar un colegio. ¿Cuántos días tardarán ${w2} pintores?
`,answer:fmt(r)+" días",opts:numOpts(r,[Number.isInteger(d*w2/w)?d*w2/w:d*2,d+w2-w]," días"),txt:true, why:`Proporcionalidad inversa: ${w} × ${d} = ${w*d}; ${w*d} : ${w2} = ${fmt(r)}.`};} const L=pick([5,8,10]),km=L*pick([12,15,16,18,20]),L2=pick([15,20,25,30,40]),r=km/L*L2; return {scene:`Un coche recorre ${km} km con ${L} L de gasolina. ¿Cuántos km recorrerá con ${L2} L?
`,answer:fmt(r)+" km",opts:numOpts(r,[km*L/L2,km+L2]," km"),txt:true, why:`Proporcionalidad directa: ${km} : ${L} = ${km/L} km por litro; × ${L2} = ${fmt(r)}.`}; } if(id==="algebra"){ if(Math.random()<.5){const a=rand(2,5),b=rand(1,6),c=rand(1,9),x=pick([-3,-2,-1,2,3]),r=a*x*x-b*x+c; return {scene:`Si x = ${fmtI(x)}
${a}x² − ${b}x + ${c} = ?
`,answer:fmtI(r),opts:intOpts(r,[a*x*x+b*x+c,-a*x*x-b*x+c]),why:`${a}·${par(x)}² − ${b}·${par(x)} + ${c} = ${fmtI(r)}.`};} const a=rand(2,9),b=rand(2,9),c=rand(1,a+b-1),r=a+b-c; return {scene:`${a}x + ${b}x − ${c}x = ?
`,answer:r+"x",opts:shuffle([...new Set([r+"x",(a+b+c)+"x",r+"x³"])]),why:"Se suman los coeficientes de los términos semejantes."}; } if(id==="ecuaciones2"){ let r1=rand(-6,6),r2=rand(-6,6);while(r1===r2||!r1||!r2){r1=rand(-6,6);r2=rand(-6,6)} const S=r1+r2,P=r1*r2,lo=Math.min(r1,r2),hi=Math.max(r1,r2); const term=(c,t)=>c===0?"":` ${c<0?"−":"+"} ${Math.abs(c)===1&&t?"":Math.abs(c)}${t}`; const eq=`x²${term(-S,"x")}${term(P,"")} = 0`; const f=(a,b)=>`x = ${fmtI(Math.min(a,b))}, x = ${fmtI(Math.max(a,b))}`; return {scene:`${eq}
`,answer:f(lo,hi),opts:shuffle([...new Set([f(lo,hi),f(-lo,-hi),f(lo,-hi)])]),txt:true, why:`Dos números que suman ${fmtI(S)} y multiplicados dan ${fmtI(P)}: ${fmtI(lo)} y ${fmtI(hi)}.`}; } if(id==="sistemas"){ let x=rand(-5,8),y=rand(-5,8);while(x===y||!x||!y){x=rand(-5,8);y=rand(-5,8)}const a=rand(1,3),S=a*x+y,D=x-y; const f=(p,q)=>`x = ${fmtI(p)}, y = ${fmtI(q)}`; const opts=[...new Set([f(x,y),f(y,x),f(-x,y),f(x,-y)])].slice(0,3); return {scene:`${a===1?"":a}x + y = ${fmtI(S)}
x − y = ${fmtI(D)}
Cubo de arista ${l} cm
`,answer:fmt(r)+" cm³",opts:shuffle([...new Set([fmt(r)+" cm³",fmt(6*l*l)+" cm³",fmt(3*l)+" cm³"])]),txt:true,why:`V = ${l}³ = ${fmt(r)} cm³.`};} if(k===1){const a=rand(2,9),b=rand(2,9),h=rand(2,12),r=a*b*h;return {scene:`Prisma rectangular de ${a} cm × ${b} cm × ${h} cm
`,answer:fmt(r)+" cm³",opts:shuffle([...new Set([fmt(r)+" cm³",fmt(2*(a*b+a*h+b*h))+" cm³",fmt(a+b+h)+" cm³"])]),txt:true,why:`V = ${a} · ${b} · ${h} = ${fmt(r)} cm³.`};} const l=pick([3,6,9]),h=pick([4,5,8,10]),r=l*l*h/3; return {scene:`Pirámide de base cuadrada (lado ${l} cm) y altura ${h} cm
`,answer:fmt(r)+" cm³",opts:shuffle([...new Set([fmt(r)+" cm³",fmt(l*l*h)+" cm³",fmt(l*l*h/2)+" cm³"])]),txt:true,why:`V = (${l}² · ${h}) : 3 = ${fmt(r)} cm³.`}; } if(id==="probabilidad"){ const R=rand(1,6),A=rand(1,6),V=rand(1,6),T=R+A+V,col=pick([["roja",R],["azul",A],["verde",V]]); const ok=fr(col[1],T); const s=new Set([ok]); [fr(T-col[1],T),fr(col[1],T-col[1]||1),fr(col[1]+1,T)].forEach(x=>{if(s.size<3&&x!==ok&&!["0","1"].includes(x))s.add(x)});let kk=1;while(s.size<3){const x=fr(col[1],T+kk);if(x!==ok)s.add(x);kk++} return {scene:`En una bolsa hay ${R} bolas rojas, ${A} azules y ${V} verdes. Sacamos una al azar. ¿Qué probabilidad hay de que sea ${col[0]}?
`, answer:ok,opts:shuffle([...s]),render:true,why:`Casos favorables (${col[1]}) entre casos posibles (${T}).`}; } if(id==="magnitudes"){const [m,u]=listQ(MAGS,used);return {scene:`${esc(m)}
`,answer:u,opts:pickOpts(u,UNITS),txt:true};} if(id==="cambios"){const [c,t]=listQ(CAMBIOS,used);return {scene:`${esc(c)}
`,answer:"cambio "+t,opts:["cambio físico","cambio químico"],txt:true, why:t==="químico"?"Se forman sustancias nuevas.":"La sustancia sigue siendo la misma."};} if(id==="siglos"){ const y=pick([rand(1,2026),pick([711,1492,1500,1605,1808,1900,1936,1978,2000,1200,476,1066])]); const c=Math.ceil(y/100),s=new Set([c]);[Math.floor(y/100),c+1].forEach(v=>{if(s.size<3&&v>0)s.add(v)});if(s.size<3)s.add(c+2); return {scene:`Año ${y}
`,answer:"siglo "+toRoman(c),opts:shuffle([...s].map(v=>"siglo "+toRoman(v))),txt:true, why:y%100===0?`El año ${y} es el último del siglo ${toRoman(c)}.`:`Del ${(c-1)*100+1} al ${c*100}: siglo ${toRoman(c)}.`}; } if(id==="arte"){const [e,s]=listQ(ARTE,used);return {scene:`${esc(e)}
`,answer:s,opts:["románico","gótico"],txt:true};} const [s,ok,bad]=listQ(GRAMMAR,used); return blankQ(s,ok,bad); } /* ---------- Motor ---------- */ function play(g){ const lect=g.id==="lectura", R=lect?6:8; const queue=lect?shuffle(LECTURAS).slice(0,3).flatMap(l=>[{l,qi:0},{l,qi:1}]):[]; let i=0, score=0; const used=new Set(); const head=(extra="")=>`${HELP[g.id]}
${msg}