From 8ec005f889c77e6c6d17a68d205bb08957019e44 Mon Sep 17 00:00:00 2001 From: Thomas Date: Mon, 24 Aug 2026 13:33:44 +0200 Subject: [PATCH] EU-Werkstatt: Probierzuege (Karten rausziehen) erfassen + Sterne ehrlicher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bisher konnte man Karten in Slots einsetzen und wieder herausziehen, bis alle voll waren — erst dann wurde ausgewertet. Dieses Herumprobieren war unsichtbar und senkte die Sterne nicht (5 Sterne trotz Trial-and-Error). - game.html: reshufflesByStep/totalReshuffles; manuelles Herausziehen einer platzierten Karte zaehlt als Probierzug. Ein Schritt gilt nur ohne Probierzuege als 'sauber auf Anhieb' -> Sterne (firstTryHits/steps) und Treffsicher-Achievement spiegeln Trial-and-Error jetzt. Endbild zeigt '🔄 N Probierzuege'; Live-State + Submit tragen die Zahlen. - teacher.html: needsHelp eu-werkstatt auch bei vielen Probierzuegen; '🔄 Probier'-Spalte in Aktuell; Run-Karte: Gesamt-Probierzuege + pro Schritt ('🔄 nach Probieren' statt 'auf Anhieb'). Co-Authored-By: Claude Opus 4.8 --- App/sims/eu-werkstatt/game.html | 30 +++++++++++++++++++++++++----- App/teacher.html | 19 +++++++++++++++---- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/App/sims/eu-werkstatt/game.html b/App/sims/eu-werkstatt/game.html index ca3d9a5..4f1a685 100644 --- a/App/sims/eu-werkstatt/game.html +++ b/App/sims/eu-werkstatt/game.html @@ -4036,6 +4036,8 @@ const state = { muelleimerCount: 0, attemptsByStep: [], // Index = stepIndex, Wert = Anzahl Versuche detoursByStep: [], // Index = stepIndex, Wert = [{label, cardId?}, ...] — Mülleimer-Picks + reshufflesByStep: [], // Index = stepIndex, Wert = Anzahl manuell wieder herausgezogener Karten (Probierzüge) + totalReshuffles: 0, startedAt: 0, }; @@ -4293,9 +4295,19 @@ function resetTracking() { state.muelleimerCount = 0; state.attemptsByStep = []; state.detoursByStep = []; + state.reshufflesByStep = []; + state.totalReshuffles = 0; state.startedAt = Date.now(); } +// Probierzug: Schüler:in zieht eine bereits platzierte Karte wieder aus dem +// Slot. Zeichen von Unsicherheit/Trial-and-Error — zählt pro Schritt und +// verhindert, dass der Schritt als „sauber auf Anhieb" gewertet wird. +function registerReshuffle() { + state.reshufflesByStep[state.stepIndex] = (state.reshufflesByStep[state.stepIndex] || 0) + 1; + state.totalReshuffles++; +} + /* ========================================================= AKTUELLEN SCHRITT RENDERN ========================================================= */ @@ -4370,7 +4382,7 @@ function renderPickStep(area, step) { // Slot-Klick = Karte rauswerfen document.getElementById('slot-0').addEventListener('click', () => { if (state.answered) return; - if (state.slotState[0].cardId) clearSlot(0); + if (state.slotState[0].cardId) { registerReshuffle(); clearSlot(0); } }); } @@ -4399,7 +4411,7 @@ function renderSentenceStep(area, step) { step.slots.forEach((_, i) => { document.getElementById(`slot-${i}`).addEventListener('click', () => { if (state.answered) return; - if (state.slotState[i].cardId) clearSlot(i); + if (state.slotState[i].cardId) { registerReshuffle(); clearSlot(i); } }); }); @@ -4720,7 +4732,9 @@ function evaluateStep() { // === Tracking === state.totalAttempts++; state.attemptsByStep[state.stepIndex] = (state.attemptsByStep[state.stepIndex] || 0) + 1; - if (correct && state.attemptsByStep[state.stepIndex] === 1) { + // Sauberer Erstversuch NUR ohne Probierzüge (Karten rein-/rausgezogen) auf + // diesem Schritt — sonst war es Trial-and-Error, kein „auf Anhieb". + if (correct && state.attemptsByStep[state.stepIndex] === 1 && !state.reshufflesByStep[state.stepIndex]) { state.firstTryHits++; } @@ -4956,6 +4970,7 @@ function showEnd() {
${state.firstTryHits}/${stepsTotal} auf Anhieb richtig ${state.totalAttempts} Versuche + ${state.totalReshuffles > 0 ? `🔄 ${state.totalReshuffles} Probierzüge` : ''} ${state.muelleimerCount > 0 ? `${state.muelleimerCount}× im Mülleimer` : ''}
`; @@ -5017,6 +5032,8 @@ function showEnd() { muelleimerCount: state.muelleimerCount, attemptsByStep: state.attemptsByStep, detoursByStep: state.detoursByStep, + reshufflesByStep: state.reshufflesByStep, + totalReshuffles: state.totalReshuffles, difficulty: state.difficulty, newAchievements, }, @@ -5275,13 +5292,14 @@ window.GGS_LIVE_STATE = function () { var stepIdx = state.stepIndex || 0; var currentStep = (state.scenario && state.scenario.steps) ? state.scenario.steps[stepIdx] : null; var attemptsThisStep = (state.attemptsByStep && state.attemptsByStep[stepIdx]) || 0; + var reshufflesThisStep = (state.reshufflesByStep && state.reshufflesByStep[stepIdx]) || 0; var secondsElapsed = state.startedAt ? Math.round((Date.now() - state.startedAt) / 1000) : 0; // Health-Ampel (für die Lehrer-Live-Übersicht der nächsten Phase) var health = 'good'; if (screen === 'play') { - if (state.muelleimerCount >= 3 || attemptsThisStep >= 3) health = 'struggling'; - else if (state.muelleimerCount >= 1 || attemptsThisStep >= 2) health = 'ok'; + if (state.muelleimerCount >= 3 || attemptsThisStep >= 3 || reshufflesThisStep >= 4) health = 'struggling'; + else if (state.muelleimerCount >= 1 || attemptsThisStep >= 2 || reshufflesThisStep >= 2) health = 'ok'; } else if (screen === 'end') { health = 'good'; } else { @@ -5315,6 +5333,8 @@ window.GGS_LIVE_STATE = function () { totalAttempts: state.totalAttempts || 0, muelleimerCount: state.muelleimerCount || 0, attemptsThisStep: attemptsThisStep, + reshuffles: state.totalReshuffles || 0, + reshufflesThisStep: reshufflesThisStep, secondsElapsed: secondsElapsed, achievementsUnlocked: Object.keys(ach).length, achievementsTotal: (typeof ACHIEVEMENTS !== 'undefined') ? ACHIEVEMENTS.length : 6, diff --git a/App/teacher.html b/App/teacher.html index fe885c2..5a5ce88 100644 --- a/App/teacher.html +++ b/App/teacher.html @@ -810,6 +810,11 @@ var LIVE_PRIMARY_FIELDS = { var color = v === 0 ? '#5a8a5e' : v >= 3 ? '#c07a6b' : '#c9913a'; return ''+v+''; }}, + {k:'reshuffles', label:'🔄 Probier', align:'center', fmt:function(v){ + if (!v) return ''; + var color = v >= 5 ? '#c07a6b' : v >= 2 ? '#c9913a' : '#5a8a5e'; + return ''+v+''; + }}, {k:'secondsElapsed', label:'Dauer', fmt:function(v){ return v ? _fmtSeconds(v) : '—'; }}, {k:'achievementsUnlocked', label:'Erfolge', fmt:function(v, row){ var s = row.state || {}; @@ -1281,7 +1286,7 @@ function _liveNeedsHelp(simId, s) { case 'weltkueche': return (s.mistakesInDish||0) >= 12; case 'farmer': return (s.cash==null?1000:s.cash) < 0 || ((s.attempts||0) >= 6 && s.hit_rate != null && s.hit_rate < 30); case 'logistik': return (s.balance==null?1000:s.balance) < 0; - case 'eu-werkstatt': return (s.attemptsThisStep||0) >= 6; + case 'eu-werkstatt': return (s.attemptsThisStep||0) >= 6 || (s.reshufflesThisStep||0) >= 5; case 'energiemanager': return (s.blackouts||0) >= 2 || (s.phase === 'done' && (s.balanced||0) < 4); case 'tourismustal': return (s.money==null?1:s.money) < 0 || (s.lossStreak||0) >= 8; case 'tourismusregion': return (s.budget==null?1:s.budget) < -400 || (s.env==null?100:s.env) < 30; @@ -5192,18 +5197,23 @@ function renderEuWerkstattRun(dt, dur, r, d) { var stepsTotal = d.stepsTotal || 0; var attempts = d.attemptsByStep || []; var detours = d.detoursByStep || []; + var reshuffles = d.reshufflesByStep || []; // Schritt-für-Schritt-Tabelle var stepRows = ''; for (var i = 0; i < stepsTotal; i++) { var n = attempts[i] || 1; - var firstTry = (n === 1); + var rs = reshuffles[i] || 0; + var clean = (n === 1 && !rs); // sauber = ein Zug, kein Herumprobieren var stepDet = (detours[i] || []).map(function(x){ var ic = x.kind === 'muelleimer' ? '🗑️' : '🔁'; return ''+ic+' '+esc(x.label||'')+''; }).join(''); - var tag = firstTry + if (rs > 0) stepDet += '🔄 '+rs+' Probierzug'+(rs===1?'':'e')+''; + var tag = clean ? '✓ auf Anhieb' - : ''+n+'. Versuch'; + : (n > 1 + ? ''+n+'. Versuch' + : '🔄 nach Probieren'); stepRows += ''+(i+1)+'.'+tag+''+(stepDet||'—')+''; } return '' @@ -5217,6 +5227,7 @@ function renderEuWerkstattRun(dt, dur, r, d) { + '
' + ''+(d.firstTryHits||0)+'/'+stepsTotal+' auf Anhieb' + ''+(d.totalAttempts||0)+' Versuche' + + ((d.totalReshuffles||0)>0 ? '🔄 '+d.totalReshuffles+' Probierzüge' : '') + ''+(d.muelleimerCount||0)+' Mülleimer' + '
' + (stepRows