Files
tft/.planer/einheiten/backend__tft__sim__game.py.md
2026-07-24 11:24:24 +02:00

72 lines
4.0 KiB
Markdown

# Einheiten: backend/tft/sim/game.py
stand: f41ac76b5789
## backend/tft/sim/game.py::pair_players
beschreibung: Ermittelt die PvP-Paarungen der lebenden Spieler und einen eventuellen Ghost-Gegner unter Vermeidung von Wiederholungsgegnern.
input: Liste lebender PlayerState und ein random.Random
output: Tupel aus Paaren, einem möglichen odd-Spieler und einem möglichen Ghost-Spieler
entscheidungen:
- Es werden bis zu 20 Shuffle-Versuche unternommen, um eine kollisionsfreie Paarung zu finden.
beleg: "for _ in range(20):"
- Wiederholungsgegner werden bei mehr als zwei Lebenden explizit ausgeschlossen.
beleg: "all(a.last_opponent != b.name for a, b in pairs)"
- Bei ungerader Spielerzahl wird ein Spieler als Ghost gegen einen zufälligen anderen gespiegelt.
beleg: "ghost_src = rng.choice([p for p in alive if p is not odd]) if odd else None"
- Die Paarungsinformation wird über last_opponent beidseitig festgehalten.
beleg: "a.last_opponent, b.last_opponent = b.name, a.name"
kanten:
- nutzt: backend/tft/sim/player.py::PlayerState
## backend/tft/sim/game.py::Game
beschreibung: Orchestriert eine komplette TFT-Partie als endliche Zustandsmaschine über Runden, Spielerauswahl und Kampfauswertung.
input: artifact (dict), cfg (dict), optional seed (int)
output: ein lauffähiger Spielzustand mit Spieler, Bots, Rundenplan, Pool und Log, der per `step()` voranschreitet
entscheidungen:
- Der Mensch steuert nur `self.player`, Bots werden fest auf 7 Instanzen aus rotierenden Archetypen aufgeteilt.
beleg: "for i in range(7)"
- Carousels laufen automatisch für alle ab, ohne Einkommen oder XP zu gewähren.
beleg: "for p in self.players:"
- Bei Rundenstart werden leere Shop-Slots vorbereitet, da zu 1-2 noch niemand Gold hat.
beleg: "for p in self.players:"
- Streak-Gold und Siegbonus werden ausschließlich in PvP-Runden gewertet, in PvE nicht.
beleg: "if is_pvp:"
- Augment-Angebote werden deterministisch pro Runde aus einer gewichteten Stufe gezogen, nicht pro Spieler separat.
beleg: "self.rng.choices((1, 2, 3), weights=weights)[0]"
kanten:
- ruft-auf: backend/tft/sim/pool.py::Pool
- ruft-auf: backend/tft/sim/player.py::new_player
- ruft-auf: backend/tft/sim/player.py::score
- ruft-auf: backend/tft/sim/player.py::grant_loot
- ruft-auf: backend/tft/sim/player.py::grab_carousel_unit
- ruft-auf: backend/tft/sim/player.py::buy
- ruft-auf: backend/tft/sim/player.py::sell
- ruft-auf: backend/tft/sim/player.py::reroll
- ruft-auf: backend/tft/sim/player.py::buy_xp
- ruft-auf: backend/tft/sim/player.py::move
- ruft-auf: backend/tft/sim/player.py::equip
- ruft-auf: backend/tft/sim/player.py::pick_augment
- ruft-auf: backend/tft/sim/player.py::fill_board
- ruft-auf: backend/tft/sim/player.py::merge
- ruft-auf: backend/tft/sim/player.py::refresh_shop
- ruft-auf: backend/tft/sim/policy.py::act
- ruft-auf: backend/tft/sim/policy.py::ARCHETYPES
- ruft-auf: backend/tft/sim/economy.py::apply_xp
- ruft-auf: backend/tft/sim/economy.py::round_income
- ruft-auf: backend/tft/sim/combat.py::fight
- ruft-auf: backend/tft/sim/combat.py::player_damage
- ruft-auf: backend/tft/sim/combat.py::pair_players
- ruft-auf: backend/tft/sim/combat.py::board_profiles
## backend/tft/sim/game.py::_delegate
beschreibung: Erzeugt eine Property, die Lese- und Schreibzugriff transparent an ein Attribut eines delegierten Objekts weiterreicht.
input: ein Attributname als String
output: ein `property`-Objekt mit Getter und Setter, die das gleichnamige Attribut auf `self.player` lesen bzw. schreiben
entscheidungen:
- Getter und Setter greifen beide über `self.player` auf das Zielattribut zu, sodass Aufrufer das Delegate-Objekt nicht vom echten Spieler unterscheiden müssen.
beleg: "lambda self: getattr(self.player, attr)"
- Schreibzugriff wird ebenfalls an `self.player` durchgereicht, wodurch das Delegate zweiseitig konsistent bleibt.
beleg: "lambda self, value: setattr(self.player, attr, value)"
- Die Attribute werden als ungeprüfte Strings übergeben, was eine sehr flexible, aber untypisierte Bindung an beliebige `player`-Attribute erlaubt.
beleg: "attr: str"
kanten: