# Einheiten: backend/tft/sim/combat.py stand: f41ac76b5789 ## backend/tft/sim/combat.py::FightResult beschreibung: Datenklasse, die das Ergebnis eines Kampfes zwischen zwei Teams festhält. input: Siegerkennzeichen "a"/"b"/None, gespielte Frames und überlebende Units beider Seiten output: Ein `FightResult`-Objekt mit `winner`, `frames`, `survivors_a` und `survivors_b` entscheidungen: - Das Ergebnis-Format schließt einen Unentschieden-Fall explizit als `None` mit ein. beleg: "winner: str | None # \"a\" | \"b\" | None = Unentschieden" - Überlebende werden seitenweise als Liste von Unit-Dicts geführt, nicht als Indizes. beleg: "survivors_a: list[dict]" - Die Anzahl der simulierten Frames wird als Ganzzahl gerundet (`ceil`). beleg: "frames=math.ceil(elapsed * FPS)," kanten: - wird-genutzt-von: backend/tft/sim/combat.py::fight ## backend/tft/sim/combat.py::_queue beschreibung: Bestimmt die Bearbeitungsreihenfolge der Units eines Teams als defensive zuerst, intern zufällig gemischt. input: Team-Liste von Unit-Dicts und ein `random.Random`-RNG output: Neue Liste, in der defensive Units vor offensiven stehen, beide Gruppen intern gemischt entscheidungen: - Defensive Units werden grundsätzlich vor offensiven angegriffen. beleg: "defensive = [p for p in team if p[\"defensive\"]]" - Innerhalb jeder Gruppe wird die Reihenfolge per `rng.shuffle` zufällig gemischt. beleg: "rng.shuffle(defensive)" - Die Sortierung ist nicht stabil, da die ursprüngliche Reihenfolge überschrieben wird. beleg: "return defensive + offensive" kanten: - nutzt: backend/tft/sim/combat.py::_suffix_off - wird-genutzt-von: backend/tft/sim/combat.py::fight ## backend/tft/sim/combat.py::_suffix_off beschreibung: Berechnet die Suffix-Summe der Offensive-Werte einer Ziel-Queue. input: Liste von Unit-Dicts mit `"off"`-Feld output: Liste gleicher Länge + 1, in der `suffix[i]` die Gesamt-Offense ab Unit `i` ist entscheidungen: - Die Liste ist absichtlich um einen Eintrag länger, damit `suffix[len(queue)] = 0` als Sicherheitselement dient. beleg: "suffix = [0.0] * (len(queue) + 1)" - Die Summation läuft rückwärts, um die echte Suffix-Summe zu bilden. beleg: "for i in range(len(queue) - 1, -1, -1):" kanten: - wird-genutzt-von: backend/tft/sim/combat.py::fight ## backend/tft/sim/combat.py::fight beschreibung: Simuliert einen deterministischen Kampf zweier Teams eventbasiert bis zum nächsten Tod oder Zeitlimit. input: Zwei Team-Profil-Listen, ein `random.Random`-RNG und eine Config mit `combat.max_frames` output: `FightResult` mit Sieger, Framezahl und Überlebenden beider Seiten entscheidungen: - Zwischen zwei Todesereignissen werden beide Offensen als konstant angenommen, `dt = min(ta, tb)`. beleg: "dt = min(ta, tb)" - Bei Überschreitung des Zeitlimits wird `dt` auf das verbleibende Restbudget begrenzt. beleg: "dt = limit - elapsed" - Überzähliger Schaden wird verlustfrei auf das nächste Ziel übertragen, indem die Rest-Defense weiter reduziert wird. beleg: "rb -= oa * dt" - Bei Zeitlimit ohne verbleibende Offense wird der Sieg nach größerer Rest-Defense entschieden. beleg: "winner = \"a\" if rest_a > rest_b + EPS else \"b\" if rest_b > rest_a + EPS else None" - Ein gleicher Kill-Frame kann nicht beide Seiten treffen, da `else`-Zweige getrennt ausgewertet werden. beleg: "else:" kanten: - ruft-auf: backend/tft/sim/combat.py::_queue - ruft-auf: backend/tft/sim/combat.py::_suffix_off - nutzt: backend/tft/sim/combat.py::FightResult - wird-genutzt-von: backend/tft/sim/combat.py::player_damage ## backend/tft/sim/combat.py::player_damage beschreibung: Berechnet den Schaden, den ein Spieler nach einer Runde abhängig von erreichter Stage und Überlebenden erhält. input: Stage-Index (1-basiert), Liste der überlebenden Units und eine Config mit `damage` output: Schadenswert als `int` entscheidungen: - Der Basis-Schaden wird stageweise aus `cfg["damage"]["stage_base"]` gelesen, bei Überschreitung wird der letzte Eintrag verwendet. beleg: "min(stage - 1, len(d[\"stage_base\"]) - 1)" - Pro überlebender Unit wird ein linearer Zusatzschaden addiert. beleg: "return base + d[\"per_surviving_unit\"] * len(survivors)" kanten: - nutzt: backend/tft/sim/combat.py::fight