@@ -89,7 +89,7 @@ def _detect_i7_events_debug_tags(text: str) -> Tuple[List[str], str]:
8989 """
9090 matches = []
9191 open_tags = []
92- for match in re .findall ("\[[^]]+\]\n ?" , text ):
92+ for match in re .findall (r "\[[^]]+\]\n?" , text ):
9393 text = text .replace (match , "" ) # Remove i7 debug tags.
9494 tag_name = match .strip ()[1 :- 1 ] # Strip starting '[' and trailing ']'.
9595
@@ -127,12 +127,12 @@ def __init__(self, *args, **kwargs):
127127 :param kwargs: The kwargs
128128 """
129129 super ().__init__ (* args , ** kwargs )
130- self ._has_won = False
131- self ._has_lost = False
130+ self .has_timeout = False
132131 self ._state_tracking = False
133132 self ._compute_intermediate_reward = False
133+ self ._max_score = 0
134134
135- def init (self , output : str , game = None ,
135+ def init (self , output : str , game : Game ,
136136 state_tracking : bool = False , compute_intermediate_reward : bool = False ):
137137 """
138138 Initialize the game state and set tracking parameters.
@@ -149,10 +149,9 @@ def init(self, output: str, game=None,
149149 self ._game_progression = GameProgression (game , track_quests = compute_intermediate_reward )
150150 self ._state_tracking = state_tracking
151151 self ._compute_intermediate_reward = compute_intermediate_reward and len (game .quests ) > 0
152-
153- self ._objective = ""
154- if len (game .quests ) > 0 :
155- self ._objective = game .quests [0 ].desc
152+ self ._objective = game .objective
153+ self ._score = 0
154+ self ._max_score = self ._game_progression .max_score
156155
157156 def view (self ) -> "GlulxGameState" :
158157 """
@@ -177,6 +176,7 @@ def view(self) -> "GlulxGameState":
177176 game_state ._nb_moves = self .nb_moves
178177 game_state ._has_won = self .has_won
179178 game_state ._has_lost = self .has_lost
179+ game_state .has_timeout = self .has_timeout
180180
181181 if self ._state_tracking :
182182 game_state ._admissible_commands = self .admissible_commands
@@ -199,6 +199,7 @@ def update(self, command: str, output: str) -> "GlulxGameState":
199199 game_state = super ().update (command , output )
200200 game_state .previous_state = self .view ()
201201 game_state ._objective = self .objective
202+ game_state ._max_score = self .max_score
202203 game_state ._game_progression = self ._game_progression
203204 game_state ._state_tracking = self ._state_tracking
204205 game_state ._compute_intermediate_reward = self ._compute_intermediate_reward
@@ -215,12 +216,6 @@ def update(self, command: str, output: str) -> "GlulxGameState":
215216 # An action that affects the state of the game.
216217 game_state ._game_progression .update (game_state ._action )
217218
218- if game_state ._compute_intermediate_reward :
219- if game_state ._game_progression .winning_policy is None :
220- game_state ._has_lost = True
221- elif len (game_state ._game_progression .winning_policy ) == 0 :
222- game_state ._has_won = True
223-
224219 return game_state
225220
226221 @property
@@ -317,24 +312,54 @@ def intermediate_reward(self):
317312
318313 @property
319314 def score (self ):
320- if self .has_won :
321- return 1
322- elif self .has_lost :
323- return - 1
324-
325- return 0
315+ if not hasattr (self , "_score" ):
316+ if self ._state_tracking :
317+ self ._score = self ._game_progression .score
318+ else :
319+
320+ # Check if there was any Inform7 events.
321+ if self ._feedback == self ._raw :
322+ self ._score = self .previous_state .score
323+ else :
324+ output = self ._raw
325+ if not self .game_ended :
326+ output = self ._env ._send ("score" )
327+
328+ match = re .search ("scored (?P<score>[0-9]+) out of a possible (?P<max_score>[0-9]+)," , output )
329+ self ._score = 0
330+ if match :
331+ self ._score = int (match .groupdict ()["score" ])
332+
333+ return self ._score
326334
327335 @property
328336 def max_score (self ):
329- return 1
337+ return self . _max_score
330338
331339 @property
332340 def has_won (self ):
333- return self ._has_won or '*** The End ***' in self .feedback
341+ if not hasattr (self , "_has_won" ):
342+ if self ._compute_intermediate_reward :
343+ self ._has_won = self ._game_progression .completed
344+ else :
345+ self ._has_won = '*** The End ***' in self .feedback
346+
347+ return self ._has_won
334348
335349 @property
336350 def has_lost (self ):
337- return self ._has_lost or '*** You lost! ***' in self .feedback
351+ if not hasattr (self , "_has_lost" ):
352+ if self ._compute_intermediate_reward :
353+ self ._has_lost = self ._game_progression .failed
354+ else :
355+ self ._has_lost = '*** You lost! ***' in self .feedback
356+
357+ return self ._has_lost
358+
359+ @property
360+ def game_ended (self ) -> bool :
361+ """ Whether the game is finished or not. """
362+ return self .has_won | self .has_lost | self .has_timeout
338363
339364 @property
340365 def game_infos (self ) -> Mapping :
@@ -439,8 +464,8 @@ def step(self, command: str) -> Tuple[GlulxGameState, float, bool]:
439464 raise GameNotRunningError ()
440465
441466 self .game_state = self .game_state .update (command , output )
442- done = self .game_state .game_ended or not self .game_running
443- return self .game_state , self .game_state .score , done
467+ self .game_state .has_timeout = not self .game_running
468+ return self .game_state , self .game_state .score , self . game_state . game_ended
444469
445470 def _send (self , command : str ) -> Union [str , None ]:
446471 if not self .game_running :
0 commit comments