Spaces:
Paused
Paused
| """apply_action correctness + win predicates (SPEC §11 Day 1).""" | |
| from __future__ import annotations | |
| from game.challenges import CHALLENGES_BY_ID | |
| from game.models import Action | |
| from game.world import apply_action, check_win, initial_world | |
| def test_initial_world_shape(): | |
| w = initial_world() | |
| assert set(w.objects) == {"blue_stone", "red_stone"} | |
| assert set(w.agents) == {"alien", "other"} | |
| assert w.containers == ["basket"] | |
| assert all(o.location == "ground" and not o.hidden for o in w.objects.values()) | |
| def test_pick_up_takes_into_holding_and_reveals(): | |
| w = initial_world() | |
| w.objects["blue_stone"].hidden = True # pretend it was hidden | |
| apply_action(w, Action("pick_up", {"obj_id": "blue_stone"})) | |
| assert w.objects["blue_stone"].location == "alien" | |
| assert "blue_stone" in w.agents["alien"].holding | |
| assert w.objects["blue_stone"].hidden is False # in hand, in the open | |
| def test_put_in_container_conceals(): | |
| w = initial_world() | |
| apply_action(w, Action("put_in", {"obj_id": "blue_stone", "container_id": "basket"})) | |
| assert w.objects["blue_stone"].location == "basket" | |
| assert w.objects["blue_stone"].hidden is True | |
| assert "puts" in w.log[-1] and "basket" in w.log[-1] | |
| def test_give_transfers_and_reveals(): | |
| w = initial_world() | |
| apply_action(w, Action("put_in", {"obj_id": "red_stone", "container_id": "basket"})) | |
| assert w.objects["red_stone"].hidden is True | |
| apply_action(w, Action("give", {"obj_id": "red_stone", "agent_id": "other"})) | |
| assert w.objects["red_stone"].location == "other" | |
| assert "red_stone" in w.agents["other"].holding | |
| assert w.objects["red_stone"].hidden is False | |
| def test_give_detaches_from_previous_holder(): | |
| w = initial_world() | |
| apply_action(w, Action("pick_up", {"obj_id": "blue_stone"})) | |
| assert "blue_stone" in w.agents["alien"].holding | |
| apply_action(w, Action("give", {"obj_id": "blue_stone", "agent_id": "other"})) | |
| assert "blue_stone" not in w.agents["alien"].holding | |
| assert "blue_stone" in w.agents["other"].holding | |
| def test_move_to_and_point_at_and_wait(): | |
| w = initial_world() | |
| apply_action(w, Action("move_to", {"target": "other"})) | |
| assert w.agents["alien"].location == "other" | |
| before = {k: (o.location, o.hidden) for k, o in w.objects.items()} | |
| apply_action(w, Action("point_at", {"target": "blue_stone"})) | |
| apply_action(w, Action("wait", {})) | |
| after = {k: (o.location, o.hidden) for k, o in w.objects.items()} | |
| assert before == after # neither changes world state | |
| # --- win predicates: false at start, true after the intended action ---------- # | |
| def test_win_warmup(): | |
| w = initial_world() | |
| ch = CHALLENGES_BY_ID["warmup"] | |
| assert check_win(w, ch) is False | |
| apply_action(w, Action("put_in", {"obj_id": "red_stone", "container_id": "basket"})) | |
| assert check_win(w, ch) is True | |
| def test_win_hide(): | |
| w = initial_world() | |
| ch = CHALLENGES_BY_ID["hide"] | |
| assert check_win(w, ch) is False | |
| apply_action(w, Action("put_in", {"obj_id": "blue_stone", "container_id": "basket"})) | |
| assert check_win(w, ch) is True | |
| def test_win_gift(): | |
| w = initial_world() | |
| ch = CHALLENGES_BY_ID["gift"] | |
| assert check_win(w, ch) is False | |
| apply_action(w, Action("give", {"obj_id": "blue_stone", "agent_id": "other"})) | |
| assert check_win(w, ch) is True | |
| def test_win_surprise_needs_concealment(): | |
| w = initial_world() | |
| ch = CHALLENGES_BY_ID["surprise"] | |
| assert check_win(w, ch) is False | |
| # merely giving (visible) is NOT a surprise | |
| apply_action(w, Action("give", {"obj_id": "blue_stone", "agent_id": "other"})) | |
| assert check_win(w, ch) is False | |
| # concealing a stone is | |
| apply_action(w, Action("put_in", {"obj_id": "red_stone", "container_id": "basket"})) | |
| assert check_win(w, ch) is True | |
| def test_win_secret(): | |
| w = initial_world() | |
| ch = CHALLENGES_BY_ID["secret"] | |
| assert check_win(w, ch) is False | |
| apply_action(w, Action("put_in", {"obj_id": "blue_stone", "container_id": "basket"})) | |
| assert check_win(w, ch) is True | |
| def test_win_secret_accepts_any_stone(): | |
| # Hiding the red stone counts too — don't fail the player over which object. | |
| w = initial_world() | |
| ch = CHALLENGES_BY_ID["secret"] | |
| apply_action(w, Action("put_in", {"obj_id": "red_stone", "container_id": "basket"})) | |
| assert check_win(w, ch) is True | |