From db0a9b88fdfc1a24207ffbee8b760380a71f7112 Mon Sep 17 00:00:00 2001 From: idriz Date: Fri, 4 Sep 2026 11:57:43 +0200 Subject: [PATCH] Dodaj igru Superheroji (glasovna) + admin tab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Igra: 1-5 igrača, nekoliko rundi (konfigurabilno). Svaku rundu svaki igrač kaže izmišljenog lika (širok pojam — bilo koji medij), Idriz presudi ko bi pobijedio i zašto. Pobjednik runde se banuje do kraja partije. Redoslijed se rotira svaku rundu (zadnji ima prednost). Najviše pobjeda runda = pobjednik partije. - idriz/gamestore.py: trajno skladište (heroji, Elo rejting, broj rundi), bez vanjskih zavisnosti (i admin ga uvozi). clear_favorite() drži borbe dosljedne kroz partije (jači heroj ne gubi od znatno slabijeg). - idriz/game.py: resolve_hero (najjači LLM gpt-5.5 + web search fallback samo kad ne zna lika), adjudicate (presuda + obrazloženje na bosanskom), Match (tok partije). - assistant.py: 4 realtime alata (nova_partija, izbor, presudi, kraj) + upute; igra ide odmah nazad modelu, ne kroz pozadinski posao. - config.py: game_model (default = text_model). - admin: tab "Superheroji" (broj rundi + rang-lista + reset pamćenja). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01LzKpYaEsuWDevuNnvSjcFW --- README.md | 15 ++ admin/app.py | 37 ++++ admin/templates/base.html | 3 + admin/templates/superheroji.html | 66 +++++++ idriz/assistant.py | 142 ++++++++++++++- idriz/config.py | 4 + idriz/game.py | 290 +++++++++++++++++++++++++++++++ idriz/gamestore.py | 175 +++++++++++++++++++ 8 files changed, 731 insertions(+), 1 deletion(-) create mode 100644 admin/templates/superheroji.html create mode 100644 idriz/game.py create mode 100644 idriz/gamestore.py diff --git a/README.md b/README.md index e1f8429..0b56123 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,18 @@ Odštampani PDF-ovi ostaju u `~/.local/share/idriz/out/`. ``` IDRIZ_DRY_RUN=1 .venv/bin/python scripts/test_summary.py "Volcano" "8 godina" ``` + +## Igra "Superheroji" + +Glasovna igra (bez štampanja). Tok: Idriz pita koliko igrača (1–5) i imena, pa se +igra nekoliko rundi. Svaku rundu svaki igrač kaže jednog izmišljenog lika (bilo koji +medij — Supermen, Mario, La Linea, Mad Max...), a Idriz presudi ko bi pobijedio i +zašto. Pobjednik runde se više ne može birati do kraja partije. Sistem pamti +relativne jačine likova (Elo) u `~/.local/share/idriz/heroes.json` da borbe budu +dosljedne kroz partije. Za prepoznavanje likova koristi se najjači tekstualni model +(`game_model`, default `gpt-5.5`) i njegovo znanje; web search (Responses API) samo +kad model ne zna lika. + +- `idriz/gamestore.py` — trajno skladište (heroji, Elo, broj rundi), bez vanjskih zavisnosti. +- `idriz/game.py` — prepoznavanje likova, presuđivanje, tok partije (`Match`). +- Broj rundi i rang-lista heroja se podešavaju u admin panelu (tab "Superheroji"). diff --git a/admin/app.py b/admin/app.py index d2adb55..3d64c35 100644 --- a/admin/app.py +++ b/admin/app.py @@ -7,14 +7,20 @@ Prijava ide preko PAM-a (Linux korisnik `idriz`). import os import secrets import subprocess +import sys from datetime import datetime from functools import wraps +from pathlib import Path import pam as pam_module from flask import ( Flask, render_template, request, redirect, url_for, session, flash ) +# Pristup skladištu igre (bez openai zavisnosti) iz glavnog idriz paketa. +sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) +from idriz import gamestore # noqa: E402 + # --- Konfiguracija ----------------------------------------------------------- # Samo ovaj Linux korisnik smije da se prijavi. @@ -195,6 +201,37 @@ def status(): ) +@app.route("/superheroji", methods=["GET", "POST"]) +@login_required +def superheroji(): + if request.method == "POST": + action = request.form.get("action") + if action == "rounds": + try: + n = int(request.form.get("rounds", "")) + saved = gamestore.save_rounds(n) + flash(f"Broj rundi postavljen na {saved}.") + except (ValueError, TypeError): + flash("Neispravan broj rundi.") + elif action == "reset": + store = gamestore.HeroStore() + store.heroes = {} + store.aliases = {} + store.save() + flash("Pamćenje jačina heroja je obrisano.") + return redirect(url_for("superheroji")) + + store = gamestore.HeroStore() + return render_template( + "superheroji.html", + rounds=gamestore.load_rounds(), + min_rounds=gamestore.MIN_ROUNDS, + max_rounds=gamestore.MAX_ROUNDS, + heroes=store.leaderboard(), + active_page="superheroji", + ) + + if __name__ == "__main__": from waitress import serve print(f"Idriz admin na http://{LISTEN_HOST}:{LISTEN_PORT}") diff --git a/admin/templates/base.html b/admin/templates/base.html index 0a27a15..f17ec47 100644 --- a/admin/templates/base.html +++ b/admin/templates/base.html @@ -98,6 +98,9 @@ ● Status servisa + + ★ Superheroji +