from pathlib import Path import pytest from dojo.sim import BoardFiles, Scenario, matrix, run BOARD = Path(__file__).parent.parent / "board" FILES = BoardFiles(BOARD / "quadrant.txt", BOARD / "legend.toml") LINEUP = ("balanced", "random") def test_matrix_crosses_every_axis() -> None: scenarios = matrix(["A", "B"], [3, 4], [2, 1], [0], [LINEUP]) assert len(scenarios) == 8 assert scenarios[0].name == "A p3 kiai+2 start0 balanced,random" assert scenarios[-1].config.kiai_bonus == 1 assert scenarios[-1].config.brown_requires_kumite def test_lineup_fills_the_seats_and_rotates_each_game() -> None: scenario = Scenario("A", 3, 2, 0, LINEUP) assert scenario.seating(0) == ("balanced", "random", "balanced") assert scenario.seating(1) == ("random", "balanced", "balanced") assert scenario.seating(3) == scenario.seating(0) @pytest.mark.parametrize( ("variant", "players", "lineup", "message"), [ ("C", 4, LINEUP, "unknown variant"), ("A", 4, ("balanced", "cheater"), "unknown bots"), ("A", 4, (), "unknown bots"), ("A", 9, LINEUP, "supported range"), ], ) def test_invalid_scenarios_are_rejected( variant: str, players: int, lineup: tuple[str, ...], message: str ) -> None: with pytest.raises(ValueError, match=message): Scenario(variant, players, 2, 0, lineup) def test_runs_are_reproducible_and_independent_of_worker_count() -> None: scenarios = matrix(["A", "B"], [3], [2], [0], [LINEUP]) serial = run(FILES, scenarios, games=2, seed=5, jobs=1) parallel = run(FILES, scenarios, games=2, seed=5, jobs=2) assert serial == parallel assert [(g.scenario, g.seed) for g in serial] == [ (scenarios[0].name, 5), (scenarios[0].name, 6), (scenarios[1].name, 5), (scenarios[1].name, 6), ] assert serial[1].lineup == "random,balanced,balanced"