104 lines
4.2 KiB
Python
104 lines
4.2 KiB
Python
"""Arena: Boards auf das Kampffeld, eigene Positionen, leere Seiten."""
|
|
|
|
import random
|
|
|
|
from tft.sim.arena import BOARD_COLS
|
|
from tft.sim import arena, hexgrid
|
|
|
|
STATS = {"hp": 800, "armor": 20, "magicResist": 20, "damage": 50,
|
|
"damageByStar": [0, 50, 100, 200], "attackSpeed": 1.0, "range": 1,
|
|
"mana": 0, "initialMana": 0, "critChance": 0.0, "critMultiplier": 1.4}
|
|
ARTIFACT = {"static": {
|
|
"units": {"A": {"traits": [], "stats": STATS},
|
|
"B": {"traits": [], "stats": {**STATS, "range": 4}}},
|
|
"items": {"HP": {"effects": {"Health": 500}}},
|
|
"traits": {},
|
|
}}
|
|
|
|
|
|
def test_front_row_of_both_sides_faces_the_other():
|
|
"""Reihe 0 des Spielers ist die vorderste — sonst laufen alle aneinander vorbei."""
|
|
a = arena.from_hex(3, "a")
|
|
b = arena.from_hex(3, "b")
|
|
assert hexgrid.distance((a["col"], a["row"]), (b["col"], b["row"])) == 1
|
|
|
|
|
|
def test_back_row_is_furthest_away():
|
|
a = arena.from_hex(3 + 3 * BOARD_COLS, "a")
|
|
b = arena.from_hex(3 + 3 * BOARD_COLS, "b")
|
|
assert hexgrid.distance((a["col"], a["row"]), (b["col"], b["row"])) == 7
|
|
|
|
|
|
def test_own_positions_are_used():
|
|
board = [{"api_name": "A", "stars": 1, "hex": 3}]
|
|
out = arena.placed(board, "a", ARTIFACT["static"]["units"])
|
|
assert (out[0]["col"], out[0]["row"]) == (3, 3)
|
|
|
|
|
|
def test_boards_without_positions_fall_back_to_the_lineup():
|
|
"""Endboards aus der Riot-API tragen keine Felder."""
|
|
board = [{"api_name": "A", "stars": 1}, {"api_name": "B", "stars": 1}]
|
|
out = arena.placed(board, "a", ARTIFACT["static"]["units"])
|
|
assert all("col" in e and "row" in e for e in out)
|
|
# Nahkämpfer vorne, Fernkämpfer hinten.
|
|
front = next(e for e in out if e["api_name"] == "A")
|
|
back = next(e for e in out if e["api_name"] == "B")
|
|
assert front["row"] > back["row"]
|
|
|
|
|
|
def test_two_units_never_share_a_cell():
|
|
board = [{"api_name": "A", "stars": 1, "hex": 3},
|
|
{"api_name": "A", "stars": 1, "hex": 3}]
|
|
out = arena.placed(board, "a", ARTIFACT["static"]["units"])
|
|
assert len({(e["col"], e["row"]) for e in out}) == 2
|
|
|
|
|
|
def test_an_empty_board_loses_at_once():
|
|
board = [{"api_name": "A", "stars": 1, "hex": 0}]
|
|
res, log = arena.fight([], board, ARTIFACT, random.Random(1))
|
|
assert res.winner == "b" and res.frames == 0 and log is None
|
|
res, _ = arena.fight(board, [], ARTIFACT, random.Random(1))
|
|
assert res.winner == "a"
|
|
assert arena.fight([], [], ARTIFACT, random.Random(1))[0].winner is None
|
|
|
|
|
|
def test_items_reach_the_fighters():
|
|
board = [{"api_name": "A", "stars": 1, "hex": 0, "items": ["HP"]}]
|
|
plain = arena.side([{"api_name": "A", "stars": 1, "hex": 0}], "a", ARTIFACT)
|
|
armed = arena.side(board, "a", ARTIFACT)
|
|
assert armed[0].max_hp == plain[0].max_hp + 500
|
|
|
|
|
|
def test_the_bigger_board_wins():
|
|
big = [{"api_name": "A", "stars": 1, "hex": h} for h in range(4)]
|
|
small = [{"api_name": "A", "stars": 1, "hex": 0}]
|
|
assert arena.fight(big, small, ARTIFACT, random.Random(1))[0].winner == "a"
|
|
|
|
|
|
def test_replay_returns_a_playable_log():
|
|
"""Feldmaße, Kämpfer und Ereignisse — mehr braucht die Anzeige nicht."""
|
|
a = [{"api_name": "A", "stars": 1, "hex": h} for h in range(3)]
|
|
b = [{"api_name": "A", "stars": 1, "hex": h} for h in range(2)]
|
|
_, log = arena.fight(a, b, ARTIFACT, random.Random(1), record=True)
|
|
assert log["cols"] == hexgrid.COLS and log["rows"] == hexgrid.ROWS
|
|
assert len(log["units"]) == 5
|
|
assert {u["slot"] for u in log["units"]} == set(range(5))
|
|
kinds = {e["e"] for e in log["events"]}
|
|
assert "spawn" in kinds and "hit" in kinds
|
|
assert log["winner"] == "a"
|
|
|
|
|
|
def test_replay_is_none_without_a_fight():
|
|
_, log = arena.fight([], [{"api_name": "A", "stars": 1, "hex": 0}],
|
|
ARTIFACT, random.Random(1), record=True)
|
|
assert log is None
|
|
|
|
|
|
def test_replay_matches_the_fight():
|
|
"""Sonst zeigt die Anzeige etwas anderes als das Spiel gewertet hat."""
|
|
a = [{"api_name": "A", "stars": 1, "hex": h} for h in range(3)]
|
|
b = [{"api_name": "B", "stars": 1, "hex": h} for h in range(3)]
|
|
res, log = arena.fight(a, b, ARTIFACT, random.Random(3), record=True)
|
|
plain, _ = arena.fight(a, b, ARTIFACT, random.Random(3))
|
|
assert log["winner"] == res.winner == plain.winner
|