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:
2026-07-11 02:45:08 +02:00
parent eb565d4c01
commit 0a2ebf46b4
55 changed files with 6820 additions and 0 deletions
+199
View File
@@ -0,0 +1,199 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Tourismustal GeoGraSim</title>
<script>/*__TOURISMUSTAL_INJECTION__*/</script>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<canvas id="map"></canvas>
<header id="topbar" class="panel">
<button id="btnHome" class="icon-btn" title="Zurück zur Übersicht"></button>
<h1><span id="valleyTitle">Tourismustal</span> <span id="sceneName"></span></h1>
<div class="top-right">
<div id="clock" class="clock"></div>
<div class="speed" role="group" aria-label="Zeitskala">
<button data-speed="0" class="icon-btn speed-btn" title="Pause"></button>
<button data-speed="1" class="icon-btn speed-btn active" title="Normal">1×</button>
<button data-speed="2" class="icon-btn speed-btn" title="Schnell">2×</button>
<button data-speed="4" class="icon-btn speed-btn" title="Sehr schnell">4×</button>
</div>
<button id="btnLog" class="icon-btn" title="Meldungen">🔔<span id="logBadge" class="badge hidden">0</span></button>
<button id="btnSound" class="icon-btn" title="Sound an/aus">🔊</button>
<button id="btnMusic" class="icon-btn" title="Musik an/aus">🎵</button>
<button id="btnHelp" class="icon-btn" title="Anleitung &amp; Info"></button>
</div>
</header>
<aside id="kpis" class="panel">
<div class="kpi-season" id="seasonBadge">Sommer</div>
<div id="yearWheel" title="Jahreskreis (Juli bis Juni)">
<div class="seg sum" style="flex:2" title="JuliAugust"></div>
<div class="seg aut" style="flex:1" title="September"></div>
<div class="seg win" style="flex:6" title="Skisaison: OktoberMärz"></div>
<div class="seg spr" style="flex:1" title="April"></div>
<div class="seg sum" style="flex:2" title="MaiJuni"></div>
<div id="yearMarker"></div>
</div>
<div id="weatherRow">
<b id="weatherNow" title="Wetter heute"></b>
<span id="forecast" title="Vorhersage (3 Tage)"></span>
</div>
<div class="kpi"><span>💰 Geld</span><b id="kMoney"></b></div>
<div class="kpi"><span>🥾 Gäste/Tag</span><b id="kGuests"></b></div>
<div id="kGap" class="kpi-gap hidden"></div>
<div class="kpi hidden" id="kpiRowSnow"><span>❄️ Schnee</span><b id="kSnow"></b></div>
<div class="kpi"><span>😊 Zufriedenheit</span><b id="kSat"></b></div>
<div class="kpi hidden" id="kpiRowNature"><span>🌲 Naturwert</span><b id="kNature"></b></div>
<div class="kpi hidden" id="kpiRowStaff"><span>👷 Personal</span><b id="kStaff"></b></div>
<div class="price-row hidden" id="priceRow">
<span>🎟️ Skipass</span><b id="kPrice">25 €</b>
</div>
<input id="priceSlider" type="range" min="15" max="45" step="1" value="25"
aria-label="Skipass-Preis" class="hidden">
<div id="quest" class="hidden">
<h3>Auftrag</h3>
<div class="quest-body">
<span id="questIcon" class="quest-icon"></span>
<div>
<b id="questTitle"></b>
<small id="questDesc"></small>
<small id="questReward" class="quest-reward"></small>
</div>
</div>
</div>
<div id="goals" class="hidden">
<h3>Ziele bis Ende 1979</h3>
<ul id="goalList"></ul>
</div>
<button id="btnReport" class="secondary">📋 Tagesbericht</button>
</aside>
<aside id="buildmenu" class="panel">
<h2>Bauen</h2>
<div id="buildItems"></div>
</aside>
<section id="graphs" class="panel hidden">
<div class="graph-box">
<div class="legend"><span class="dot money"></span> Geld</div>
<canvas id="graphMoney"></canvas>
</div>
<div class="graph-box">
<div class="legend"><span class="dot guests"></span> Gäste/Tag</div>
<canvas id="graphCanvas"></canvas>
</div>
</section>
<div id="playerPanel" class="panel hidden">
<select id="trackSelect" aria-label="Titel wählen"></select>
<div class="player-controls">
<button id="plPrev" class="icon-btn" title="Voriger Titel"></button>
<button id="plPlay" class="icon-btn" title="Abspielen/Pause"></button>
<button id="plNext" class="icon-btn" title="Nächster Titel"></button>
<input id="plVol" type="range" min="0" max="1" step="0.05" aria-label="Lautstärke">
</div>
</div>
<div id="toast" class="panel hidden"></div>
<div id="cardOverlay" class="overlay hidden">
<div class="card panel">
<div id="cardIcon" class="card-icon"></div>
<h2 id="cardTitle"></h2>
<p id="cardText"></p>
<div class="card-buttons">
<button id="cardOk" class="primary">Weiter</button>
<button id="cardAlt" class="secondary hidden">Ablehnen</button>
</div>
</div>
</div>
<div id="buildingOverlay" class="overlay hidden">
<div class="card panel">
<div id="biIcon" class="card-icon"></div>
<h2 id="biTitle"></h2>
<div id="biLevel" class="bi-level"></div>
<ul id="biStats" class="bi-stats"></ul>
<div id="biCost" class="bi-cost"></div>
<div id="biProblems" class="bi-problems hidden"></div>
<div id="biKnowledge" class="bi-knowledge hidden"></div>
<div class="card-buttons">
<button id="biUpgrade" class="primary"></button>
<button id="biClose" class="secondary">Schließen</button>
</div>
<button id="biDemolish" class="bi-demolish">🧨 Abreißen (30 % zurück)</button>
</div>
</div>
<div id="reportOverlay" class="overlay hidden">
<div class="card panel report-card">
<h2 id="rpTitle">📋 Tagesbericht</h2>
<div id="rpBody"></div>
<button id="rpClose" class="primary">Schließen</button>
</div>
</div>
<div id="logOverlay" class="overlay hidden">
<div class="card panel">
<h2>📨 Meldungen</h2>
<ul id="logList"></ul>
<button id="logClose" class="primary">Schließen</button>
</div>
</div>
<div id="startOverlay" class="overlay">
<div class="card panel">
<div class="card-icon">🏔️</div>
<h2>Tourismustal</h2>
<p class="intro">Entwickle ein Alpental zur Tourismusregion und halte
Wirtschaft, Personal, Schnee und Natur im Gleichgewicht.</p>
<input id="valleyName" type="text" maxlength="24"
placeholder="Wie soll dein Tal heißen? (optional)"
autocomplete="off">
<div class="scene-list">
<button class="scene-btn" data-scene="pionierzeit">
<b>Szene 1 · Pionierzeit 1975</b>
<small>Baue das erste Skigebiet des Tals auf Schritt für Schritt.</small>
</button>
<button class="scene-btn" data-scene="boom">
<b>Szene 2 · Boom 2000</b>
<small>Die Gäste strömen wächst du, ohne das Tal zu verkaufen?</small>
</button>
<button class="scene-btn" data-scene="klimawandel">
<b>Szene 3 · Schneegrenze 2035</b>
<small>Die Winter werden wärmer erfinde das Tal neu.</small>
</button>
</div>
</div>
</div>
<script type="module" src="js/main.js"></script>
<script>
// Fallback: Per Doppelklick geöffnet (file://) laden ES-Module nicht.
// Dann wäre der Startbildschirm sichtbar, aber tot klare Meldung zeigen.
window.addEventListener('load', function () {
setTimeout(function () {
if (window.__ttLoaded) return;
var card = document.querySelector('#startOverlay .card');
if (!card) return;
var warn = document.createElement('p');
warn.style.cssText = 'background:#fdecea;color:#a33227;border-radius:12px;'
+ 'padding:12px;font-size:14px;text-align:left;line-height:1.5';
warn.textContent = location.protocol === 'file:'
? '⚠️ Die Seite wurde als Datei geöffnet so kann die Simulation nicht '
+ 'starten. Bitte über einen Webserver aufrufen, z. B. XAMPP starten '
+ 'und http://localhost/geograSimMac/ öffnen.'
: '⚠️ Die Simulation konnte nicht geladen werden. Bitte Seite neu laden '
+ '(Strg/Cmd+R).';
card.appendChild(warn);
}, 1500);
});
</script>
</body>
</html>