U18: Risk/Reward-Abkürzungen mit Timer (Biologe/Elektriker/Cyborgs), Spinnenfrage ersetzt

This commit is contained in:
David Kertzscher 2026-07-01 14:13:47 +00:00
parent ef336090db
commit 39678a1ece
2 changed files with 351 additions and 120 deletions

243
app.py
View file

@ -1,4 +1,5 @@
import os
import time
import sqlite3
from flask import Flask, request, redirect, session
from datetime import datetime, timezone, timedelta
@ -163,6 +164,19 @@ def adventure_seite(inhalt, akzent="#f59e0b"):
.pfad:hover { border-color:ACCENT; transform:translateY(-1px); }
.pfad .exit-link { margin:0 0 6px 0; }
.pfad-hinweis { display:block; color:#94a3b8; font-size:14px; }
.deal { display:flex; flex-wrap:wrap; gap:10px; margin:14px 0 22px; }
.deal span { background:#0f172a; border:1px solid #334155; border-radius:8px;
padding:8px 12px; font-size:14px; }
.timer-wrap { margin:2px 0 18px; }
.timer { font-size:42px; font-weight:800; color:#f87171; line-height:1;
font-variant-numeric:tabular-nums; }
.timer small { font-size:16px; color:#94a3b8; font-weight:600; }
.timer-bar { height:8px; background:#0f172a; border:1px solid #334155;
border-radius:6px; overflow:hidden; margin-top:10px; }
.timer-bar > div { height:100%; background:#f87171; width:100%;
transition:width .12s linear; }
.exit-link.danger { background:#f87171; }
.exit-link.danger:hover { filter:brightness(1.08); }
.feedback-bad { background:#7f1d1d; border:1px solid #b91c1c; color:#fecaca;
border-radius:10px; padding:12px 14px; margin-bottom:16px; font-weight:600; }
.win-emoji { font-size:54px; text-align:center; margin-bottom:8px; }
@ -186,7 +200,8 @@ def adventure_seite(inhalt, akzent="#f59e0b"):
@app.route("/")
def start():
# Fortschritt für einen frischen Durchlauf zurücksetzen
for key in [k for k in session.keys() if k.startswith("raum_")]:
for key in [k for k in list(session.keys())
if k.startswith("raum_") or k.startswith("chal_")]:
session.pop(key, None)
inhalt = """
<div class="adv-card">
@ -198,10 +213,12 @@ def start():
<strong>Haien</strong> 🦈, <strong>Lasern</strong> 🔴 und natürlich
<strong>Laserhaien</strong> 🦈.</p>
<p class="adv-desc">Jede Etage ist ein Gang, der sich gabelt. <strong>Lies die
Hinweise genau!</strong> Der <strong>richtige Weg</strong> stellt dir ein paar
thematische Fragen und führt direkt eine Etage höher. Der <strong>falsche Weg</strong>
endet nach einem Haufen wirrer Trivia in einer <strong>Sackgasse</strong> dann
heißt es: umkehren! Ganz oben wartet die letzte Frage zu Präsident Business.</p>
Hinweise genau!</strong> Der <strong>sichere Prüf-Weg</strong> stellt dir ein paar
thematische Fragen und führt gemütlich eine Etage höher. Der andere Weg ist eine
<strong>riskante Abkürzung</strong>: Dort wartet jemand mit einem Deal schaffst
du seine Fragen <strong>gegen die Uhr</strong>, springst du weit nach oben. Ein
Fehler oder zu langsam? <strong>Mission vorbei.</strong> Ganz oben wartet die
letzte Frage zu Präsident Business.</p>
<a href="/app/raum/1" class="exit-link">Abenteuer starten </a>
<p class="muted">Lieber quatschen statt einbrechen?
<a href="/app/pinnwand">Zu den Kommentaren </a></p>
@ -214,6 +231,183 @@ def frage():
return redirect("/app/")
# ─── Adventure-Helfer: Sieg / Game Over / Challenge ──────────────────────────
def _clear_challenge(rid):
"""Timer- und Fortschritts-Keys einer Challenge aus der Session entfernen."""
session.pop("chal_%d_deadline" % rid, None)
session.pop("chal_%d_idx" % rid, None)
session.modified = True
def sieg_screen(text=None):
body = text or ("Du hast Präsident Business gestoppt und das Kragle gesichert. "
"Die Welt bleibt frei und kreativ!")
inhalt = ("""
<div class="adv-card" style="text-align:center">
<div class="win-emoji">🎉🧱🎉</div>
<div class="adv-floor">Mission erfüllt</div>
<h1>Befreit!</h1>
<p class="adv-desc">%s</p>
<p class="adv-frage" style="color:#f59e0b">Everything is awesome! 🎵</p>
<a href="/app/" class="exit-link">Nochmal spielen 🔁</a>
<a href="/app/pinnwand" class="ghost-link">Sieg in den Kommentaren feiern 💬</a>
</div>""" % esc(body))
return adventure_seite(inhalt)
def gameover_screen(grund):
inhalt = ("""
<div class="adv-card" style="text-align:center">
<div class="win-emoji">💥🤖💥</div>
<div class="adv-floor" style="color:#f87171">Mission gescheitert</div>
<h1>Erwischt!</h1>
<p class="adv-desc">%s</p>
<a href="/app/" class="exit-link">Nochmal von vorn </a>
<a href="/app/pinnwand" class="ghost-link">Frust in den Kommentaren lassen 💬</a>
</div>""" % esc(grund))
return adventure_seite(inhalt, akzent="#f87171")
def challenge_raum(db, r):
"""Risk/Reward-Abkürzung mit Zeitlimit (Biologe, Elektriker, Cyborgs)."""
rid = r["id"]
limit = int(r["zeit_limit"] or 40)
ziel = int(r["ziel_anzahl"] or 10)
erfolg_raum = r["erfolg_raum"] or 0
erfolg_text = r["erfolg_text"] or ""
dl_key = "chal_%d_deadline" % rid
idx_key = "chal_%d_idx" % rid
fragen = db.execute(
"SELECT * FROM fragen WHERE raum_id=? ORDER BY id", (rid,)
).fetchall()
back = db.execute(
"SELECT nach_raum FROM ausgaenge WHERE von_raum=? ORDER BY rowid LIMIT 1",
(rid,)
).fetchone()
db.close()
back_raum = back["nach_raum"] if back else 1
gesamt = min(ziel, len(fragen)) if fragen else ziel
now = time.time()
# ── Noch nicht gestartet → Intro (die Entscheidung: Risk vs. Reward) ──
if dl_key not in session:
if request.args.get("start") == "1" and fragen:
session[dl_key] = now + limit
session[idx_key] = 0
session.modified = True
return redirect("/app/raum/%d" % rid)
reward = ("🏆 Bei Erfolg: sofort gewonnen!" if not erfolg_raum
else "🏆 Bei Erfolg: Express ganz nach oben")
inhalt = ("""
<div class="adv-card">
<div class="adv-floor"> Risiko-Abkürzung · Etage %d</div>
<h1>%s</h1>
<p class="adv-desc">%s</p>
<div class="deal">
<span>🎯 %d Fragen richtig</span>
<span> %d Sekunden</span>
<span>%s</span>
<span>💀 Ein Fehler = Aus</span>
</div>
<a href="/app/raum/%d?start=1" class="exit-link danger">Herausforderung annehmen </a>
<a href="/app/raum/%d" class="ghost-link">Lieber den sicheren Prüf-Weg</a>
</div>""" % (r["etage"] or 0, esc(r["name"]), esc(r["beschreibung"]),
gesamt, limit, reward, rid, back_raum))
return adventure_seite(inhalt, akzent="#f87171")
# ── Challenge läuft ──
deadline = session.get(dl_key, 0)
idx = session.get(idx_key, 0)
# Zeit abgelaufen? (Server ist die Wahrheit; JS meldet Timeout per ?timeout=1)
if now > deadline or request.args.get("timeout") == "1":
_clear_challenge(rid)
return gameover_screen(
"⏱️ Zeit abgelaufen! Die Wachen kommen näher du musst fliehen. "
"Der riskante Weg hat dich diesmal erwischt.")
# Antwort verarbeiten
if request.method == "POST":
gewaehlt = request.form.get("antwort", "").strip()
if idx < len(fragen) and gewaehlt.lower() == fragen[idx]["antwort"].strip().lower():
idx += 1
session[idx_key] = idx
session.modified = True
if idx >= gesamt:
_clear_challenge(rid)
if erfolg_raum and erfolg_raum > 0:
inhalt = ("""
<div class="adv-card">
<div class="adv-floor"> Abkürzung geschafft!</div>
<h1>Geschafft in letzter Sekunde!</h1>
<p class="adv-desc">%s</p>
<a href="/app/raum/%d" class="exit-link">Weiter </a>
</div>""" % (esc(erfolg_text), erfolg_raum))
return adventure_seite(inhalt)
return sieg_screen(erfolg_text)
return redirect("/app/raum/%d" % rid)
# falsche Antwort → sofortiges Game Over
_clear_challenge(rid)
return gameover_screen(
"❌ Falsch! Dein Gegenüber durchschaut dich sofort und schlägt Alarm. "
"So knapp aber der riskante Weg verzeiht keinen einzigen Fehler.")
# GET → aktuelle Frage mit Countdown zeigen
if idx >= len(fragen):
_clear_challenge(rid)
return sieg_screen(erfolg_text)
aktuelle = fragen[idx]
remaining = deadline - now
buttons = ""
for opt in aktuelle["optionen"].split("|"):
buttons += ('<button class="opt-btn" name="antwort" value="%s">%s</button>'
% (esc(opt), esc(opt)))
tpl = """
<div class="adv-card">
<div class="adv-floor"> Risiko-Challenge · __NAME__</div>
<h1>__NAME__</h1>
<div class="timer-wrap">
<div class="timer"><span id="tval">__REMAIN__</span><small> s</small></div>
<div class="timer-bar"><div id="tbar"></div></div>
</div>
<p class="adv-progress">Frage __NR__ von __GES__ · schon richtig: __IDX__</p>
<p class="adv-frage">__FRAGE__</p>
<form method="post" class="opt-form">__BTN__</form>
</div>
<script>
(function(){
var end = Date.now() + __REMAINMS__;
var full = __LIMIT__;
var v = document.getElementById('tval');
var bar = document.getElementById('tbar');
function tick(){
var rem = (end - Date.now())/1000;
if(rem < 0){ rem = 0; }
v.textContent = rem.toFixed(1);
bar.style.width = Math.max(0, Math.min(100, (rem/full)*100)) + '%';
if(rem <= 0){ window.location = '/app/raum/__ID__?timeout=1'; return; }
requestAnimationFrame(tick);
}
tick();
})();
</script>"""
html = (tpl
.replace("__NAME__", esc(r["name"]))
.replace("__REMAINMS__", str(int(max(0.0, remaining) * 1000)))
.replace("__REMAIN__", "%.1f" % max(0.0, remaining))
.replace("__LIMIT__", str(limit))
.replace("__NR__", str(idx + 1))
.replace("__GES__", str(gesamt))
.replace("__IDX__", str(idx))
.replace("__FRAGE__", esc(aktuelle["frage"]))
.replace("__BTN__", buttons)
.replace("__ID__", str(rid)))
return adventure_seite(html, akzent="#f87171")
@app.route("/raum/<int:id>", methods=["GET", "POST"])
def raum(id):
db = get_db()
@ -228,8 +422,12 @@ def raum(id):
typ = r["typ"]
# ═══ Räume mit Fragen: thema (richtig) · sackgasse (falsch) · ziel (Finale) ═══
if typ in ("thema", "sackgasse", "ziel"):
# ═══ Risk/Reward-Abkürzung mit Timer (Biologe / Elektriker / Cyborgs) ═══
if typ == "challenge":
return challenge_raum(db, r)
# ═══ Räume mit Fragen: thema (Prüf-Weg) · ziel (Finale) ═══
if typ in ("thema", "ziel"):
fragen = db.execute(
"SELECT * FROM fragen WHERE raum_id=? ORDER BY id", (id,)
).fetchall()
@ -247,12 +445,8 @@ def raum(id):
session.modified = True
db.close()
return redirect("/app/raum/%d" % id)
if typ == "sackgasse":
feedback = ('<div class="feedback-bad">❌ Falsch und der '
'Prüf-Automat fragt einfach stur weiter. Nochmal!</div>')
else:
feedback = ('<div class="feedback-bad">🚨 Alarm! Falsche Antwort '
'die Wächter werden fast auf dich aufmerksam. Nochmal!</div>')
feedback = ('<div class="feedback-bad">🚨 Alarm! Falsche Antwort '
'die Wächter werden fast auf dich aufmerksam. Nochmal!</div>')
optionen = aktuelle["optionen"].split("|")
db.close()
@ -261,9 +455,7 @@ def raum(id):
buttons += ('<button class="opt-btn" name="antwort" value="%s">%s</button>'
% (esc(opt), esc(opt)))
if typ == "sackgasse":
label = "🚧 Falscher Weg · %s" % esc(r["name"])
elif typ == "ziel":
if typ == "ziel":
label = "🧱 FINALE · %s" % esc(r["name"])
else:
label = "🔐 Sicherheitsprüfung · %s" % esc(r["name"])
@ -303,25 +495,6 @@ def raum(id):
</div>""" % esc(r["beschreibung"]))
return adventure_seite(inhalt)
# SACKGASSE → "Haha, Sackgasse!" + zurück zum Gang
if typ == "sackgasse":
zurueck = ausgaenge[0] if ausgaenge else None
back_btn = (
'<a class="exit-link" href="/app/raum/%d">%s</a>'
% (zurueck["nach_raum"], esc(zurueck["richtung"]))
if zurueck else
'<a class="exit-link" href="/app/">Zurück zum Start</a>')
inhalt = ("""
<div class="adv-card">
<div class="adv-floor">🚧 Sackgasse</div>
<h1>Haha Sackgasse!</h1>
<p class="adv-desc">Du hast dich durch einen ganzen Haufen Trivia gequält
und stehst jetzt vor einer kahlen Wand. <strong>Das war der falsche Weg!</strong>
Geh zurück in den Gang und nimm die andere Richtung.</p>
%s
</div>""" % back_btn)
return adventure_seite(inhalt)
# THEMA gelöst → Erfolg + Ausgang zur nächsten Etage
weiter = ausgaenge[0] if ausgaenge else None
weiter_btn = (

View file

@ -47,8 +47,12 @@ CREATE TABLE raeume (
id INTEGER PRIMARY KEY,
name TEXT,
beschreibung TEXT,
typ TEXT, -- 'start' | 'gang' | 'thema' | 'sackgasse' | 'ziel'
etage INTEGER -- 0 = Lobby, 1..3 = Etagen, 4 = Dach
typ TEXT, -- 'start' | 'gang' | 'thema' | 'challenge' | 'ziel'
etage INTEGER, -- 0 = Lobby, 1..3 = Etagen, 4 = Dach
zeit_limit INTEGER, -- Challenge: Sekunden Zeitlimit (sonst NULL)
ziel_anzahl INTEGER, -- Challenge: so viele Fragen richtig nötig (sonst NULL)
erfolg_raum INTEGER, -- Challenge: Raum bei Erfolg (0/NULL = sofort gewonnen)
erfolg_text TEXT -- Challenge: Story-Text bei Erfolg
);
CREATE TABLE ausgaenge (
@ -76,104 +80,131 @@ raeume = [
"Wolkenkratzer von Präsident Business auf. Ganz oben, im Kragle-Tresor, "
"wartet der gefährlichste Kleber der Welt. Ein einzelner Aufzug führt nach "
"oben. Zeit, ihn zu stoppen.",
"start", 0),
"start", 0, None, None, None, None),
# ---- Etage 1: Haie (richtiger Weg = LINKS → 11, Sackgasse = RECHTS → 12) ----
# ---- Etage 1: Haie (Prüf-Weg = LINKS → 11, Abkürzung = RECHTS → 12) ----
(10, "1. Etage Der Hai-Gang 🦈",
"Der Aufzug öffnet sich. Der Gang gabelt sich in zwei Richtungen. Von "
"LINKS weht feuchte, salzige Luft herüber dort muss das riesige "
"Haibecken sein, das du überqueren musst. Von RECHTS blinkt in kaltem Rot "
"ein Schild: „Nur Personal Abstellkammer“.",
"gang", 1),
"Der Aufzug öffnet sich in einen Gang mit zwei Wegen. Nach LINKS weht "
"salzige Luft vom Haibecken herüber der offizielle Prüf-Weg über den "
"Steg. Nach RECHTS steht eine Tür einen Spalt offen; drinnen rumort "
"jemand. Vielleicht eine schnelle Abkürzung aber riskant?",
"gang", 1, None, None, None, None),
(11, "Steg über dem Haibecken 🦈",
"Du folgst der salzigen Luft. Unter dem schmalen Steg schnappen hungrige "
"Haie. Das Sicherheitssystem summt: Beweise dein Hai-Wissen, sonst fährt "
"der Steg ein!",
"thema", 1),
(12, "Die Abstellkammer 🧹",
"Du drückst die Tür auf Besen, Eimer, ein flackernder Wartungs-Bot. "
"„HALT! Sicherheits-Quiz!“, quäkt er und stellt dir eine Frage nach der "
"anderen …",
"sackgasse", 1),
"thema", 1, None, None, None, None),
(12, "Nebenraum Der Biologe 🔬",
"Statt zum Haibecken schlüpfst du durch die Tür und stehst vor einem "
"nervösen Meeresbiologen mit dickem Wälzer unterm Arm. „Du willst hoch zum "
"Kragle? Beweis mir, dass du Ahnung hast: 10 Biologie-Fragen, 40 Sekunden, "
"kein einziger Fehler. Schaffst du's, schmuggle ich dich im Proben-Container "
"ganz nach oben. Verhaust du dich, ruf ich die Wachen!“",
"challenge", 1, 40, 10, 40,
"Der Biologe grinst: „Nicht schlecht für einen Einbrecher!“ Er versteckt "
"dich im Proben-Container und der Lastenaufzug schießt ganz nach oben "
"direkt vor den Kragle-Tresor!"),
# ---- Etage 2: Laser (richtiger Weg = RECHTS → 21, Sackgasse = LINKS → 22) ----
# ---- Etage 2: Laser (Prüf-Weg = RECHTS → 21, Abkürzung = LINKS → 22) ----
(20, "2. Etage Der Laser-Gang 🔴",
"Rote Strahlen zerschneiden die Luft zu einem glühenden Gitter. LINKS "
"gähnt ein dunkler Wartungsschacht, aus dem es muffig nach Staub riecht. "
"RECHTS pulsiert Licht hinter einer Tür mit der Aufschrift "
"„Laser-Kontrollraum“.",
"gang", 2),
"Rote Strahlen zerschneiden die Luft zu einem glühenden Gitter. Nach "
"RECHTS liegt der „Laser-Kontrollraum“ der offizielle Prüf-Weg. Nach "
"LINKS, in einem engen Wartungsgang, kauert ein Elektriker zwischen "
"Kabeln und winkt dich heran. Eine Abkürzung mit Risiko?",
"gang", 2, None, None, None, None),
(21, "Der Laser-Kontrollraum 🔴",
"Im Kontrollraum flimmern hundert Regler. Wer die Laser abschalten will, "
"muss beweisen, dass er versteht, wie sie funktionieren.",
"thema", 2),
(22, "Der Wartungsschacht 🕳️",
"Eng, dunkel, staubig und natürlich eine Sackgasse. Bevor du das merkst, "
"erwacht ein alter Prüf-Automat und feuert Trivia auf dich ab …",
"sackgasse", 2),
"thema", 2, None, None, None, None),
(22, "Wartungsgang Der Elektriker ⚡",
"Im engen Wartungsgang hockt ein Elektriker in einem Nest aus Kabeln. „Die "
"Laser willst du los? Zeig mir, dass du was von Strom verstehst: 10 Fragen, "
"40 Sekunden, fehlerfrei. Dann leg ich die ganze Etage lahm und der Express "
"bringt dich zur letzten Tür. Patzt du, jagt dich der Alarm hoch!“",
"challenge", 2, 40, 10, 40,
"Der Elektriker legt einen Hebel um mit einem Zischen erlöschen alle "
"Laser. „Express für den Profi!“ Der Aufzug rast nach oben, direkt vor die "
"letzte Tür."),
# ---- Etage 3: Laserhaie (richtiger Weg = LINKS → 31, Sackgasse = RECHTS → 32) ----
# ---- Etage 3: Laserhaie (Prüf-Weg = LINKS → 31, Abkürzung = RECHTS → 32) ----
(30, "3. Etage Der Laserhai-Gang 🦈⚡",
"Absurd, aber real: Haie. Mit Lasern. Auf dem Kopf. LINKS führt ein "
"schmaler Steg direkt über das Laserhai-Becken da musst du durch. RECHTS "
"lockt ein gemütlicher Pausenraum, aus dem Kaffeeduft strömt.",
"gang", 3),
"Absurd, aber real: Haie. Mit Lasern. Auf dem Kopf. Nach LINKS führt ein "
"schmaler Steg über das Laserhai-Becken der offizielle Prüf-Weg. Nach "
"RECHTS versperren die Cyborg-Wächter von Präsident Business den Gang und "
"fordern dich heraus: Wer sie schlägt, gewinnt sofort wer patzt, ist raus.",
"gang", 3, None, None, None, None),
(31, "Steg über dem Laserhai-Becken 🦈⚡",
"Unter dir kreisen die Laserhaie und zwinkern gefährlich. Das letzte "
"Sicherheitssystem vor dem Dach will dich prüfen bleib cool!",
"thema", 3),
(32, "Der Pausenraum ☕",
"Warm, gemütlich, verlockend … und eine glasklare Falle. Der Kaffeeautomat "
"entpuppt sich als Quiz-Maschine und lässt dich nicht mehr los …",
"sackgasse", 3),
"thema", 3, None, None, None, None),
(32, "Sperrzone Die Cyborgs 🤖",
"Drei Cyborg-Wächter riegeln den Weg ab. „DENKE. WIE. EINE. MASCHINE“, "
"rattern sie im Chor. „Fünf Fragen. Zwanzig Sekunden. Antworte nicht wie "
"ein weicher Mensch, sondern wie ein Computer. Bestehst du, erkennen wir "
"dich als eine der Unseren und du hast gewonnen. Sonst: Löschung.“",
"challenge", 3, 20, 5, 0,
"Die Cyborgs synchronisieren kurz dann nicken sie im Takt: „EINE VON "
"UNS.“ Sie treten beiseite, der Weg zum Kragle ist frei. Du hast Präsident "
"Business gestoppt!"),
# ---- Dach: Ziel ----
(40, "Das Dach Der Kragle-Tresor 🏆",
"Ganz oben. Vor dir schwebt das Kragle im offenen Tresor. Nur noch eine "
"letzte Sicherung von Präsident Business steht zwischen dir und der Rettung "
"der Welt.",
"ziel", 4),
"ziel", 4, None, None, None, None),
]
db.executemany(
"INSERT INTO raeume (id, name, beschreibung, typ, etage) VALUES (?,?,?,?,?)",
"INSERT INTO raeume "
"(id, name, beschreibung, typ, etage, zeit_limit, ziel_anzahl, erfolg_raum, erfolg_text) "
"VALUES (?,?,?,?,?,?,?,?,?)",
raeume,
)
# ─── Ausgänge (mit Story-Hinweis) ────────────────────────────────────────────
# Gänge haben ZWEI Wege (richtig/falsch). Themen-Räume führen eine Etage höher,
# Sackgassen zurück zum jeweiligen Gang.
# Gänge haben ZWEI Wege: den sicheren Prüf-Weg (Themen-Raum, eine Etage höher)
# und die riskante Abkürzung (Challenge-Raum). Challenge-Räume führen per
# "Zurück" wieder in den Gang, falls man sich doch nicht traut.
ausgaenge = [
# Lobby → Etage 1
(1, "🛗 Aufzug nach oben", 10, "Der einzige Weg führt nach oben."),
# Etage 1 (richtig = LINKS → 11, falsch = RECHTS → 12)
(10, "⬅️ Nach links", 11, "🌊 Der salzigen Meeresluft zum Haibecken folgen."),
(10, "➡️ Nach rechts", 12, "🚪 Durch die Tür „Abstellkammer“."),
# Etage 1 (Prüf-Weg = LINKS → 11, Abkürzung = RECHTS → 12)
(10, "⬅️ Nach links: Steg zum Haibecken", 11,
"🦈 Der sichere Prüf-Weg: ein paar Hai-Fragen, dann weiter."),
(10, "➡️ Nach rechts: die offene Tür", 12,
"🔬 Ein Nebenraum riskante Abkürzung mit einem Biologen."),
(11, "🪜 Treppe zur 2. Etage", 20, "Der Steg hält schnell weiter nach oben!"),
(12, "↩️ Zurück in den Hai-Gang", 10, "Diese Kammer ist eine Sackgasse."),
(12, "↩️ Zurück in den Hai-Gang", 10, "Doch lieber den sicheren Prüf-Weg nehmen."),
# Etage 2 (richtig = RECHTS → 21, falsch = LINKS → 22)
(20, "⬅️ Nach links", 22, "🕳️ In den dunklen Wartungsschacht."),
(20, "➡️ Nach rechts", 21, "🔴 Zum „Laser-Kontrollraum“."),
# Etage 2 (Prüf-Weg = RECHTS → 21, Abkürzung = LINKS → 22)
(20, "⬅️ Nach links: der Wartungsgang", 22,
"⚡ Ein Elektriker bietet dir eine riskante Abkürzung an."),
(20, "➡️ Nach rechts: Laser-Kontrollraum", 21,
"🔴 Der sichere Prüf-Weg: ein paar Laser-Fragen, dann weiter."),
(21, "🪜 Treppe zur 3. Etage", 30, "Die Laser erlöschen der Weg ist frei!"),
(22, "↩️ Zurück in den Laser-Gang", 20, "Der Schacht endet im Nichts."),
(22, "↩️ Zurück in den Laser-Gang", 20, "Doch lieber den sicheren Prüf-Weg nehmen."),
# Etage 3 (richtig = LINKS → 31, falsch = RECHTS → 32)
(30, "⬅️ Nach links", 31, "🌉 Über den Steg am Laserhai-Becken."),
(30, "➡️ Nach rechts", 32, "☕ In den gemütlichen Pausenraum."),
# Etage 3 (Prüf-Weg = LINKS → 31, Abkürzung = RECHTS → 32)
(30, "⬅️ Nach links: Steg zum Laserhai-Becken", 31,
"🦈⚡ Der sichere Prüf-Weg: ein paar Laserhai-Fragen, dann aufs Dach."),
(30, "➡️ Nach rechts: die Sperrzone", 32,
"🤖 Die Cyborgs fordern dich gewinnst du, ist sofort Schluss (im Guten)."),
(31, "🏢 Aufs Dach zum Kragle-Tresor", 40, "Die Laserhaie tauchen ab nach oben!"),
(32, "↩️ Zurück in den Laserhai-Gang", 30, "Der Pausenraum war eine Falle."),
(32, "↩️ Zurück in den Laserhai-Gang", 30, "Doch lieber den sicheren Prüf-Weg nehmen."),
]
db.executemany(
"INSERT INTO ausgaenge (von_raum, richtung, nach_raum, hinweis) VALUES (?,?,?,?)",
ausgaenge,
)
# ─── Trivia-Fragen pro Etage ─────────────────────────────────────────────────
# Pro Etage 4 Fragen: 12 thematisch passend, danach Popkultur.
# "antwort" ist die korrekte Option, "optionen" alle Auswahlmöglichkeiten (|-getrennt).
# ─── Fragen ──────────────────────────────────────────────────────────────────
# Themen-Räume (11/21/31): wenige PASSENDE Fragen der sichere Prüf-Weg.
# Challenge-Räume (12/22/32): eigene Fragenbank für die Risk/Reward-Abkürzung
# Biologe (10), Elektriker (10), Cyborgs (5, „denk wie eine Maschine“).
# Ziel-Raum (40): die finale Lord-Business-Frage.
fragen = [
# ── Etage 1 · RICHTIG: Hai-Fragen (Raum 11) ──────────────────
# ── Etage 1 · Prüf-Weg: Hai-Fragen (Raum 11) ─────────────────
(11, "🦈 Welcher Hai ist der größte Fisch der Welt?",
"Walhai", "Weißer Hai|Walhai|Hammerhai"),
(11, "🦈 Wie heißt Steven Spielbergs berühmter Hai-Film von 1975?",
@ -181,17 +212,29 @@ fragen = [
(11, "🦈 Womit atmen Haie unter Wasser?",
"Kiemen", "Lungen|Kiemen|Schwimmflossen"),
# ── Etage 1 · FALSCH: themenfremde Trivia (Raum 12) ──────────
(12, "🎮 Wie heißt Marios grün gekleideter Bruder?",
"Luigi", "Luigi|Wario|Yoshi"),
(12, "🎬 In welcher Weltraum-Saga kämpfen Jedi gegen Sith?",
"Star Wars", "Star Trek|Star Wars|Herr der Ringe"),
(12, "📱 Welches Unternehmen stellt das iPhone her?",
"Apple", "Microsoft|Apple|Samsung"),
(12, "⏰ Wie viele Minuten hat eine Stunde?",
"60", "24|60|100"),
# ── Etage 1 · Abkürzung: BIOLOGE 10 Biologie-Fragen (Raum 12) ──
(12, "🫀 Welches Organ pumpt das Blut durch den Körper?",
"Herz", "Herz|Leber|Lunge"),
(12, "🌿 Welcher Farbstoff macht Pflanzen grün?",
"Chlorophyll", "Chlorophyll|Hämoglobin|Melanin"),
(12, "🐝 Wie viele Beine hat ein Insekt?",
"6", "4|6|8"),
(12, "🫁 Welches Gas atmen Menschen zum Leben ein?",
"Sauerstoff", "Sauerstoff|Kohlendioxid|Helium"),
(12, "🔬 Wie heißt die kleinste lebende Einheit?",
"Zelle", "Zelle|Atom|Molekül"),
(12, "🐬 Welches dieser Tiere ist ein Säugetier?",
"Delfin", "Delfin|Hai|Krokodil"),
(12, "🍃 Wo findet die Fotosynthese hauptsächlich statt?",
"Blatt", "Blatt|Wurzel|Blüte"),
(12, "❤️ Wie viele Kammern hat das menschliche Herz?",
"4", "2|3|4"),
(12, "☀️ Welches Vitamin bildet der Körper mithilfe von Sonnenlicht?",
"Vitamin D", "Vitamin C|Vitamin D|Vitamin B12"),
(12, "🩸 Wie heißt der rote Blutfarbstoff?",
"Hämoglobin", "Hämoglobin|Chlorophyll|Keratin"),
# ── Etage 2 · RICHTIG: Laser-Fragen (Raum 21) ────────────────
# ── Etage 2 · Prüf-Weg: Laser-Fragen (Raum 21) ───────────────
(21, "🔴 Wofür steht das Akronym LASER?",
"Light Amplification by Stimulated Emission of Radiation",
"Light Amplification by Stimulated Emission of Radiation|"
@ -202,17 +245,29 @@ fragen = [
(21, "🌈 Welche Farbe hat ein klassischer Laserpointer meistens?",
"Rot", "Rot|Lila|Schwarz"),
# ── Etage 2 · FALSCH: themenfremde Trivia (Raum 22) ──────────
(22, "🦸 Welcher Superheld trägt ein blaues Kostüm mit rotem Umhang und „S“?",
"Superman", "Batman|Superman|Spider-Man"),
(22, "🎮 In welchem Spiel fängt man Kreaturen in kleinen Bällen?",
"Pokémon", "Minecraft|Tetris|Pokémon"),
(22, "🗼 Wie heißt die Hauptstadt von Frankreich?",
"Paris", "Paris|Rom|Madrid"),
(22, "🐶 Welches Tier bellt?",
"Hund", "Katze|Hund|Kuh"),
# ── Etage 2 · Abkürzung: ELEKTRIKER 10 Elektrik-Fragen (Raum 22) ──
(22, "⚡ In welcher Einheit misst man die elektrische Spannung?",
"Volt", "Volt|Watt|Ampere"),
(22, "🔌 In welcher Einheit misst man die Stromstärke?",
"Ampere", "Ampere|Ohm|Volt"),
(22, "🧲 Was misst man in der Einheit Ohm?",
"Widerstand", "Leistung|Widerstand|Spannung"),
(22, "🪙 Welches Material leitet Strom besonders gut?",
"Kupfer", "Kupfer|Gummi|Holz"),
(22, "🔁 Ein Stromkreis, durch den Strom fließt, ist …?",
"geschlossen", "geschlossen|offen|leer"),
(22, "📐 Wie lautet das Ohmsche Gesetz?",
"U = R · I", "U = R · I|U = R + I|U = R I"),
(22, "🟢 Welche Farbe hat der Schutzleiter (Erde) meist?",
"Grün-Gelb", "Grün-Gelb|Blau|Braun"),
(22, "🚿 Womit sollte man NIEMALS an eine Steckdose fassen?",
"Mit nassen Händen", "Mit nassen Händen|Mit einer Zange|Mit einem Messgerät"),
(22, "🏭 Was erzeugt ein Kraftwerk vor allem?",
"Elektrische Energie", "Elektrische Energie|Trinkwasser|Benzin"),
(22, "🔋 Welches Bauteil speichert elektrische Ladung?",
"Kondensator", "Kondensator|Widerstand|Transistor"),
# ── Etage 3 · RICHTIG: Laserhai-Fragen (Raum 31) ─────────────
# ── Etage 3 · Prüf-Weg: Laserhai-Fragen (Raum 31) ────────────
(31, "🦈⚡ In welchem Film wünscht sich Dr. Evil „Haie mit Laserstrahlen auf dem Kopf“?",
"Austin Powers", "James Bond|Austin Powers|Men in Black"),
(31, "🧬 Woraus setzt sich ein „Laserhai“ zusammen?",
@ -220,15 +275,18 @@ fragen = [
(31, "😉 Wenn ein Laserhai gefährlich zwinkert was schießt aus seinen Augen?",
"Laserstrahlen", "Wasser|Laserstrahlen|Konfetti"),
# ── Etage 3 · FALSCH: themenfremde Trivia (Raum 32) ──────────
(32, "🦖 In welchem Film-Franchise werden Dinosaurier in einem Park geklont?",
"Jurassic Park", "Jurassic Park|King Kong|Godzilla"),
(32, "🕷️ Wie viele Beine hat eine Spinne?",
"8", "6|8|10"),
(32, "🎨 Welche Farbe entsteht aus Blau und Gelb?",
"Grün", "Grün|Lila|Orange"),
(32, "🎮 Aus welchem Land kommt der Spielehersteller Nintendo?",
"Japan", "USA|Japan|Deutschland"),
# ── Etage 3 · Abkürzung: CYBORGS 5 Maschinen-Logik-Fragen (Raum 32) ──
# „Antworte wie eine Maschine nicht unbedingt logisch für Menschen.“
(32, "🤖 1 + 1 = ? (denke binär, wie ein Computer)",
"10", "2|10|11"),
(32, "🤖 WAHR UND FALSCH ergibt … (Boolesche Logik)?",
"Falsch", "Wahr|Falsch|Vielleicht"),
(32, "🤖 Bei welcher Zahl beginnt ein Computer zu zählen?",
"0", "0|1|-1"),
(32, "🤖 Wie viele Bits hat ein Byte?",
"8", "4|8|16"),
(32, "🤖 0,1 + 0,2 ergibt für einen Computer ungefähr …?",
"0,30000000000000004", "0,3|0,30000000000000004|0,03"),
# ── Dach · ZIEL: finale Lord-Business-Frage (Raum 40) ────────
(40, "🧱 FINALE: Wie heißt der Bösewicht, in dessen Turm du gerade eingebrochen bist?",