From 5d79fa3c3ad4287ea89a1ddc5447a6327f8521e2 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 23 Aug 2026 12:19:41 +0200 Subject: [PATCH] Klima: Flut-Bewertung ans 40%-Spielziel angeglichen Flut-Score (End- + Live-Score in game-2d/3d) = max(0, 25*(1-Flut/50)): 0% volle 25 Pkt, 40% noch ~5 Pkt, erst ~50% gegen 0 (statt 0 schon ab 31%). Lehrer-Geflutet-Ampel gruen <25 / gelb <=40 / rot >40. Klima-Stimmung nutzt jetzt den (fairen) Score. Co-Authored-By: Claude Opus 4.8 --- App/sims/klima/game-2d.html | 4 ++-- App/sims/klima/game-3d.html | 4 ++-- App/teacher.html | 14 ++++++++++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/App/sims/klima/game-2d.html b/App/sims/klima/game-2d.html index 2e87618..d41398b 100644 --- a/App/sims/klima/game-2d.html +++ b/App/sims/klima/game-2d.html @@ -1341,7 +1341,7 @@ function _liveKlimaScore() { if (state.phase !== 'playing' && state.phase !== 'citizen' && state.phase !== 'end') return null; var sp = state.diff.startPopulation || 6000; var tempScore = Math.max(0, Math.min(35, 35 - ((state.currentTemp||0) - 15.5) * 20)); - var floodScore = Math.max(0, 25 - (state.floodedPct||0) * 0.8); + var floodScore = Math.max(0, 25 * (1 - (state.floodedPct||0) / 50)); // Ziel < 40 %: bei 40 % noch ~5 Pkt var budgetScore = Math.max(0, Math.min(20, (state.budget||0) / 10)); var popScore = Math.max(0, Math.min(20, ((state.population||0) / sp) * 20)); return Math.round(tempScore + floodScore + budgetScore + popScore); @@ -3921,7 +3921,7 @@ function computeStars() { } function computeScore() { const tempScore = Math.max(0, Math.min(35, 35 - (state.currentTemp - 15.5) * 20)); - const floodScore = Math.max(0, 25 - state.floodedPct * 0.8); + const floodScore = Math.max(0, 25 * (1 - state.floodedPct / 50)); // Ziel < 40 %: bei 40 % noch ~5 Pkt const budgetScore = Math.max(0, Math.min(20, state.budget / 10)); const popScore = Math.max(0, Math.min(20, (state.population / state.diff.startPopulation) * 20)); return Math.round(tempScore + floodScore + budgetScore + popScore); diff --git a/App/sims/klima/game-3d.html b/App/sims/klima/game-3d.html index 1d869c9..a59eee0 100644 --- a/App/sims/klima/game-3d.html +++ b/App/sims/klima/game-3d.html @@ -1581,7 +1581,7 @@ function _liveKlimaScore() { if (state.phase !== 'playing' && state.phase !== 'citizen' && state.phase !== 'end') return null; var sp = state.diff.startPopulation || 6000; var tempScore = Math.max(0, Math.min(35, 35 - ((state.currentTemp||0) - 15.5) * 20)); - var floodScore = Math.max(0, 25 - (state.floodedPct||0) * 0.8); + var floodScore = Math.max(0, 25 * (1 - (state.floodedPct||0) / 50)); // Ziel < 40 %: bei 40 % noch ~5 Pkt var budgetScore = Math.max(0, Math.min(20, (state.budget||0) / 10)); var popScore = Math.max(0, Math.min(20, ((state.population||0) / sp) * 20)); return Math.round(tempScore + floodScore + budgetScore + popScore); @@ -5391,7 +5391,7 @@ function computeStars() { } function computeScore() { const tempScore = Math.max(0, Math.min(35, 35 - (state.currentTemp - 15.5) * 20)); - const floodScore = Math.max(0, 25 - state.floodedPct * 0.8); + const floodScore = Math.max(0, 25 * (1 - state.floodedPct / 50)); // Ziel < 40 %: bei 40 % noch ~5 Pkt const budgetScore = Math.max(0, Math.min(20, state.budget / 10)); const popScore = Math.max(0, Math.min(20, (state.population / state.diff.startPopulation) * 20)); return Math.round(tempScore + floodScore + budgetScore + popScore); diff --git a/App/teacher.html b/App/teacher.html index b53dfef..7610032 100644 --- a/App/teacher.html +++ b/App/teacher.html @@ -737,7 +737,15 @@ var LIVE_PRIMARY_FIELDS = { // Kennzahlen mit Ampel-Linien (grün→rot), absolute Skalen wie im Spiel: {k:'co2', label:'CO₂', unit:'ppm', fmt:function(v){ return _liveBar(v, 280, 700, 'low'); }}, {k:'temp', label:'Temp', unit:'°C', fmt:function(v){ return _liveBar(v, 14, 20, 'low', 1); }}, - {k:'floodedPct', label:'Geflutet', unit:'%', fmt:function(v){ return _liveBar(v, 0, 100, 'low'); }}, + {k:'floodedPct', label:'Geflutet', unit:'%', fmt:function(v){ + // Ampel am Spielziel „Stadt schützen < 40 %": grün < 25, gelb 25–40, rot > 40. + if (v==null||isNaN(v)) return ''; + var c = v < 25 ? '#5a8a5e' : v <= 40 ? '#c9913a' : '#c07a6b'; + var pct = Math.max(0, Math.min(100, v)); + return '' + + '' + + ''+Math.round(v)+''; + }}, {k:'budget', label:'Budget', unit:'Mio €', fmt:function(v){ return _liveBar(v, -500, 3000, 'high'); }}, {k:'population', label:'Bev.', fmt:function(v, row){ // Relativ zur Startbevölkerung (Level 3 = 7000, sonst 6000): unter Start = rot, @@ -1292,7 +1300,9 @@ function _liveMood(simId, s) { switch (simId) { case 'weltkueche': return (s.mistakesInDish||0) <= 2 ? 'good' : (s.mistakesInDish >= 8 ? 'bad' : 'mid'); case 'farmer': return (s.hit_rate==null) ? 'mid' : (s.hit_rate >= 60 ? 'good' : s.hit_rate >= 30 ? 'mid' : 'bad'); - case 'klima': case 'klima-3d': return ((s.floodedPct==null?100:s.floodedPct) < 20 && (s.budget||0) >= 0) ? 'good' : 'mid'; + case 'klima': case 'klima-3d': return (typeof s.score === 'number') + ? (s.score >= 65 ? 'good' : s.score >= 40 ? 'mid' : 'bad') + : (((s.floodedPct==null?100:s.floodedPct) < 25 && (s.budget||0) >= 0) ? 'good' : 'mid'); case 'busfahrt': case 'fluggesellschaft': return (s.budget==null?0:s.budget) >= 5000 ? 'good' : (s.budget < 0 ? 'bad' : 'mid'); case 'tourismustal': return (s.money==null?0:s.money) >= 4000 ? 'good' : (s.money < 0 ? 'bad' : 'mid'); case 'heli': return (s.totalStars||0) >= 4 ? 'good' : 'mid';