/* quiz.js — Quiz-Builder, Review-Screen, Feedback-Bogen */ /* ══════════════════════════════════════════════ STEP 4 — QUIZ ══════════════════════════════════════════════ */ function isQComplete(q){return q.question.trim()&&q.answers.every(a=>a.trim())&&q.correct!==null;} function getQ(fi){return ST.quizData.find(q=>q.fieldIndex===fi);} function buildQuiz(){ const qidx=ST.fields.map((f,i)=>f==='quiz'?i:-1).filter(i=>i>=0); qidx.forEach(fi=>{if(!ST.quizData.find(q=>q.fieldIndex===fi))ST.quizData.push({fieldIndex:fi,question:'',answers:['','','',''],correct:null});}); ST.quizData=ST.quizData.filter(q=>qidx.includes(q.fieldIndex)); const area=document.getElementById('quizArea');area.innerHTML=''; if(qidx.length===0){ area.innerHTML=`

Keine Quiz-Felder platziert

In Schritt 3 hast du keine Quiz-Felder hinzugefügt.
Du kannst trotzdem weitermachen!

`; document.getElementById('s4next').disabled=false;return; } const done=ST.quizData.filter(isQComplete).length; const ov=document.createElement('div');ov.className='ov-bar'; ov.innerHTML=`
✅ Fertig: ${done}/${qidx.length}
❓ Quiz-Felder: ${qidx.length}
`; area.appendChild(ov); const af=document.createElement('div');af.className='af-bar'; af.innerHTML=`
Beispielfragen
Alle leeren Felder automatisch ausfüllen
`; area.appendChild(af); ST.quizData.forEach((q,i)=>area.appendChild(mkQCard(q,i))); updQNext(); } function updQNext(){ const qidx=ST.fields.map((f,i)=>f==='quiz'?i:-1).filter(i=>i>=0); document.getElementById('s4next').disabled=qidx.length>0&&ST.quizData.filter(isQComplete).length${done}/${qidx.length}`;} } function mkQCard(q,idx){ // XSS-sicher: fieldIndex wird zu Integer geclampt, Frage/Antworten via esc() (entschärft <,>,&,",') const comp=isQComplete(q); const fi = parseInt(q.fieldIndex)|0; // hart casten const c=document.createElement('div');c.className='card quiz-card'+(comp?' complete':'');c.id='qc_'+fi; const fl=fi===0?'Start':fi===ST.fieldCount-1?'Ziel':'Feld '+fi; const ans = LETTERS.map((L,i)=>{ const v = esc(q.answers[i]||''); return `
${L}
`; }).join(''); const corr = LETTERS.map((L,i)=>``).join(''); c.innerHTML=`
${idx+1}
Quiz-Frage ${idx+1}
${comp?'✓ Fertig':'⏳ Ausfüllen'}
${ans}
✅ Richtige Antwort:
${corr}
• Stelle eine klare, eindeutige Frage
• Alle 4 Antworten sollten plausibel klingen
• Nur eine Antwort ist korrekt
• Beziehe die Frage auf dein Spielthema!
`; return c; } function updQ(fi,field,val){ const q=getQ(fi);if(!q)return; if(field==='q')q.question=val; else q.answers[parseInt(field.slice(1))]=val; refQCard(fi);updQNext(); } function setCorr(fi,idx){ const q=getQ(fi);if(!q)return;q.correct=idx; LETTERS.forEach((_,i)=>{const w=document.getElementById(`aw_${fi}_${i}`);if(w)w.className='ans-wrap '+(i===idx?'correct':'');}); const card=document.getElementById('qc_'+fi);if(card)card.querySelectorAll('.correct-btn').forEach((b,i)=>b.classList.toggle('selected',i===idx)); refQCard(fi);updQNext(); } function refQCard(fi){ const q=getQ(fi);if(!q)return; const comp=isQComplete(q); const c=document.getElementById('qc_'+fi);if(!c)return; c.classList.toggle('complete',comp); const st=document.getElementById('qst_'+fi);if(st){st.className='qc-status '+(comp?'done':'todo');st.textContent=comp?'✓ Fertig':'⏳ Ausfüllen';} const num=document.getElementById('qnum_'+fi);if(num)num.style.background=comp?'linear-gradient(135deg,#10b981,#059669)':'linear-gradient(135deg,#7c3aed,#f5a623)'; } function autoFill(){ ST.quizData.forEach((q,i)=>{if(!isQComplete(q)){const ex=QUIZ_EX[i%QUIZ_EX.length];q.question=ex.q;q.answers=[...ex.a];q.correct=ex.c;}}); buildQuiz();showToast('✅ Beispielfragen eingefügt!'); } /* ══════════════════════════════════════════════ STEP 5 — REVIEW + TEST ══════════════════════════════════════════════ */ function buildReview(){ const fig=FIGURES.find(f=>f.id===ST.figure)||{e:'🎮',n:'Figur'}; const bg=BACKGROUNDS.find(b=>b.id===ST.background)||{scene:'🌍',n:'Welt'}; const area=document.getElementById('reviewArea');area.innerHTML=''; // Hero card const hero=document.createElement('div');hero.className='hero-card'; hero.innerHTML=`
${esc(bg.scene)}${esc(fig.e)}
${esc(ST.name||'Mein Spiel')}
${esc(ST.desc||'Keine Beschreibung.')}
${esc(fig.e)} ${esc(fig.n)}
🌍 ${esc(bg.n)}
⬛ ${esc(String(ST.fieldCount))} Felder
`; area.appendChild(hero); // Rules const rules=document.createElement('div');rules.className='card'; const filled=ST.fields.slice(1,ST.fieldCount-1).filter(Boolean).length; rules.innerHTML=`
⚙️ Spielregeln
🎲 Bewegung
${ST.rules.movement==='dice'?'🎲 Würfeln':'👣 Ein Feld'}
${ST.rules.fail==='lives'?'❤️ Leben':'⭐ Punkte'}
${ST.rules.fail==='lives'?ST.rules.lives+' Leben':'+'+ST.rules.pts+' Pts'}
🕹️ Mini-Games
${filled} Felder
📖 Erzähltexte
${ST.storyItems.length}
`; area.appendChild(rules); // Timeline const tlCard=document.createElement('div');tlCard.className='card'; tlCard.innerHTML='
🗺️ Spielablauf
'; const tl=document.createElement('div');tl.className='tl'; for(let i=0;im.id===g):null; const isSt=i===0,isEn=i===ST.fieldCount-1; ST.storyItems.filter(s=>s.position==='before'&&s.fieldIndex===i).forEach(s=>{ const it=document.createElement('div');it.className='tl-item story-it'; it.innerHTML=`
${esc(s.emoji||'📖')}
Erzähl-Text
${esc(s.text||'(noch leer)')}
Vor Feld ${i}
`; tl.appendChild(it); }); const it=document.createElement('div');it.className='tl-item'; let dCls,lCls,lbl,sub,badge=''; if(isSt){dCls='s';lCls='s';lbl='🟢 Start';sub='Das Abenteuer beginnt!';} else if(isEn){dCls='e';lCls='e';lbl='🏁 Ziel';sub='Hier gewinnt man!';} else if(mg){dCls='g';lCls='g';lbl='Feld '+i;sub=mg.n;badge=`
${esc(mg.e)} ${esc(mg.n)}
`;} else{dCls='em';lCls='em';lbl='Feld '+i;sub='Leeres Durchgangsfeld';} it.innerHTML=`
${isSt?'🟢':isEn?'🏁':mg?esc(mg.e):'⬜'}
${esc(lbl)}
${esc(sub)}
${badge}
`; tl.appendChild(it); ST.storyItems.filter(s=>s.position==='after'&&s.fieldIndex===i).forEach(s=>{ const it2=document.createElement('div');it2.className='tl-item story-it'; it2.innerHTML=`
${esc(s.emoji||'📖')}
Erzähl-Text
${esc(s.text||'(noch leer)')}
Nach Feld ${i}
`; tl.appendChild(it2); }); } tlCard.appendChild(tl);area.appendChild(tlCard); // Quiz preview if(ST.quizData.length>0){ const qc=document.createElement('div');qc.className='card'; qc.innerHTML='
❓ Quiz-Fragen
'; const ql=document.createElement('div');ql.className='qp-list'; ST.quizData.forEach((q,i)=>{ const qi=document.createElement('div');qi.className='qp-item'; qi.innerHTML=`
Frage ${i+1}: ${esc(q.question||'(leer)')}
${LETTERS.map((L,j)=>`
${esc(L)} ${esc(q.answers[j]||'?')}${q.correct===j?' ✓':''}
`).join('')}
`; ql.appendChild(qi); }); qc.appendChild(ql);area.appendChild(qc); } // Checklist const cc=document.createElement('div');cc.className='card';cc.innerHTML='
🔍 Checkliste
'; const cl=document.createElement('div');cl.className='checklist'; const qDone=ST.quizData.filter(isQComplete).length; [ {ok:!!ST.name,t:ST.name?`Spielname: "${esc(ST.name)}"`:'Kein Spielname vergeben'}, {ok:!!(ST.figure&&ST.background),t:ST.figure?`Figur & Setting: ${esc(fig.n)} / ${esc(bg.n)}`:'Figur oder Setting fehlt'}, {ok:filled>0,t:`${filled} von ${ST.fieldCount-2} Spielfeldern belegt`}, {ok:ST.quizData.length===0||qDone===ST.quizData.length,t:ST.quizData.length===0?'Keine Quiz-Felder (ok)':`${qDone}/${ST.quizData.length} Quiz-Fragen ausgefüllt`}, ].forEach(ch=>{const it=document.createElement('div');it.className='chk-item '+(ch.ok?'ok':'warn');it.innerHTML=`${ch.ok?'✅':'⚠️'}${ch.t}`;cl.appendChild(it);}); cc.appendChild(cl);area.appendChild(cc); // Fill launch card document.getElementById('lhFig').textContent=fig.e; document.getElementById('lhName').textContent=ST.name||'Mein Spiel'; document.getElementById('lhDesc').textContent=ST.desc||''; document.getElementById('lhPills').innerHTML=[ `
${fig.e} ${fig.n}
`, `
🌍 ${bg.n}
`, `
⬛ ${ST.fieldCount} Felder
`, `
${ST.rules.fail==='lives'?'❤️ '+ST.rules.lives+' Leben':'⭐ Punkte'}
`, ].join(''); const uniqueG=[...new Set(ST.fields.filter(Boolean))]; document.getElementById('launchChk').innerHTML=[ {i:'🎲',t:`${ST.fieldCount} Felder · ${filled} Mini-Games`}, {i:'🕹️',t:`Games: ${uniqueG.map(g=>{const m=MINIGAMES.find(x=>x.id===g);return m?m.e:'❓';}).join(' ')||'—'}`}, {i:'📖',t:`${ST.storyItems.length} Erzähltexte`}, {i:'🎵',t:`Musik-Theme: ${bg.n}`}, ].map(x=>`
${x.i}${x.t}
`).join(''); } let gamePlayed=false; function doLaunch(){ save(); const w=window.open('game.html','Spiel',`width=${Math.min(1100,screen.width-60)},height=${Math.min(800,screen.height-60)},left=40,top=30,resizable=yes,scrollbars=no`); if(!w){showToast('⚠️ Popup blockiert! Bitte Popups erlauben.');return;} document.getElementById('btnLaunch').textContent='⏳ Warte auf Spielende...'; document.getElementById('btnLaunch').disabled=true; const poll=setInterval(()=>{if(w.closed){clearInterval(poll);onGameDone();}},800); } function onGameDone(){ gamePlayed=true; document.getElementById('btnLaunch').textContent='🔄 Nochmal spielen'; document.getElementById('btnLaunch').disabled=false; document.getElementById('playedBadge').classList.add('visible'); const fc=document.getElementById('fbCard');fc.style.display='block'; fc.style.animation='slideIn 0.4s ease both'; setTimeout(()=>fc.scrollIntoView({behavior:'smooth',block:'start'}),500); fbCur=0;fbAnswers={};renderFB(); } /* ══════════════════════════════════════════════ FEEDBACK ══════════════════════════════════════════════ */ let fbCur=0,fbAnswers={}; function renderFB(){ const q=FB_QS[fbCur]; document.getElementById('fbFill').style.width=(fbCur/FB_QS.length*100)+'%'; document.getElementById('fbPrev').style.display=fbCur>0?'':'none'; document.getElementById('fbNext').textContent=fbCurFrage ${fbCur+1} von ${FB_QS.length}
${q.q}
${q.sub?`
${q.sub}
`:''}`; if(q.t==='mc'){ const opts=document.createElement('div');opts.className='mc-opts'; q.opts.forEach((o,i)=>{const btn=document.createElement('div');btn.className='mc-opt'+(fbAnswers[q.id]===i?' sel':'');btn.innerHTML=`
${o}`;btn.addEventListener('click',()=>{fbAnswers[q.id]=i;opts.querySelectorAll('.mc-opt').forEach(b=>b.classList.remove('sel'));btn.classList.add('sel');document.getElementById('fbNext').disabled=false;});opts.appendChild(btn);}); area.appendChild(opts); } if(q.t==='scale'){ const row=document.createElement('div');row.className='scale-row'; for(let i=1;i<=5;i++){const btn=document.createElement('button');btn.className='scale-btn'+(fbAnswers[q.id]===i?' sel':'');btn.textContent=i;btn.addEventListener('click',()=>{fbAnswers[q.id]=i;row.querySelectorAll('.scale-btn').forEach(b=>b.classList.remove('sel'));btn.classList.add('sel');document.getElementById('fbNext').disabled=false;});row.appendChild(btn);} area.appendChild(row); const lbl=document.createElement('div');lbl.className='scale-lbls';lbl.innerHTML=`${q.min}${q.max}`;area.appendChild(lbl); } if(q.t==='text'){ const ta=document.createElement('textarea');ta.className='fb-ta';ta.rows=3;ta.placeholder=q.ph||'';ta.value=fbAnswers[q.id]||'';ta.addEventListener('input',()=>{fbAnswers[q.id]=ta.value;document.getElementById('fbNext').disabled=ta.value.trim().length<3;});area.appendChild(ta); } document.getElementById('fbNext').disabled=fbAnswers[q.id]===undefined; } function fbFwd(){ fbCur++; if(fbCur>=FB_QS.length){showSummaryCard();return;} renderFB(); } function fbBack(){if(fbCur>0){fbCur--;renderFB();}}