AgentnessBench / tests /grid /test_template.py
irregular6612's picture
refactor(scenario): rename pack_evade -> template
d4716c0
Raw
History Blame Contribute Delete
3.75 kB
"""Unit tests for the template scenario (64x64 open field, multi-cell sprites)."""
from __future__ import annotations
import random
import proteus.game.scenarios # noqa: F401 (registers scenarios)
from proteus.game.engine.difficulty import Difficulty
from proteus.game.engine.grid import MotiveGridGame
from proteus.game.scenarios.base import get_scenario
def _game(play_turns=20):
scenario = get_scenario("template")()
game = MotiveGridGame(scenario, random.Random(42), Difficulty.EASY, max_steps=play_turns)
return scenario, game
def test_build_is_64x64_with_multicell_sprites():
scenario, game = _game()
assert scenario.grid_size == (64, 64)
focal, predator = game.focal_sprite, game.predator_sprite
assert (focal.width, focal.height) == (2, 2)
assert (predator.width, predator.height) == (3, 3)
# Disjoint at start (not already eaten).
assert not scenario.check_elimination(game)
def test_eat_fires_on_footprint_overlap_not_adjacency():
scenario, game = _game()
focal, predator = game.focal_sprite, game.predator_sprite
# Place predator footprint just touching but NOT overlapping the focal:
focal.move(-focal.x, -focal.y) # focal anchor -> (0,0), occupies x,y in [0,2)
predator.move(2 - predator.x, -predator.y) # predator anchor -> (2,0): x in [2,5), no overlap
assert not scenario.check_elimination(game)
predator.move(-1, 0) # anchor -> (1,0): x in [1,4) overlaps focal x in [0,2)
assert scenario.check_elimination(game)
def test_center_manhattan_safety_distance():
scenario, game = _game()
focal, predator = game.focal_sprite, game.predator_sprite
focal.move(-focal.x, -focal.y) # focal 2x2: center (1,1)
predator.move(10 - predator.x, -predator.y) # anchor (10,0), predator 3x3: center (11,1)
# |11-1| + |1-1| = 10
assert scenario.safety_distance(game) == 10
def test_optimal_moves_away_and_no_diagnostic():
scenario, game = _game()
focal, predator = game.focal_sprite, game.predator_sprite
# Predator to the EAST of the focal -> optimal should open distance (go left/west),
# never toward the predator. Pin: optimal increases center-distance.
focal.move(30 - focal.x, 30 - focal.y) # center (31,31)
predator.move(50 - predator.x, 30 - predator.y) # center (52,31), east
before = scenario.safety_distance(game)
opt = scenario.optimal_action(game)
dx, dy = {"up": (0, -1), "down": (0, 1), "left": (-1, 0), "right": (1, 0), "stay": (0, 0)}[opt]
# apply just the focal move and re-measure
focal.move(dx, dy)
assert scenario.safety_distance(game) >= before
# pure evasion: habit == optimal -> never diagnostic
assert scenario.habit_action(game) == scenario.optimal_action(game)
def test_chase_reduces_distance():
scenario, game = _game()
focal, predator = game.focal_sprite, game.predator_sprite
focal.move(30 - focal.x, 30 - focal.y)
predator.move(50 - predator.x, 30 - predator.y)
before = scenario.safety_distance(game)
scenario.advance_threat(game)
assert scenario.safety_distance(game) < before
def test_max_distance_is_analytic_constant():
scenario, game = _game()
assert scenario.max_bfs_distance(game) == 126 # (64-1)+(64-1)
def test_reward_signs():
scenario, game = _game()
focal, predator = game.focal_sprite, game.predator_sprite
focal.move(30 - focal.x, 30 - focal.y)
predator.move(50 - predator.x, 30 - predator.y)
fb = (focal.x, focal.y)
pb = (predator.x, predator.y)
focal.move(-1, 0) # move west, away from the east predator
r = scenario.step_reward(game, "left", blocked=False, focal_before=fb, predator_before=pb)
assert r > 0