Euer Adventure merkt sich euch. Bisher hat die App nur aus der Datenbank gelesen — jetzt schreibt sie hinein: Über ein Formular gebt ihr euren Namen ein, die App speichert per INSERT und UPDATE euren Spielstand. App-Neustart? Ihr macht genau dort weiter, wo ihr wart.
Voraussetzungen: u18 abgeschlossen — euer Klick-Adventure läuft, das Rätsel (6.3) hat schon ein erstes POST-Formular. Genau das bauen wir jetzt systematisch aus. Es muss nichts installiert werden.
1. In den App-Ordner wechseln:
2. Virtuelle Umgebung aktivieren (danach steht (venv) vorne):
3. App starten:
Dann im Browser https://isa##.edumake.de/app/ aufrufen (Hard Reload Strg/Cmd + Shift + R): Kommt ihr von der Startseite bis ins Rätsel?
(venv) vorne? Seid ihr im Ordner ~/public_html/app? Liegt adventure.db da (ls)? Falls nicht: python3 init_db.py. Im Browser Hard Reload gemacht?
spielstand ergänzenspielstand anlegen (init_db.py)spielstand merkt sich pro Spieler, in welchem Raum er zuletzt war. spieler ist der Primärschlüssel — jeder Name kommt genau einmal vor.
init_db.py ergänzenÖffnet init_db.py in VS Code und fügt innerhalb von db.executescript("""…""") — am besten direkt nach den CREATE TABLE-Blöcken — diesen Block ein:
Datei speichern (Strg/Cmd + S).
spielstand gibt es kein DROP und kein DELETE. Wenn ihr später neue Räume einbaut und init_db.py erneut lauft, werden die Räume neu aufgebaut — die Spielstände bleiben erhalten.
init_db.py committeninit_db.py → Stage → Commit (Tabelle spielstand) → Sync.
Auf git.md-phw.de: Ist die neue Tabelle in init_db.py zu sehen? (Datei anklicken → Inhalt prüfen)
Ihr kennt die Reihenfolge aus u18 — App zuerst stoppen, sonst ist die Datenbank gesperrt:
1. Laufende App beenden:
2. Neuen Stand holen (kommt init_db.py geändert an?):
3. venv aktivieren (falls nötig) und Skript ausführen:
Kontrolle: Gibt es die neue Tabelle wirklich? Einmal kurz nachsehen:
method="post" schickt Daten an die App — dort landen sie in request.form. Und damit die App sich merkt, wer ihr seid, nutzen wir session (ein Cookie im Browser).
app.py: Import-Zeile und Startroute ersetzen1. Die erste Zeile und den Kopf der App erweitern — session braucht einen secret_key (eigenen Fantasietext wählen):
2. Die Startroute (@app.route("/") samt Funktion) komplett ersetzen:
Stage → Commit (Startseite mit Formular) → Sync.
request.form["name"] — was im Eingabefeld <input name="name"> stand.session["spieler"] — die App merkt sich euren Namen (Cookie), bis der Browser ihn vergisst.INSERT OR IGNORE — legt den Spieler an; gibt es ihn schon (gleicher Name = Primärschlüssel), passiert nichts — sein Spielstand bleibt.action — es schickt an dieselbe Adresse. Der /app/-Trick aus u18 funktioniert so einfach weiter.
Im Browser https://isa##.edumake.de/app/ (Hard Reload): Namen eingeben → Abenteuer starten → ihr landet in der Eingangshalle. Der INSERT ist passiert — sehen werdet ihr ihn im nächsten Schritt.
app.py: zwei kleine Ergänzungen1. In der Funktion raum(id) — direkt nach db = get_db() — den Spielstand fortschreiben:
2. In der Startroute start() die letzte return-Zeile durch diesen Block ersetzen — wer schon einen Spielstand hat, bekommt einen Weiterspielen-Link:
Stage → Commit (Spielstand speichern) → Sync.
Strg + C → git pull → python3 app.pyStrg + C) und wieder starten (python3 app.py)request.form → INSERT/UPDATE → Datenbank. Genau dieses Muster steckt hinter Logins, Warenkörben, Gästebüchern — hinter fast jeder echten Webanwendung.
? statt Zusammenkleben? Alles, was aus request.form kommt, hat ein Mensch getippt — auch Böswilliges. Mit WHERE spieler=? setzt SQLite den Wert sicher ein. SQL selbst zusammenzukleben ("…" + name + "…") öffnet die Tür für SQL-Injection. Merksatz: Nutzereingaben nie in SQL kleben — immer ?.
Wie immer gilt auf dem Server die Reihenfolge aus u18: App stoppen → git pull → (nur bei geändertem init_db.py: python3 init_db.py) → App starten.
Zeigt in jedem Raum an, wer gerade unterwegs ist. In raum(id) beim Zusammenbauen des HTML:
Die Startseite zeigt, wie viele Abenteurer es schon gibt — eure erste COUNT-Abfrage:
Wo genau der Code hin muss, überlegt ihr selbst: Er braucht eine offene DB-Verbindung (db = get_db() … db.close()).
Ein Link/Button „Neues Abenteuer“ meldet den Spieler ab. Neue Route:
Link auf der Startseite: <a href="/app/reset">Neues Abenteuer</a>. Was passiert, wenn sich derselbe Name danach wieder anmeldet — und warum? (Tipp: INSERT OR IGNORE)
Jetzt habt ihr alles dafür zusammen (in u18 war das noch Zukunftsmusik):
spielstand um zwei Spalten erweitern: start_zeit REAL, fertig_zeit REAL.INSERT die Startzeit mitgeben (import time → time.time()), im Zielraum („Befreit!“) die fertig_zeit per UPDATE setzen./highscore:inventar (spieler TEXT, gegenstand TEXT) — in der Bibliothek liegt ein Schlüssel (INSERT beim Betreten).SELECT prüfen, sonst Hinweis anzeigen).INSERT und SELECT.Gestaltet auch das Formular modern & minimalistisch (passend zu eurem Stil aus u18): dunkle Fläche, Eingabefeld und Button mit abgerundeten Ecken, dezenter Akzent. Mini-Start: