Lehrer-View-Uebersicht: Sterne- + Prozent-Formeln je Sim dokumentiert
- Globale Erklaer-Box: wie der Zeilen-% entsteht (live.php extractScore: Score sonst Sterne/5x100) + Uneinheitlichkeiten (0-3 vs 0-5 Sterne, rohe score-Werte, Weltkueche pro Gericht, Logistik sendet nichts) + Vorschlag 'ein System' (% = Wahrheit, Sterne abgeleitet, gleiche Schwellen). - Pro Sim ein Bewertungs-Block mit exakter Sterne-Formel + Prozent-Herkunft (aus dem Sterne-Audit der Game-Files) inkl. Warnhinweisen. - Tourismustal: Gaeste-Spalte auf gruen (Gesamtgaeste = Spielfaktor). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+103
-1
@@ -51,6 +51,18 @@
|
|||||||
.note li{margin:.15rem 0;line-height:1.4}
|
.note li{margin:.15rem 0;line-height:1.4}
|
||||||
.note code{background:#efe8d5;border-radius:3px;padding:0 4px;font-size:.72rem;color:#7a5a1a}
|
.note code{background:#efe8d5;border-radius:3px;padding:0 4px;font-size:.72rem;color:#7a5a1a}
|
||||||
.allgreen{margin:.6rem 1.1rem 1rem;background:#f0f7f1;border:1px solid #cfe6d2;border-left:4px solid #5a8a5e;border-radius:8px;padding:.55rem .85rem;font-size:.76rem;color:#3a6b3e}
|
.allgreen{margin:.6rem 1.1rem 1rem;background:#f0f7f1;border:1px solid #cfe6d2;border-left:4px solid #5a8a5e;border-radius:8px;padding:.55rem .85rem;font-size:.76rem;color:#3a6b3e}
|
||||||
|
.scorebox{margin:.2rem 1.1rem 1rem;background:#eef3f7;border:1px solid #d3e0e8;border-left:4px solid #4a7c8a;border-radius:8px;padding:.7rem .9rem;font-size:.78rem;color:#2f4a58}
|
||||||
|
.scorebox h4{font-size:.8rem;color:#2f5866;margin-bottom:.45rem;display:flex;align-items:center;gap:.4rem}
|
||||||
|
.scorebox .srow{display:grid;grid-template-columns:78px 1fr;gap:.5rem;margin:.28rem 0;align-items:start}
|
||||||
|
.scorebox .srow .lab{font-weight:700;color:#3a6072}
|
||||||
|
.scorebox code{background:#dde8ee;border-radius:3px;padding:0 4px;font-size:.72rem;color:#294a58;font-family:'Courier New',monospace}
|
||||||
|
.scorebox .flag{display:block;margin-top:.5rem;font-size:.73rem;color:#8a3a2a;background:#fbeee9;border:1px solid #ecc9bd;border-radius:6px;padding:.35rem .55rem}
|
||||||
|
.scorebox .flag b{color:#a5341f}
|
||||||
|
.gbox{background:#fff;border-radius:12px;box-shadow:0 1px 4px rgba(0,0,0,.04);padding:1.1rem 1.3rem;margin-bottom:1.2rem;border-left:4px solid #4a7c8a}
|
||||||
|
.gbox h2{font-size:1rem;color:#1f4b37;font-weight:800;margin-bottom:.5rem}
|
||||||
|
.gbox p{font-size:.82rem;line-height:1.5;color:#4a4a4a;margin-bottom:.5rem}
|
||||||
|
.gbox code{background:#eef3f5;border-radius:3px;padding:0 4px;font-size:.75rem;color:#294a58;font-family:'Courier New',monospace}
|
||||||
|
.gbox .rec{background:#f0f7f1;border:1px solid #cfe6d2;border-radius:8px;padding:.6rem .8rem;font-size:.8rem;color:#2f5e39;margin-top:.5rem}
|
||||||
.foot{font-size:.72rem;color:#8a8a8a;text-align:center;margin-top:2rem}
|
.foot{font-size:.72rem;color:#8a8a8a;text-align:center;margin-top:2rem}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@@ -80,6 +92,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="gbox">
|
||||||
|
<h2>So entstehen Prozent & Sterne — und warum das heute uneinheitlich ist</h2>
|
||||||
|
<p><b>Der Zeilen-Prozentwert</b> in „Ergebnisse/Aktuell" entsteht in <code>live.php · extractScore</code>: liefert die Sim einen eigenen <b>0–100-Score</b>, wird der genommen; sonst aus den Sternen: <code>% = Sterne / 5 × 100</code>.</p>
|
||||||
|
<p><b>Die Sterne</b> berechnet jede App am Ende selbst — aus unterschiedlichen Kennzahlen und Schwellen (je Sim unten dokumentiert). Deshalb bedeuten 4★ heute nicht überall dasselbe.</p>
|
||||||
|
<p><b>Uneinheitlichkeiten:</b> Busfahrt · Fluggesellschaft · Kofferdetektiv liefern nur <b>0–3 Sterne</b> statt 0–5. Busfahrt/Fluggesellschaft senden als <code>score</code> rohe Punkte (nicht 0–100 → Zeilen-% verzerrt). Weltküche wertet <b>pro Gericht</b> statt pro Durchgang. <b>Logistik überträgt weder Sterne noch Score</b>. Ein echter 0–100-Live-Score existiert nur bei Klima, Fluss, Heli, Kofferdetektiv, Tourismusregion (abgeleitet Tourismustal).</p>
|
||||||
|
<div class="rec"><b>Vorschlag (ein System):</b> Jede App liefert genau <b>eine Funktion → Leistungs-% (0–100)</b> als Wahrheit (grün→rot-Balken). Sterne werden daraus mit <b>denselben globalen Schwellen für alle</b> abgeleitet (z. B. ≥90→5★ · ≥75→4 · ≥55→3 · ≥35→2 · sonst 1). Dann bedeuten Sterne überall dasselbe und % ↔ Sterne sind konsistent.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="toc" id="toc"></div>
|
<div class="toc" id="toc"></div>
|
||||||
<div id="content"></div>
|
<div id="content"></div>
|
||||||
<p class="foot">Alle Werte sind Beispieldaten zur Ansicht. Render-Logik gespiegelt aus <code>teacher.html · renderLive()</code>. Grün/Grau ist Atlas' Vorschlag — bitte prüfen & korrigieren.</p>
|
<p class="foot">Alle Werte sind Beispieldaten zur Ansicht. Render-Logik gespiegelt aus <code>teacher.html · renderLive()</code>. Grün/Grau ist Atlas' Vorschlag — bitte prüfen & korrigieren.</p>
|
||||||
@@ -393,7 +413,7 @@ var GREEN = {
|
|||||||
heli: ['missionId','planIndex','planCorrect','planAttempts','startScore','landingScore','totalStars','failed'],
|
heli: ['missionId','planIndex','planCorrect','planAttempts','startScore','landingScore','totalStars','failed'],
|
||||||
kofferdetektiv: ['progressPct','score','cases_solved','hints_revealed','wrong_guesses_total'],
|
kofferdetektiv: ['progressPct','score','cases_solved','hints_revealed','wrong_guesses_total'],
|
||||||
sonnensystem: ['completed','progressPct','achievementsUnlocked'],
|
sonnensystem: ['completed','progressPct','achievementsUnlocked'],
|
||||||
tourismustal: ['scene','year','money','satisfaction','nature','goalsDone','buildings'],
|
tourismustal: ['scene','year','money','guestsToday','satisfaction','nature','goalsDone','buildings'],
|
||||||
tourismusregion: ['mapId','wave','budget','revenue','avgStars','env','goalsDone'],
|
tourismusregion: ['mapId','wave','budget','revenue','avgStars','env','goalsDone'],
|
||||||
logistik: ['levelId','balance','ordersDelivered','ordersLate','progressPct'],
|
logistik: ['levelId','balance','ordersDelivered','ordersLate','progressPct'],
|
||||||
};
|
};
|
||||||
@@ -428,6 +448,74 @@ var GREY_REASON = {
|
|||||||
ordersOpen:'offene Aufträge im Moment',
|
ordersOpen:'offene Aufträge im Moment',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
3b) Bewertung je Sim — wie Sterne UND Prozent zustandekommen.
|
||||||
|
Quelle: Sterne-Audit der Game-Files (Formeln/Schwellen 1:1).
|
||||||
|
============================================================ */
|
||||||
|
var SCORING = {
|
||||||
|
farmer: {
|
||||||
|
stars:'<b>0–5</b> aus <code>totalScore</code> (0–100, gewichtet: Konto 25% · Trefferquote 20% · CO₂ 15% · Krankheiten 10% · Sorten 10% · Länder 10% · Klimazonen 10%). Schwellen: <code>≥85→5 · ≥70→4 · ≥50→3 · ≥30→2 · sonst 1</code>.',
|
||||||
|
pct:'Kein 0–100-Live-Score → Zeilen-% = <code>Sterne/5×100</code> (im Ergebnis liegt zusätzlich <code>data.score</code>).',
|
||||||
|
},
|
||||||
|
klima: {
|
||||||
|
stars:'<b>0–5</b>: Basis <code>2★</code> bei Sieg, dann <code>+1</code> je Temp<17° · Temp<16,3° · Budget>200 · (Flut<20% & Bev.>90% Start). Deckel: Temp≥17°→max 3★, ≥18,5°→max 1★.',
|
||||||
|
pct:'Eigener 0–100-Score = <code>TempScore(0–35)+FlutScore(0–25)+BudgetScore(0–20)+BevScore(0–20)</code>. Live-Score identisch → Zeilen-% = dieser Score.',
|
||||||
|
},
|
||||||
|
fluss: {
|
||||||
|
stars:'<b>0–5</b> aus Score: <code>≥85→5 · ≥70→4 · ≥55→3 · ≥35→2 · sonst 1</code>.',
|
||||||
|
pct:'Score 0–100 = <code>Ø(Biodiv, Wirtschaft, Hochwasserschutz) − 5×Siedlungsverluste</code>. Live-Score vorhanden → Zeilen-% = Score.',
|
||||||
|
},
|
||||||
|
energiemanager: {
|
||||||
|
stars:'<b>0–5</b> aus <code>Quote = ausgeglichene Blöcke / gesamt</code>: <code>≥1,0→5 · ≥0,87→4 · ≥0,66→3 · ≥0,50→2 · sonst 1</code>. Blackout-Deckel: 1×→max 3★, ≥2×→max 2★.',
|
||||||
|
pct:'Kein 0–100-Live-Score → Zeilen-% = <code>Sterne/5×100</code>.',
|
||||||
|
},
|
||||||
|
'eu-werkstatt': {
|
||||||
|
stars:'<b>0–5</b> aus <code>firstTryRate = saubere Erstversuche / Schritte</code>: <code>≥1,0→5 · ≥0,85→4 · ≥0,65→3 · ≥0,40→2 · sonst 1</code>.',
|
||||||
|
pct:'Kein 0–100-Live-Score → Zeilen-% = <code>Sterne/5×100</code>.',
|
||||||
|
},
|
||||||
|
weltkueche: {
|
||||||
|
stars:'<b>0–5 pro Gericht</b> aus Fehlern: <code>0→5 · ≤1→4 · ≤3→3 · ≤6→2 · sonst 1</code>.',
|
||||||
|
pct:'Live-<code>score</code> ist eine <b>rohe Punktezahl</b> (nicht 0–100) → Zeilen-% aktuell unklar.',
|
||||||
|
flags:['Wird <b>pro Gericht</b> gesendet, nicht pro Durchgang.','„Fehler in %" (Fehler ÷ Aktionen) gehört genau hierher — vergleichbar statt roher, gericht-abhängiger Zahl.'],
|
||||||
|
},
|
||||||
|
busfahrt: {
|
||||||
|
stars:'<b>nur 0–3</b> aus <code>Ratio = Topo-Punkte / (Aufträge×3)</code>: <code>≥0,85→3 · ≥0,55→2 · ≥0,30→1 · sonst 0</code>.',
|
||||||
|
pct:'Gesendeter <code>score</code> = rohe Topo-Punkte (nicht 0–100).',
|
||||||
|
flags:['0–3 statt 0–5 Sterne.','score ist keine 0–100-Zahl → Zeilen-% verzerrt.'],
|
||||||
|
},
|
||||||
|
fluggesellschaft: {
|
||||||
|
stars:'<b>nur 0–3</b> aus <code>Ratio = Topo-Punkte / (Flüge×3)</code>: <code>≥0,85→3 · ≥0,55→2 · ≥0,30→1 · sonst 0</code>.',
|
||||||
|
pct:'Gesendeter <code>score</code> = rohe Topo-Punkte (nicht 0–100).',
|
||||||
|
flags:['0–3 statt 0–5 Sterne.','score ist keine 0–100-Zahl → Zeilen-% verzerrt.'],
|
||||||
|
},
|
||||||
|
heli: {
|
||||||
|
stars:'<b>0–5</b> = <code>round((PlanSterne + Start + Landung) / 3)</code>. PlanSterne aus Timing (Ø≥1,6→5 …) bzw. Klickgenauigkeit; Chefpilot-Übernahme → 0.',
|
||||||
|
pct:'Live-Score 0–100 = <code>Sterne/5×100</code> (submit <code>score = Sterne×20</code>) → Zeilen-% = das.',
|
||||||
|
},
|
||||||
|
kofferdetektiv: {
|
||||||
|
stars:'<b>nur 0–3</b> aus <code>q = score100/100</code>: <code>≥0,7→3 · ≥0,45→2 · ≥0,2→1 · sonst 0</code>.',
|
||||||
|
pct:'<code>score100 = Punkte / (Fälle×100) × 100</code> (je Fall 100 P, −7/Hinweis, −15/Fehltipp, −20/Timeout). Live-Score = score100 → Zeilen-% = das.',
|
||||||
|
flags:['0–3 statt 0–5 Sterne.'],
|
||||||
|
},
|
||||||
|
sonnensystem: {
|
||||||
|
stars:'<b>1–5</b> aus <code>Quote = Erstversuch-richtig / gesamt</code>: <code>≥0,85→5 · ≥0,68→4 · ≥0,50→3 · ≥0,30→2 · sonst 1</code> (Minimum 1, nie 0).',
|
||||||
|
pct:'Kein 0–100-Live-Score (nur <code>levelWon</code>+Fortschritt; <code>scoreQuote</code> im data) → Zeilen-% = <code>Sterne/5×100</code>.',
|
||||||
|
},
|
||||||
|
tourismustal: {
|
||||||
|
stars:'<b>0–5</b> = <code>min(5, erreichte Ziele + (Sieg?1:0))</code>.',
|
||||||
|
pct:'Score 0–100 = <code>erreichte Ziele / gesamt × 100</code>; kein Live-0–100 → Zeilen-% = data.score bzw. Sterne/5×100.',
|
||||||
|
},
|
||||||
|
tourismusregion: {
|
||||||
|
stars:'<b>0–5</b> = <code>round(Ø Besucher-Bewertung)</code> (avgStars 0–5).',
|
||||||
|
pct:'Score 0–100 = gewichtet: <code>Bewertung 35% · Wertschöpfung 25% · Nachhaltigkeit 20% · Lenkung 10% · Finanzen 10%</code>. Live <code>avgStars</code> → Zeilen-% = Score.',
|
||||||
|
},
|
||||||
|
logistik: {
|
||||||
|
stars:'<b>0–5</b> aus Endkontostand: <code>≤0→0 · ≥16000→5 · ≥13000→4 · ≥10500→3 · ≥8500→2 · sonst 1</code>.',
|
||||||
|
pct:'Kein Score/Stern wird ans Backend gesendet.',
|
||||||
|
flags:['Sterne & Score werden <b>NICHT übertragen</b> — im Lehrer-Cockpit erscheint für Logistik kein Stern/Prozent. Eigene Endpoints <code>/api/assessment</code> + <code>/api/logistik-sessions</code>.'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/* ============================================================
|
/* ============================================================
|
||||||
4) Testdaten je Sim (3 Schüler:innen: stark · schwach · mittel)
|
4) Testdaten je Sim (3 Schüler:innen: stark · schwach · mittel)
|
||||||
============================================================ */
|
============================================================ */
|
||||||
@@ -522,6 +610,17 @@ var TEST = {
|
|||||||
var _LIVE_PAUSE_SEC = 90;
|
var _LIVE_PAUSE_SEC = 90;
|
||||||
function _liveIsActive(ls){ return ls.last_seen_ms && (NOW - ls.last_seen_ms) <= _LIVE_PAUSE_SEC*1000; }
|
function _liveIsActive(ls){ return ls.last_seen_ms && (NOW - ls.last_seen_ms) <= _LIVE_PAUSE_SEC*1000; }
|
||||||
|
|
||||||
|
function renderScoring(id){
|
||||||
|
var sc = SCORING[id];
|
||||||
|
if (!sc) return '';
|
||||||
|
var h = '<div class="scorebox"><h4>🎯 So entsteht die Bewertung</h4>';
|
||||||
|
h += '<div class="srow"><span class="lab">Sterne</span><span>'+sc.stars+'</span></div>';
|
||||||
|
h += '<div class="srow"><span class="lab">Prozent</span><span>'+sc.pct+'</span></div>';
|
||||||
|
(sc.flags||[]).forEach(function(f){ h += '<div class="flag">⚠ '+f+'</div>'; });
|
||||||
|
h += '</div>';
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
function renderSim(meta){
|
function renderSim(meta){
|
||||||
var fields = LIVE_PRIMARY_FIELDS[meta.id] || [];
|
var fields = LIVE_PRIMARY_FIELDS[meta.id] || [];
|
||||||
var rows = TEST[meta.id] || [];
|
var rows = TEST[meta.id] || [];
|
||||||
@@ -596,6 +695,9 @@ function renderSim(meta){
|
|||||||
});
|
});
|
||||||
h += '</tbody></table></div>';
|
h += '</tbody></table></div>';
|
||||||
|
|
||||||
|
// Bewertung: wie Sterne + Prozent entstehen
|
||||||
|
h += renderScoring(meta.id);
|
||||||
|
|
||||||
// Nach-Abschluss-Hinweis
|
// Nach-Abschluss-Hinweis
|
||||||
if (greyKeys.length){
|
if (greyKeys.length){
|
||||||
h += '<div class="note"><b>Nach Abschluss NICHT relevant (nur live):</b><ul>';
|
h += '<div class="note"><b>Nach Abschluss NICHT relevant (nur live):</b><ul>';
|
||||||
|
|||||||
Reference in New Issue
Block a user