from flask import Flask, request, session, redirect
import sqlite3
from datetime import datetime
app = Flask(__name__)
app.secret_key = "sneaky-snakes-snacken-snacks"
def get_db():
db = sqlite3.connect("adventure.db")
db.row_factory = sqlite3.Row
return db
def layout(content):
return f"""
{content}
"""
def ensure_columns():
db = get_db()
db.execute("""
CREATE TABLE IF NOT EXISTS highscore (
id INTEGER PRIMARY KEY AUTOINCREMENT,
spieler TEXT NOT NULL,
sekunden REAL NOT NULL,
gewonnen_am TEXT NOT NULL
)
""")
try:
db.execute("ALTER TABLE spielstand ADD COLUMN startzeit TEXT")
except sqlite3.OperationalError:
pass
try:
db.execute("ALTER TABLE spielstand ADD COLUMN fertig INTEGER DEFAULT 0")
except sqlite3.OperationalError:
pass
db.commit()
db.close()
ensure_columns()
@app.route("/", methods=["GET", "POST"])
def start():
if request.method == "POST":
name = request.form["name"].strip()
if name != "":
session["spieler"] = name
session["startzeit"] = datetime.utcnow().isoformat()
db = get_db()
row = db.execute(
"SELECT spieler FROM spielstand WHERE spieler=?",
(name,)
).fetchone()
if row:
db.execute(
"UPDATE spielstand SET raum_id=1, startzeit=?, fertig=0 WHERE spieler=?",
(session["startzeit"], name)
)
else:
db.execute(
"INSERT INTO spielstand (spieler, raum_id, startzeit, fertig) VALUES (?, 1, ?, 0)",
(name, session["startzeit"])
)
db.commit()
db.close()
return redirect("/app/raum/1")
db = get_db()
anzahl = db.execute("SELECT COUNT(*) AS n FROM spielstand").fetchone()["n"]
highscores = db.execute(
"SELECT spieler, sekunden, gewonnen_am FROM highscore ORDER BY sekunden ASC, gewonnen_am ASC LIMIT 10"
).fetchall()
db.close()
html = "Verlies
"
html += f"{anzahl} Abenteurer waren schon hier.
"
if "spieler" in session:
db = get_db()
s = db.execute(
"SELECT raum_id FROM spielstand WHERE spieler=?",
(session["spieler"],)
).fetchone()
db.close()
if s:
html += f"Willkommen zurück, {session['spieler']}!
"
html += f'Weiterspielen'
html += 'Neues Abenteuer'
html += """
"""
html += "Highscore
"
if highscores:
html += "
"
for hs in highscores:
minuten = int(hs["sekunden"] // 60)
sekunden = int(hs["sekunden"] % 60)
zeit = f"{minuten}m {sekunden}s" if minuten else f"{sekunden}s"
html += f"- {hs['spieler']} — {zeit}
"
html += "
"
else:
html += "
Noch kein Schatz gefunden.
"
html += "
"
return layout(html)
@app.route("/raum/", methods=["GET", "POST"])
def raum(id):
db = get_db()
if "spieler" in session:
db.execute(
"UPDATE spielstand SET raum_id=? WHERE spieler=?",
(id, session["spieler"])
)
db.commit()
r = db.execute("SELECT * FROM raeume WHERE id=?", (id,)).fetchone()
if r["raetsel_frage"]:
if request.method == "POST":
if request.form["antwort"].strip() == r["raetsel_antwort"]:
now = datetime.utcnow()
startzeit_str = session.get("startzeit")
if not startzeit_str:
row = db.execute(
"SELECT startzeit FROM spielstand WHERE spieler=?",
(session["spieler"],)
).fetchone()
startzeit_str = row["startzeit"] if row else None
if startzeit_str and "spieler" in session:
startzeit = datetime.fromisoformat(startzeit_str)
sekunden = (now - startzeit).total_seconds()
bereits = db.execute(
"SELECT 1 FROM highscore WHERE spieler=? AND gewonnen_am=?",
(session["spieler"], now.date().isoformat())
).fetchone()
db.execute(
"INSERT INTO highscore (spieler, sekunden, gewonnen_am) VALUES (?, ?, ?)",
(session["spieler"], sekunden, now.date().isoformat())
)
db.execute(
"UPDATE spielstand SET fertig=1 WHERE spieler=?",
(session["spieler"],)
)
db.commit()
db.close()
return layout("""
Du findest einen Schatz
Herzlichen Glückwunsch. Du hast das Verlies überlebt.
Zurück zum Anfang
""")
db.close()
return layout(f"""
Leider falsch
Die Antwort war nicht richtig.
Nochmal
""")
db.close()
return layout(f"""
{r["name"]}
{r["beschreibung"]}
""")
ausgaenge = db.execute(
"SELECT richtung, nach_raum FROM ausgaenge WHERE von_raum=?",
(id,)
).fetchall()
db.close()
exits_html = ""
for a in ausgaenge:
exits_html += f'{a["richtung"]}'
spieler_html = ""
if "spieler" in session:
spieler_html = f'Unterwegs als: {session["spieler"]}
'
html = f"""
{r["name"]}
{r["beschreibung"]}
{spieler_html}
{exits_html}
"""
return layout(html)
@app.route("/reset")
def reset():
session.pop("spieler", None)
session.pop("startzeit", None)
return redirect("/app/")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=9008)