Files
tft/backend/tests/test_sim.py
2026-07-23 00:35:30 +02:00

97 lines
2.9 KiB
Python

import random
import pytest
from tft.constants.loader import load_constants
from tft.sim import economy
from tft.sim.pool import Pool
from tft.sim.rounds import schedule
from tft.sim.shop import roll
def make_static(per_tier: int = 13) -> dict:
units = {}
for cost in range(1, 6):
for i in range(per_tier):
units[f"U{cost}_{i}"] = {
"cost": cost,
"traits": ["T1"],
"role": "Tank",
"stats": {"hp": 600 + 100 * cost, "armor": 40, "magicResist": 40,
"damage": 55, "attackSpeed": 0.7, "mana": 60,
"initialMana": 0, "range": 1},
}
return {
"meta": {"set": 17},
"units": units,
"traits": {"T1": {"breakpoints": [{"min_units": 2, "style": 1}]}},
"items": {f"TFT_Item_{i}": {} for i in range(10)},
"augments": {f"TFT17_Augment_{i}": {} for i in range(8)},
}
@pytest.fixture(scope="module")
def cfg():
return load_constants(17)
@pytest.fixture
def static():
return make_static()
def test_pool_take_put_back(static, cfg):
pool = Pool(static["units"], cfg["pool"]["sizes"])
assert pool.available("U1_0") == 30
pool.take("U1_0", 3)
assert pool.available("U1_0") == 27
pool.put_back("U1_0", 3)
assert pool.available("U1_0") == 30
with pytest.raises(ValueError):
pool.take("U5_0", 10)
def test_shop_odds_empirical(static, cfg):
pool = Pool(static["units"], cfg["pool"]["sizes"])
rng = random.Random(42)
counts = [0] * 5
n = 10_000
for _ in range(n // cfg["shop"]["slots"]):
for api in roll(pool, 8, cfg, rng):
counts[static["units"][api]["cost"] - 1] += 1
expected = cfg["shop"]["odds"][7]
for tier in range(5):
assert counts[tier] / n == pytest.approx(expected[tier] / 100, abs=0.02)
def test_interest_cap(cfg):
assert economy.interest(0, cfg) == 0
assert economy.interest(39, cfg) == 3
assert economy.interest(80, cfg) == cfg["gold"]["interest_cap"]
def test_streak_gold(cfg):
assert economy.streak_gold(1, cfg) == 0
assert economy.streak_gold(3, cfg) == 1
assert economy.streak_gold(-5, cfg) == 2
assert economy.streak_gold(9, cfg) == 3
def test_apply_xp_levels_up(cfg):
level, xp = economy.apply_xp(1, 0, 4, cfg)
assert level == 3 # 1->2 costs 2, 2->3 costs 2
assert xp == 0
level, _ = economy.apply_xp(9, 0, 1000, cfg)
assert level == cfg["xp"]["max_level"]
def test_schedule(cfg):
rounds = schedule(cfg)
labels = [r["label"] for r in rounds]
assert labels[:4] == ["1-1", "1-2", "1-3", "1-4"]
assert rounds[0]["kind"] == "carousel"
aug = [r["label"] for r in rounds if r["augment"]]
assert aug == cfg["rounds"]["augment_rounds"]
stage2 = [r for r in rounds if r["stage"] == 2]
assert [r["kind"] for r in stage2] == cfg["rounds"]["stage_n"]