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

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 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