351 lines
18 KiB
Python
351 lines
18 KiB
Python
"""
|
||
U18 – Klick-Adventure "Einbruch im Octan-Tower" (The-Lego-Movie-Style)
|
||
=====================================================================
|
||
Legt die SQLite-Datenbank `adventure.db` an und befüllt sie mit einem
|
||
verzweigten Verlies:
|
||
|
||
- raeume : Räume/Gänge des Octan-Towers (mit Typ: start/gang/thema/
|
||
sackgasse/ziel)
|
||
- ausgaenge : welcher Weg (links/rechts/…) führt in welchen Raum – inkl.
|
||
Story-Hinweis für die Entscheidung
|
||
- fragen : Fragen pro Raum
|
||
• Themen-Räume → thematische Fragen (der RICHTIGE Weg)
|
||
• Sackgassen → themenfremde Trivia (der FALSCHE Weg)
|
||
• Ziel-Raum → die finale Lord-Business-Frage
|
||
|
||
Spielprinzip
|
||
------------
|
||
Jede Etage ist ein Gang, der sich gabelt. Nach den Text-Hinweisen entscheidet
|
||
man sich für links oder rechts:
|
||
• RICHTIGER Weg → wenige thematische Fragen → direkt eine Etage höher.
|
||
• FALSCHER Weg → viele themenfremde Trivia → "Haha, Sackgasse!" → zurück
|
||
zum Gang, dann den richtigen Weg nehmen.
|
||
Ganz oben wartet der Kragle-Tresor mit der finalen Lord-Business-Frage.
|
||
|
||
Leitprinzip (wie in U17):
|
||
LOKAL schreiben & pushen – auf dem SERVER einmalig ausführen:
|
||
python3 init_db.py
|
||
Danach entsteht adventure.db direkt neben diesem Skript.
|
||
"""
|
||
import os
|
||
import sqlite3
|
||
|
||
# adventure.db immer neben dieser Datei ablegen (unabhängig vom Arbeitsverzeichnis)
|
||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
DB_PATH = os.path.join(BASE_DIR, "adventure.db")
|
||
|
||
db = sqlite3.connect(DB_PATH)
|
||
|
||
# Tabellen bei jedem Lauf sauber neu aufbauen (DROP statt DELETE, damit auch
|
||
# geänderte Spalten greifen).
|
||
db.executescript("""
|
||
DROP TABLE IF EXISTS raeume;
|
||
DROP TABLE IF EXISTS ausgaenge;
|
||
DROP TABLE IF EXISTS fragen;
|
||
|
||
CREATE TABLE raeume (
|
||
id INTEGER PRIMARY KEY,
|
||
name TEXT,
|
||
beschreibung TEXT,
|
||
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 (
|
||
von_raum INTEGER,
|
||
richtung TEXT, -- kurzer Button-Text, z. B. "⬅️ Nach links"
|
||
nach_raum INTEGER,
|
||
hinweis TEXT -- Story-Hinweis unter dem Button
|
||
);
|
||
|
||
CREATE TABLE fragen (
|
||
id INTEGER PRIMARY KEY,
|
||
raum_id INTEGER,
|
||
frage TEXT,
|
||
antwort TEXT,
|
||
optionen TEXT -- Antwortmöglichkeiten, per | getrennt
|
||
);
|
||
""")
|
||
|
||
# ─── Persistente Tabellen (U19) ──────────────────────────────────────────────
|
||
# Bewusst OHNE DROP und mit IF NOT EXISTS: Wenn init_db.py erneut läuft (z. B.
|
||
# nach neuen Räumen), werden Räume/Ausgänge/Fragen neu aufgebaut – aber alle
|
||
# Spielstände, Bestzeiten und Inventare BLEIBEN erhalten.
|
||
db.executescript("""
|
||
CREATE TABLE IF NOT EXISTS spielstand (
|
||
spieler TEXT PRIMARY KEY, -- jeder Name kommt genau einmal vor
|
||
raum_id INTEGER, -- zuletzt besuchter Raum
|
||
start_zeit REAL, -- Start des aktuellen Laufs (time.time())
|
||
fertig_zeit REAL -- Zeitpunkt des Sieges (NULL solange offen)
|
||
);
|
||
|
||
CREATE TABLE IF NOT EXISTS laeufe (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
spieler TEXT,
|
||
start_zeit REAL,
|
||
fertig_zeit REAL,
|
||
dauer REAL, -- Gesamtdauer in Sekunden
|
||
status TEXT -- 'gewonnen' | 'gescheitert'
|
||
);
|
||
|
||
CREATE TABLE IF NOT EXISTS stage_zeiten (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
spieler TEXT,
|
||
stage TEXT, -- z. B. 'Hai-Fragen (Prüf-Weg)'
|
||
dauer REAL, -- Dauer dieses Einzelabschnitts
|
||
zeit REAL -- Zeitpunkt der Eintragung
|
||
);
|
||
|
||
CREATE TABLE IF NOT EXISTS inventar (
|
||
spieler TEXT,
|
||
gegenstand TEXT -- Item-ID, z. B. 'laserhai_key'
|
||
);
|
||
""")
|
||
|
||
# Falls eine ältere spielstand-Tabelle bereits existiert (z. B. nur mit
|
||
# spieler/raum_id), fehlende U19-Spalten nachziehen statt Daten zu verlieren.
|
||
cols = {r[1] for r in db.execute("PRAGMA table_info(spielstand)").fetchall()}
|
||
if "start_zeit" not in cols:
|
||
db.execute("ALTER TABLE spielstand ADD COLUMN start_zeit REAL")
|
||
if "fertig_zeit" not in cols:
|
||
db.execute("ALTER TABLE spielstand ADD COLUMN fertig_zeit REAL")
|
||
|
||
|
||
# ─── Räume ───────────────────────────────────────────────────────────────────
|
||
# IDs bewusst gruppiert: 1 = Lobby, 10er = Etage 1, 20er = Etage 2, 30er = Etage 3.
|
||
raeume = [
|
||
# ---- Start ----
|
||
(1, "Lobby des Octan-Towers",
|
||
"Die gläsernen Türen fallen hinter dir zu – kein Zurück. Über dir ragt der "
|
||
"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, None, None, None, None),
|
||
|
||
# ---- Etage 1: Haie (Prüf-Weg = LINKS → 11, Abkürzung = RECHTS → 12) ----
|
||
(10, "1. Etage – Der Hai-Gang 🦈",
|
||
"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, 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 (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. 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, 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 (Prüf-Weg = LINKS → 31, Abkürzung = RECHTS → 32) ----
|
||
(30, "3. Etage – Der Laserhai-Gang 🦈⚡",
|
||
"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, 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, None, None, None, None),
|
||
]
|
||
db.executemany(
|
||
"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: 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 (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, "Doch lieber den sicheren Prüf-Weg nehmen."),
|
||
|
||
# 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, "Doch lieber den sicheren Prüf-Weg nehmen."),
|
||
|
||
# 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, "Doch lieber den sicheren Prüf-Weg nehmen."),
|
||
]
|
||
db.executemany(
|
||
"INSERT INTO ausgaenge (von_raum, richtung, nach_raum, hinweis) VALUES (?,?,?,?)",
|
||
ausgaenge,
|
||
)
|
||
|
||
# ─── 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 · 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?",
|
||
"Der weiße Hai", "Der weiße Hai|Free Willy|Findet Nemo"),
|
||
(11, "🦈 Womit atmen Haie unter Wasser?",
|
||
"Kiemen", "Lungen|Kiemen|Schwimmflossen"),
|
||
|
||
# ── 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 · 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|"
|
||
"Large Automatic System for Energy Reflection|"
|
||
"Leuchtende Aktive Strahlen-Emissions-Röhre"),
|
||
(21, "⚔️ Welche leuchtende Laser-Waffe führt ein Jedi in Star Wars?",
|
||
"Lichtschwert", "Lichtschwert|Laserpistole|Zauberstab"),
|
||
(21, "🌈 Welche Farbe hat ein klassischer Laserpointer meistens?",
|
||
"Rot", "Rot|Lila|Schwarz"),
|
||
|
||
# ── 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 Gummihandschuhen|Mit einem isolierten Schraubendreher"),
|
||
(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 · 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?",
|
||
"Hai und Laser", "Hai und Laser|Katze und Hund|Auto und Boot"),
|
||
(31, "😉 Wenn ein Laserhai gefährlich zwinkert – was schießt aus seinen Augen?",
|
||
"Laserstrahlen", "Wasser|Laserstrahlen|Konfetti"),
|
||
|
||
# ── 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?",
|
||
"Lord Business", "Lord Business|Lord Vader|Lord Farquaad"),
|
||
]
|
||
db.executemany(
|
||
"INSERT INTO fragen (raum_id, frage, antwort, optionen) VALUES (?,?,?,?)",
|
||
fragen,
|
||
)
|
||
|
||
db.commit()
|
||
db.close()
|
||
|
||
print("Datenbank adventure.db angelegt:", DB_PATH)
|
||
print(" Räume:", len(raeume),
|
||
"| Ausgänge:", len(ausgaenge),
|
||
"| Fragen:", len(fragen))
|
||
print(" Persistente Tabellen: spielstand, laeufe, stage_zeiten, inventar (erhalten)")
|