This commit is contained in:
team3
2026-09-07 07:44:09 +02:00
parent 848c8ea1aa
commit e12c2595fc
69 changed files with 7080 additions and 1165 deletions

View File

@@ -3,7 +3,7 @@ import pytest
from tft.constants.loader import load_constants
from tft.model import artifact as artifact_mod
from tft.sim.autoplay import play_afk, play_econ
from tft.sim.game import Game, InvalidAction
from tft.sim.game import MAX_ITEMS_PER_UNIT, Game, InvalidAction
from tests.test_sim import make_static
@@ -229,7 +229,20 @@ def test_natural_level_progression(art, cfg):
assert checks["3-2"] == (5, 0)
def test_no_augments_are_offered(art, cfg):
"""Augments sind per Config abgeschaltet — weder Spieler noch Bots bekommen welche."""
game = Game(art, cfg, seed=2)
for _ in range(24):
assert not game.player.augment_offer
assert all(not p.augments for p in game.players)
if game.over:
break
game.step()
def test_augment_offer_single_tier(art, cfg):
# Die Mechanik bleibt geprüft, auch wenn sie ausgeliefert deaktiviert ist.
cfg = {**cfg, "rounds": {**cfg["rounds"], "augment_rounds": ["2-1"]}}
game = Game(art, cfg, seed=9)
mixed = {f"AUG_T{t}_{i}": {"tier": t} for t in (1, 2, 3) for i in range(4)}
game.artifact = {**art, "static": {**art["static"], "augments": mixed},
@@ -255,6 +268,89 @@ def test_equip_crafts_completed_item(art, cfg):
assert game.board[0]["items"] == ["COMPLETED", "C_A"]
def test_merge_keeps_surplus_items_and_extra_copy(art, cfg):
"""Verschmelzen darf weder Items vernichten noch die 4. Kopie schlucken."""
from tft.sim import player
game = Game(art, cfg, seed=1)
game.items = []
game.board = [{"api_name": "U1_0", "stars": 1, "items": ["I_A", "I_B"]},
{"api_name": "U1_0", "stars": 1, "items": ["I_C", "I_D"]}]
game.bench = [{"api_name": "U1_0", "stars": 1, "items": ["I_E", "I_F"]},
{"api_name": "U1_0", "stars": 1, "items": []}]
player.merge(game.player, "U1_0", 1)
on_units = [i for u in game.board + game.bench for i in u["items"]]
assert sorted(on_units + game.items) == ["I_A", "I_B", "I_C", "I_D", "I_E", "I_F"]
assert len(on_units) == MAX_ITEMS_PER_UNIT
# 3 Kopien verschmelzen, die 4. bleibt als eigene 1★-Unit stehen.
stars = sorted(u["stars"] for u in game.board + game.bench)
assert stars == [1, 2]
def test_place_on_hex(art, cfg):
from tft.sim.player import BOARD_HEXES
game = Game(art, cfg, seed=1)
game.level = 3
game.bench = [{"api_name": "U1_0", "stars": 1, "items": [], "hex": None},
{"api_name": "U2_0", "stars": 1, "items": [], "hex": None}]
game.board = []
game.place("bench", 0, 12)
assert [(u["api_name"], u["hex"]) for u in game.board] == [("U1_0", 12)]
# Auf ein belegtes Hex ziehen -> der Belegte wandert auf die Bank.
game.place("bench", 0, 12)
assert [(u["api_name"], u["hex"]) for u in game.board] == [("U2_0", 12)]
assert game.bench[0]["api_name"] == "U1_0" and game.bench[0]["hex"] is None
# Innerhalb des Felds verschieben.
game.place("board", 0, 5)
assert game.board[0]["hex"] == 5
with pytest.raises(InvalidAction):
game.place("board", 0, BOARD_HEXES)
def test_ranged_units_are_seated_in_the_back():
"""Automatisches Aufstellen: Nahkämpfer nach vorn, Fernkämpfer nach hinten."""
from tft.sim.player import (BOARD_COLS, BOARD_ROWS, PlayerState, fill_board)
ranged_art = {"static": {"units": {
"MELEE": {"cost": 1, "stats": {"range": 1}},
"RANGED": {"cost": 1, "stats": {"range": 4}},
}}}
p = PlayerState(name="t", archetype="x", hp=100, gold=0, level=4)
p.bench = [{"api_name": "RANGED", "stars": 1, "items": []},
{"api_name": "MELEE", "stars": 1, "items": []}]
fill_board(p, ranged_art)
rows = {u["api_name"]: u["hex"] // BOARD_COLS for u in p.board}
assert rows["MELEE"] == 0
assert rows["RANGED"] == BOARD_ROWS - 1
def test_place_swaps_within_board(art, cfg):
game = Game(art, cfg, seed=1)
game.level = 3
game.board = [{"api_name": "U1_0", "stars": 1, "items": [], "hex": 0},
{"api_name": "U2_0", "stars": 1, "items": [], "hex": 9}]
game.bench = []
game.place("board", 0, 9)
assert {u["api_name"]: u["hex"] for u in game.board} == {"U1_0": 9, "U2_0": 0}
def test_autofill_assigns_unique_hexes(art, cfg):
game = Game(art, cfg, seed=4)
for _ in range(6):
game.step()
for p in game.players:
hexes = [u["hex"] for u in p.board]
assert all(h is not None for h in hexes)
assert len(set(hexes)) == len(hexes)
assert all(u.get("hex") is None for u in p.bench)
def test_loot_drops_components(art, cfg):
comp_art = {**art, "component_pool": ["C_A", "C_B"]}
game = Game(comp_art, cfg, seed=2)