85 lines
2.6 KiB
Python
85 lines
2.6 KiB
Python
"""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]
|