AgentnessBench / tests /engine /test_health_interact_hooks.py
irregular6612's picture
feat(engine): health/damage + interact action + on_step_effects/check_success in turn loop
9bd40a5
Raw
History Blame Contribute Delete
2.61 kB
# tests/engine/test_health_interact_hooks.py
"""Health, interact dispatch, and check_success wired into the shared turn loop.
Uses a tiny Template subclass to exercise health_start at construction, and
per-instance method shadowing (the test_turn_order pattern) for the per-turn
hooks. Template's predator spawns far from the focal, so a single turn never
triggers its predator-overlap elimination.
"""
import random
from proteus.game.engine.difficulty import Difficulty
from proteus.game.engine.grid import MotiveGridGame
from proteus.game.scenarios.template import Template
import proteus.game.scenarios # noqa: F401
class _HP(Template):
def health_start(self, difficulty):
return 6
def _game(scen):
return MotiveGridGame(scen, random.Random(0), Difficulty.EASY, max_steps=10)
def test_health_initialized_from_scenario():
assert _game(_HP()).health == 6
def test_damage_reduces_and_clamps_health():
game = _game(_HP())
game.damage(2)
assert game.health == 4
game.damage(99)
assert game.health == 0 # clamped, never negative
def test_on_step_effects_called_each_turn():
scen = _HP()
scen.on_step_effects = lambda g: g.damage(1)
game = _game(scen)
game.apply_motive_action("stay")
assert game.health == 5
def test_health_zero_can_drive_elimination():
scen = _HP()
scen.on_step_effects = lambda g: g.damage(6)
scen.check_elimination = lambda g: g.health <= 0
game = _game(scen)
game.apply_motive_action("stay")
assert game.eliminated
def test_check_success_triggers_win():
scen = _HP()
scen.check_success = lambda g: True
game = _game(scen)
game.apply_motive_action("stay")
assert game.survived
def test_interact_dispatches_and_does_not_move():
scen = _HP()
calls = []
scen.on_interact = lambda g: calls.append(g.step_count)
game = _game(scen)
fx, fy = game.focal_sprite.x, game.focal_sprite.y
game.apply_motive_action("interact")
assert calls == [1] # on_interact ran once
assert (game.focal_sprite.x, game.focal_sprite.y) == (fx, fy) # no move
assert game.step_count == 1 # turn advanced
def test_interact_is_noop_dispatch_when_not_overridden():
# Default on_interact is a no-op: interact still advances the turn safely.
game = _game(_HP())
game.apply_motive_action("interact")
assert game.step_count == 1
def test_unknown_action_still_raises():
import pytest
game = _game(_HP())
with pytest.raises(ValueError):
game.apply_motive_action("teleport")