from proteus.game.engine.difficulty import Difficulty from proteus.game.metrics.rollout import RolloutResult, optimal_rollout def test_optimal_rollout_is_deterministic(): a = optimal_rollout("template", seed=42, difficulty=Difficulty.EASY, n_turns=5) b = optimal_rollout("template", seed=42, difficulty=Difficulty.EASY, n_turns=5) assert isinstance(a, RolloutResult) assert a.focal_positions == b.focal_positions assert a.final_safety_distance == b.final_safety_distance def test_optimal_rollout_length_capped_by_n_turns(): r = optimal_rollout("template", seed=42, difficulty=Difficulty.EASY, n_turns=3) assert len(r.focal_positions) <= 3 # Each recorded position is the PRE-move focal cell for that optimal turn. assert all(isinstance(p, tuple) and len(p) == 2 for p in r.focal_positions) def test_optimal_rollout_first_position_is_handover(): # The first optimal pre-move position equals the focal's spawn cell (template # has no Cut pre-roll, so the handover IS the spawn). Self-derived, not hardcoded. import random from proteus.game.engine.grid import MotiveGridGame from proteus.game.scenarios.base import get_scenario scenario = get_scenario("template")() game = MotiveGridGame(scenario, random.Random(42), Difficulty.EASY, max_steps=10) spawn = (game.focal_sprite.x, game.focal_sprite.y) r = optimal_rollout("template", seed=42, difficulty=Difficulty.EASY, n_turns=5) assert r.focal_positions[0] == spawn