93 lines
3.1 KiB
Python
93 lines
3.1 KiB
Python
import random
|
|
|
|
from tft.sim import combat
|
|
|
|
|
|
def prof(off, dfn, defensive=True, name="u"):
|
|
return {"off": off, "def": dfn, "defensive": defensive,
|
|
"unit": {"api_name": name, "stars": 1, "items": []}}
|
|
|
|
|
|
CFG = {
|
|
"combat": {"max_frames": 1800},
|
|
"damage": {"stage_base": [0, 2, 5, 8, 10, 12, 17, 17],
|
|
"per_surviving_unit": 1, "player_hp": 100},
|
|
}
|
|
|
|
|
|
def test_kill_time_matches_dps_at_60fps():
|
|
# Def 10 gegen Gesamt-Off 5 -> 2 s = 120 Frames.
|
|
a = [prof(5, 1000)]
|
|
b = [prof(0, 10)]
|
|
res = combat.fight(a, b, random.Random(1), CFG)
|
|
assert res.winner == "a"
|
|
assert res.frames == 120
|
|
assert res.survivors_b == []
|
|
|
|
|
|
def test_overflow_carries_to_next_unit():
|
|
# Zwei Units à 10 Def gegen Off 5 -> exakt 4 s, kein Schaden verpufft.
|
|
a = [prof(5, 1000)]
|
|
b = [prof(0, 10), prof(0, 10)]
|
|
res = combat.fight(a, b, random.Random(1), CFG)
|
|
assert res.winner == "a"
|
|
assert res.frames == 240
|
|
|
|
|
|
def test_dead_units_stop_contributing_offense():
|
|
# B killt As Front nach 2 s; danach kämpft A nur noch mit halber Offense.
|
|
a = [prof(6, 12, defensive=True), prof(6, 1000, defensive=False)]
|
|
b = [prof(6, 60)]
|
|
res = combat.fight(a, b, random.Random(1), CFG)
|
|
assert res.winner == "a"
|
|
assert res.frames == 480 # 2 s + 36/6 s statt 60/12 s bei konstanter Offense
|
|
assert len(res.survivors_a) == 1
|
|
|
|
|
|
def test_queue_targets_defensive_units_first():
|
|
team = [prof(1, 1, defensive=False, name="carry1"),
|
|
prof(1, 1, defensive=True, name="tank1"),
|
|
prof(1, 1, defensive=False, name="carry2"),
|
|
prof(1, 1, defensive=True, name="tank2")]
|
|
q = combat._queue(team, random.Random(5))
|
|
assert [p["defensive"] for p in q] == [True, True, False, False]
|
|
|
|
|
|
def test_simultaneous_last_kill_is_draw():
|
|
a = [prof(5, 10)]
|
|
b = [prof(5, 10)]
|
|
res = combat.fight(a, b, random.Random(1), CFG)
|
|
assert res.winner is None
|
|
assert res.survivors_a == [] and res.survivors_b == []
|
|
|
|
|
|
def test_empty_boards():
|
|
res = combat.fight([], [], random.Random(1), CFG)
|
|
assert res.winner is None and res.frames == 0
|
|
res = combat.fight([prof(1, 1)], [], random.Random(1), CFG)
|
|
assert res.winner == "a"
|
|
|
|
|
|
def test_stall_hits_time_limit_more_defense_wins():
|
|
a = [prof(0, 100)]
|
|
b = [prof(0, 50)]
|
|
res = combat.fight(a, b, random.Random(1), CFG)
|
|
assert res.winner == "a"
|
|
assert res.frames == CFG["combat"]["max_frames"]
|
|
|
|
|
|
def test_same_seed_same_result():
|
|
team_a = [prof(7, 300), prof(12, 150, defensive=False), prof(5, 400)]
|
|
team_b = [prof(9, 250), prof(10, 200, defensive=False)]
|
|
r1 = combat.fight(team_a, team_b, random.Random(42), CFG)
|
|
r2 = combat.fight(team_a, team_b, random.Random(42), CFG)
|
|
assert (r1.winner, r1.frames) == (r2.winner, r2.frames)
|
|
assert [p["api_name"] for p in r1.survivors_a] == \
|
|
[p["api_name"] for p in r2.survivors_a]
|
|
|
|
|
|
def test_player_damage_counts_exact_survivors():
|
|
survivors = [{"api_name": f"u{i}"} for i in range(4)]
|
|
assert combat.player_damage(3, survivors, CFG) == 5 + 4
|
|
assert combat.player_damage(1, [], CFG) == 0
|