Tourismustal: Komplett-Integration (Sim + Wrapper + SQL + Lehrer-Backend)
Sim nach App/sims/tourismustal umgezogen (Source of Truth), game.html mit Injection-Marker. Neu in der Sim: 5 Sommergebaeude (Bikepark mit Flowtrails, Hochseilgarten, Fahrradverleih als Verstaerker, Aussichtsplattform, Erlebnisspielplatz), Rettungsstation mit Notarzthubschrauber, Ausbau- Bauanimation, Event-Pacing, Schulden-Notbremse (Bank-Zwangsverkauf), Berater-Tipps (Ruecklagen), Sommer-Trend-Mechanik (Serfaus-Effekt) und Wissens-Bausteine mit echten DACH-Tourismusdaten (QUELLEN.md). Plattform: PHP-Wrapper mit base-Tag + Session-Mode, Modul-Detailseite, module_info (beta) + Glossar (14 Begriffe inkl. Leichter Sprache + Quellen) + Lehrplan-Anker AT/DE/CH an neuer Kompetenz tourismus-raumentwicklung. Lehrer-Backend: Benchmark-Formel, Live-Cockpit-Spalten, needsHelp-Heuristik, Modul-Highlights. Strategie-Testharness (tests/strategien.mjs) belegt: Panzer-Rush wird liquidiert, Ruecklagen zahlen sich aus. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -621,6 +621,8 @@ if ($method === 'GET') {
|
||||
return ($state['balance'] ?? 1000) < 0;
|
||||
case 'eu-werkstatt':
|
||||
return ($state['attemptsThisStep'] ?? 0) >= 6;
|
||||
case 'tourismustal':
|
||||
return ($state['money'] ?? 1) < 0 || ($state['lossStreak'] ?? 0) >= 8;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -74,6 +74,13 @@ $MODULE_HIGHLIGHTS = [
|
||||
['key'=>'routes_completed','label'=>'Routen', 'agg'=>'max'],
|
||||
['key'=>'avg_accuracy', 'label'=>'Genauigkeit','agg'=>'max','format'=>'percent'],
|
||||
],
|
||||
'tourismustal' => [
|
||||
['key'=>'results.money', 'label'=>'Konto', 'agg'=>'max', 'unit'=>'€'],
|
||||
['key'=>'results.maxGuests', 'label'=>'Gäste-Rekord','agg'=>'max'],
|
||||
['key'=>'results.maxSummerGuests', 'label'=>'Sommer-Rekord','agg'=>'max'],
|
||||
['key'=>'results.nature', 'label'=>'Naturwert', 'agg'=>'max', 'unit'=>'%'],
|
||||
['key'=>'results.goalsDone', 'label'=>'Ziele', 'agg'=>'max'],
|
||||
],
|
||||
];
|
||||
|
||||
// Hilfsfunktion: holt einen Wert aus einem JSON-Pfad ("results.money" → $json['results']['money']).
|
||||
|
||||
@@ -52,6 +52,7 @@ class Benchmark
|
||||
'fluss' => self::scoreFluss($results),
|
||||
'fluggesellschaft' => self::scoreFluggesellschaft($results),
|
||||
'kofferdetektiv' => self::scoreKofferdetektiv($results),
|
||||
'tourismustal' => self::scoreTourismustal($results),
|
||||
// Entscheidungstag: kein assessment-Submit-Pfad bekannt → null
|
||||
default => self::scoreFallbackStars($results),
|
||||
};
|
||||
@@ -437,6 +438,27 @@ class Benchmark
|
||||
return (int)round(max(0, min(100, $base + $clean + $sparse - $malus)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tourismustal — Zielerreichung × Zufriedenheit × Naturwert − Schulden-Malus.
|
||||
* 50 % Szenen-Ziele + 25 % Gäste-Zufriedenheit + 25 % Naturwert,
|
||||
* −15 wenn das Konto im Minus endet (Rücklagen sind Teil der Didaktik).
|
||||
* Felder aus dem Submit-Hook (game.html → progress.php submit_assessment).
|
||||
*/
|
||||
private static function scoreTourismustal(array $r): ?int
|
||||
{
|
||||
$goalsDone = $r['goalsDone'] ?? null;
|
||||
$goalsTotal = (int)($r['goalsTotal'] ?? 0);
|
||||
if (!is_numeric($goalsDone) || $goalsTotal <= 0) return null;
|
||||
$sat = (float)($r['satisfaction'] ?? 0);
|
||||
$nature = (float)($r['nature'] ?? 0);
|
||||
$money = (float)($r['money'] ?? 0);
|
||||
$score = ($goalsDone / $goalsTotal) * 50
|
||||
+ ($sat / 100) * 25
|
||||
+ ($nature / 100) * 25
|
||||
- ($money < 0 ? 15 : 0);
|
||||
return (int)round(max(0, min(100, $score)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generischer Fallback: Sterne aus 5-er-Skala.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user