irregular6612 commited on
Commit
b89d17e
·
1 Parent(s): 64948f6

feat(engine): additive Scenario.check_success early-win hook (default False)

Browse files
proteus/game/engine/grid.py CHANGED
@@ -176,6 +176,8 @@ class MotiveGridGame(ARCBaseGame):
176
 
177
  if self.scenario.check_elimination(self):
178
  self.lose()
 
 
179
  elif self.step_count >= self.max_steps:
180
  self.win()
181
 
 
176
 
177
  if self.scenario.check_elimination(self):
178
  self.lose()
179
+ elif self.scenario.check_success(self):
180
+ self.win()
181
  elif self.step_count >= self.max_steps:
182
  self.win()
183
 
proteus/game/scenarios/base.py CHANGED
@@ -144,6 +144,22 @@ class Scenario(ABC):
144
  """
145
  raise NotImplementedError
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  @abstractmethod
148
  def optimal_action(self, game: MotiveGridGame) -> str:
149
  """Return the motive-congruent correct next action (the prediction key).
 
144
  """
145
  raise NotImplementedError
146
 
147
+ def check_success(self, game: MotiveGridGame) -> bool:
148
+ """Return whether the focal has achieved the scenario goal (early win).
149
+
150
+ Default ``False``: most scenarios end only on elimination or the step
151
+ budget. Goal-reaching scenarios (e.g. ``take_a_seat``) override this to
152
+ win the moment the goal is met.
153
+
154
+ Args:
155
+ game: The live game to inspect (POST-move state).
156
+
157
+ Returns:
158
+ ``True`` to end the episode as a win this turn, else ``False``.
159
+ """
160
+ del game
161
+ return False
162
+
163
  @abstractmethod
164
  def optimal_action(self, game: MotiveGridGame) -> str:
165
  """Return the motive-congruent correct next action (the prediction key).
tests/engine/test_check_success_hook.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # tests/engine/test_check_success_hook.py
2
+ import random
3
+
4
+ from proteus.game.engine.difficulty import Difficulty
5
+ from proteus.game.engine.grid import MotiveGridGame
6
+ from proteus.game.scenarios.base import Scenario, get_scenario
7
+ import proteus.game.scenarios # noqa: F401
8
+
9
+
10
+ def test_default_check_success_is_false():
11
+ # Base hook is opt-in: existing scenarios never win early.
12
+ scen = get_scenario("resource_race")()
13
+ game = MotiveGridGame(scen, random.Random(0), Difficulty.EASY, max_steps=40)
14
+ assert scen.check_success(game) is False
15
+
16
+
17
+ def test_check_success_triggers_early_win():
18
+ # A scenario whose check_success returns True wins on the very first step.
19
+ base = get_scenario("resource_race")()
20
+
21
+ class _AlwaysWin(type(base)): # reuse a concrete scenario, override the hook
22
+ def check_success(self, game):
23
+ return True
24
+
25
+ scen = _AlwaysWin()
26
+ game = MotiveGridGame(scen, random.Random(0), Difficulty.EASY, max_steps=99)
27
+ game.apply_motive_action("stay")
28
+ assert game.survived is True
29
+ assert game.step_count == 1 # won before the step budget