| import unittest |
|
|
| from terrarium.large_world import generate_large_world |
| from terrarium.neural_schema import NEURAL_ACTION_SCHEMA_VERSION, NEURAL_OPTIONS |
| from terrarium.option_controller import ( |
| OPTION_RESOLUTION_SCHEMA_VERSION, |
| apply_resolution_step, |
| option_scores_from_context, |
| resolve_option, |
| ) |
|
|
|
|
| class OptionControllerTest(unittest.TestCase): |
| def test_all_neural_options_resolve_without_direct_coordinates(self): |
| world = generate_large_world(seed=515) |
| position = tuple(world["creature_spawn"]) |
| for option in NEURAL_OPTIONS: |
| resolution = resolve_option( |
| option, |
| world, |
| position, |
| user_position=tuple(world["user_spawn"]), |
| resources={"hunger": 0.45, "energy": 0.7, "fear": 0.2}, |
| temperament={"careful": 0.5, "playful": 0.4, "social": 0.4, "curious": 0.6}, |
| slow_steering={ |
| "directive": {"mode": "inspect", "strength": 0.6, "urgency": 0.3}, |
| "option_priors": {"inspect_novelty": 0.2}, |
| }, |
| ) |
| self.assertEqual(resolution["schema_version"], OPTION_RESOLUTION_SCHEMA_VERSION) |
| self.assertEqual(resolution["action_schema_version"], NEURAL_ACTION_SCHEMA_VERSION) |
| self.assertEqual(resolution["option"], option) |
| self.assertNotIn("coordinates", resolution) |
| self.assertNotIn("resource_mutation", resolution) |
| self.assertNotIn("direct_logits", resolution) |
|
|
| def test_unsafe_user_approach_is_refused_by_controller(self): |
| world = generate_large_world(seed=616) |
| creature = tuple(world["creature_spawn"]) |
| user = tuple(world["user_spawn"]) |
| x0, y0 = creature |
| x1, y1 = user |
| for x in range(min(x0, x1), max(x0, x1) + 1): |
| world["terrain"][y0][x] = "hazard" |
| for y in range(min(y0, y1), max(y0, y1) + 1): |
| world["terrain"][y][x1] = "hazard" |
| world["terrain"][y0][x0] = "open" |
| world["terrain"][y1][x1] = "open" |
|
|
| resolution = resolve_option( |
| "approach_user", |
| world, |
| creature, |
| user_position=user, |
| resources={"hunger": 0.2, "energy": 0.8, "fear": 0.1}, |
| temperament={"careful": 0.9, "social": 0.7}, |
| ) |
|
|
| self.assertEqual(resolution["primitive_action"], "wait") |
| self.assertEqual(resolution["arbiter_override"], "unsafe_user_approach") |
|
|
| def test_resolution_step_moves_only_for_passable_move_actions(self): |
| world = generate_large_world(seed=717) |
| position = tuple(world["creature_spawn"]) |
| resolution = resolve_option("explore_frontier", world, position, visited={position}) |
| next_position = apply_resolution_step(world, position, resolution) |
| if resolution["primitive_action"].startswith("move_"): |
| self.assertNotEqual(next_position, position) |
| else: |
| self.assertEqual(next_position, position) |
| x, y = next_position |
| self.assertNotEqual(world["terrain"][y][x], "wall") |
|
|
| def test_option_scores_reflect_temperament_memory_and_slow_steering(self): |
| world = generate_large_world(seed=818) |
| position = tuple(world["creature_spawn"]) |
| careful = option_scores_from_context( |
| world, |
| position, |
| user_position=tuple(world["user_spawn"]), |
| resources={"hunger": 0.3, "energy": 0.8, "fear": 0.2}, |
| temperament={"careful": 0.9, "playful": 0.1, "social": 0.2, "curious": 0.4}, |
| memory={"negative_pull": 0.7}, |
| ) |
| playful = option_scores_from_context( |
| world, |
| position, |
| user_position=tuple(world["user_spawn"]), |
| resources={"hunger": 0.3, "energy": 0.8, "fear": 0.2}, |
| temperament={"careful": 0.1, "playful": 0.9, "social": 0.8, "curious": 0.4}, |
| memory={"negative_pull": 0.0}, |
| slow_steering={"directive": {"mode": "approach_user", "strength": 0.6}}, |
| ) |
|
|
| self.assertGreater(careful["avoid_or_retreat"], playful["avoid_or_retreat"]) |
| self.assertGreater(playful["approach_user"], careful["approach_user"]) |
| self.assertGreater(playful["follow_slow_directive"], careful["follow_slow_directive"]) |
|
|
|
|
| if __name__ == "__main__": |
| unittest.main() |
|
|