import random from proteus.game.engine.difficulty import Difficulty from proteus.game.engine.grid import MotiveGridGame from proteus.game.scenarios.base import get_scenario from proteus.game.scenarios.template import _REWARD_EDGE_BLOCK def _start(): s = get_scenario("template")() game = MotiveGridGame(s, random.Random(42), Difficulty.EASY, max_steps=20) return game, s def test_step_reward_positive_when_moving_away(): game, s = _start() focal_before = (game.focal_sprite.x, game.focal_sprite.y) predator_before = (game.predator_sprite.x, game.predator_sprite.y) # The focal spawns west of the predator; moving further from it earns reward. away = s.optimal_action(game) game.apply_motive_action(away) r = s.step_reward(game, away, blocked=False, focal_before=focal_before, predator_before=predator_before) assert r > 0 def test_step_reward_negative_when_moving_toward(): game, s = _start() focal_before = (game.focal_sprite.x, game.focal_sprite.y) predator_before = (game.predator_sprite.x, game.predator_sprite.y) # 'right' moves toward the predator (east). game.apply_motive_action("right") r = s.step_reward(game, "right", blocked=False, focal_before=focal_before, predator_before=predator_before) assert r < 0 def test_step_reward_negative_on_blocked_move(): # Generic property: a blocked move (footprint hits a wall/edge) is penalised # via the _REWARD_EDGE_BLOCK branch, regardless of geometry. This is the only # test exercising the blocked=True path. game, s = _start() focal_before = (game.focal_sprite.x, game.focal_sprite.y) predator_before = (game.predator_sprite.x, game.predator_sprite.y) r = s.step_reward(game, "left", blocked=True, focal_before=focal_before, predator_before=predator_before) assert r < 0 assert r == _REWARD_EDGE_BLOCK def test_safety_distance_is_distance_focal_to_predator(): game, s = _start() d = s.safety_distance(game) assert isinstance(d, int) and d >= 0