mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
90 lines
3.0 KiB
Python
90 lines
3.0 KiB
Python
"""Offline checks for the generation-5 stage configuration and gates."""
|
|
|
|
import unittest
|
|
|
|
import generation5
|
|
|
|
|
|
def flag_value(flags: list[str], name: str) -> str:
|
|
index = flags.index(name)
|
|
return flags[index + 1]
|
|
|
|
|
|
class Generation5ConfigTests(unittest.TestCase):
|
|
def test_stage_sequence_and_lineage(self) -> None:
|
|
self.assertEqual([stage["number"] for stage in generation5.STAGES], [4, 5, 6])
|
|
state = generation5.fresh_state()
|
|
checkpoint = generation5.resume_checkpoint(
|
|
state, stage_index=0, attempt=0, foundation=generation5.FOUNDATION_CHECKPOINT
|
|
)
|
|
self.assertEqual(checkpoint, generation5.FOUNDATION_CHECKPOINT)
|
|
|
|
def test_start_state_probabilities_leave_random_remainder(self) -> None:
|
|
for stage in generation5.STAGES:
|
|
flags = stage["flags"]
|
|
total = sum(
|
|
float(flag_value(flags, name))
|
|
for name in (
|
|
"--kickoff-chance",
|
|
"--near-goal-chance",
|
|
"--air-drill-chance",
|
|
"--air-intercept-chance",
|
|
)
|
|
)
|
|
with self.subTest(stage=stage["name"]):
|
|
self.assertLessEqual(total, 1.0)
|
|
|
|
def test_only_league_stage_requests_pool(self) -> None:
|
|
self.assertEqual(
|
|
[stage["name"] for stage in generation5.STAGES if stage.get("league_pool")],
|
|
["league"],
|
|
)
|
|
self.assertEqual(flag_value(generation5.STAGES[2]["flags"], "--opponent-mode"), "league")
|
|
|
|
def test_telemetry_floors_fail_closed_on_missing_metric(self) -> None:
|
|
ok, failures = generation5.telemetry_passes(
|
|
generation5.STAGES[0], {"rollout/upright_fraction": 1.0}
|
|
)
|
|
self.assertFalse(ok)
|
|
self.assertIn("rollout/forward_motion_fraction missing", failures)
|
|
|
|
def test_match_gate_only_blocks_clear_regression(self) -> None:
|
|
self.assertTrue(
|
|
generation5.match_passes({"wins_a": 40, "wins_b": 54, "episodes": 100})
|
|
)
|
|
self.assertFalse(
|
|
generation5.match_passes({"wins_a": 40, "wins_b": 55, "episodes": 100})
|
|
)
|
|
|
|
def test_evaluation_goal_rate_counts_either_scorer(self) -> None:
|
|
self.assertEqual(
|
|
generation5.evaluation_goal_rate(
|
|
{"wins_a": 45, "wins_b": 35, "draws": 20, "episodes": 100}
|
|
),
|
|
0.8,
|
|
)
|
|
|
|
def test_physical_side_imbalance_exposes_broken_player_slot(self) -> None:
|
|
self.assertEqual(
|
|
generation5.physical_side_imbalance(
|
|
{
|
|
"physical_team_wins": {"team_0": 90, "team_1": 5},
|
|
"episodes": 100,
|
|
}
|
|
),
|
|
0.85,
|
|
)
|
|
self.assertEqual(
|
|
generation5.physical_side_imbalance(
|
|
{
|
|
"physical_team_wins": {"team_0": 42, "team_1": 38},
|
|
"episodes": 100,
|
|
}
|
|
),
|
|
0.04,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|