4.1 KiB
Einheiten: backend/tft/sim/combat.py
stand: f41ac76b57
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
Nonemit 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.shufflezufä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)] = 0als 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
dtauf 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