feat: Spiele-Empfehlungs-Engine mit Scoring-Algorithmus
Quality Gate / 🛡️ Lint + Type Check + Tests (push) Failing after 11m56s
Quality Gate / 🛡️ Lint + Type Check + Tests (push) Failing after 11m56s
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""Empfehlungs-Service für Brettspiele."""
|
||||
|
||||
from game_database import SPIEL
|
||||
|
||||
FACTOR_KOMPLEXITAET: float = 33.34
|
||||
FACTOR_DAUER: float = 33.33
|
||||
FACTOR_INTERAKTION: float = 33.33
|
||||
|
||||
|
||||
def score_berechnen(
|
||||
spiel: SPIEL, praeferenzen: dict[str, float]
|
||||
) -> float:
|
||||
"""Berechnet den Match-Score für ein Spiel.
|
||||
|
||||
Bewertet das Spiel nach drei Dimensionen:
|
||||
- Komplexität: je näher an Wunsch, desto besser
|
||||
- Dauer: je kuerzer unter Wunsch, desto besser
|
||||
- Interaktion (via max_spieler): je naeher an Wunsch, desto besser
|
||||
|
||||
Args:
|
||||
spiel: Das zu bewertende Spiel-Dict.
|
||||
praeferenzen: Nutzerpraefereenzen mit Schlüsseln
|
||||
'komplexitaet', 'dauer', 'interaktion'.
|
||||
|
||||
Returns:
|
||||
Score von 0 bis 100, 100 = perfekte Uebereinstimmung.
|
||||
"""
|
||||
punkte: float = 0.0
|
||||
max_punkte: float = 0.0
|
||||
|
||||
if "komplexitaet" in praeferenzen:
|
||||
wunsch = praeferenzen["komplexitaet"]
|
||||
max_punkte += FACTOR_KOMPLEXITAET
|
||||
diff = abs(spiel["komplexitaet"] - wunsch)
|
||||
punkte += FACTOR_KOMPLEXITAET * max(0.0, 1.0 - diff * 0.5)
|
||||
|
||||
if "dauer" in praeferenzen:
|
||||
wunsch = praeferenzen["dauer"]
|
||||
max_punkte += FACTOR_DAUER
|
||||
actual = spiel["dauer_min"]
|
||||
if actual <= wunsch:
|
||||
punkte += FACTOR_DAUER * (1.0 - (wunsch - actual) / max(wunsch, 1.0))
|
||||
else:
|
||||
punkte += FACTOR_DAUER * 0.15
|
||||
|
||||
if "interaktion" in praeferenzen:
|
||||
wunsch = praeferenzen["interaktion"]
|
||||
max_punkte += FACTOR_INTERAKTION
|
||||
diff = abs(spiel["max_spieler"] - wunsch)
|
||||
punkte += FACTOR_INTERAKTION * max(0.0, 1.0 - diff / 6.0)
|
||||
|
||||
if max_punkte == 0.0:
|
||||
return 0.0
|
||||
|
||||
return round(punkte / max_punkte * 100.0, 2)
|
||||
|
||||
|
||||
def empfehlungen_erstellen(
|
||||
spiele: list[SPIEL],
|
||||
praeferenzen: dict[str, float],
|
||||
limit: int = 5,
|
||||
) -> list[tuple[str, float]]:
|
||||
"""Erstellt Empfehlungen basierend auf Spielerpraefereenzen.
|
||||
|
||||
Berechnet fuer jedes Spiel einen Score und gibt die Top-N
|
||||
Spiele zurueck, sortiert nach Score absteigend.
|
||||
|
||||
Args:
|
||||
spiele: Liste aller verfügbaren Spiele.
|
||||
praeferenzen: Nutzerpraefereenzen fuer das Scoring.
|
||||
limit: Maximale Anzahl zurückgegebener Empfehlungen.
|
||||
|
||||
Returns:
|
||||
Liste von (Name, Score)-Tuples, sortiert nach Score absteigend.
|
||||
"""
|
||||
scored: list[tuple[str, float]] = []
|
||||
|
||||
for spiel in spiele:
|
||||
name: str = spiel.get("name", "Unbekannt")
|
||||
punktzahl: float = score_berechnen(spiel, praeferenzen)
|
||||
scored.append((name, punktzahl))
|
||||
|
||||
scored.sort(key=lambda entry: entry[1], reverse=True)
|
||||
return scored[:limit]
|
||||
Reference in New Issue
Block a user