def record_quest(self, ask_for_state: bool = False) -> Quest: """ Defines the game's quest by recording the commands. This launches a `textworld.play` session. Args: ask_for_state: If true, the user will be asked to specify which set of facts of the final state are should be true in order to consider the quest as completed. Returns: The resulting quest. """ with make_temp_directory() as tmpdir: game_file = self.compile(pjoin(tmpdir, "record_quest")) recorder = Recorder() textworld.play(game_file, wrapper=recorder) # Skip "None" actions. actions = [action for action in recorder.actions if action is not None] # Ask the user which quests have important state, if this is set # (if not, we assume the last action contains all the relevant facts) winning_facts = None if ask_for_state and recorder.last_game_state is not None: winning_facts = user_query.query_for_important_facts(actions=recorder.actions, facts=recorder.last_game_state.state.facts, varinfos=self._working_game.infos) self._quests = [Quest(actions=actions, winning_conditions=winning_facts)] # Calling build will generate the description for the quest. self.build() return self._quests[0]
def set_quest_from_commands(self, commands: List[str], ask_for_state: bool = False) -> Quest: """ Defines the game's quest using predefined text commands. This launches a `textworld.play` session. Args: commands: Text commands. ask_for_state: If true, the user will be asked to specify which set of facts of the final state are should be true in order to consider the quest as completed. Returns: The resulting quest. """ with make_temp_directory() as tmpdir: try: game_file = self.compile(pjoin(tmpdir, "record_quest.ulx")) recorder = Recorder() agent = textworld.agents.WalkthroughAgent(commands) textworld.play(game_file, agent=agent, wrappers=[recorder], silent=True) except textworld.agents.WalkthroughDone: pass # Quest is done. # Skip "None" actions. actions = [action for action in recorder.actions if action is not None] # Ask the user which quests have important state, if this is set # (if not, we assume the last action contains all the relevant facts) winning_facts = None if ask_for_state and recorder.last_game_state is not None: winning_facts = [ user_query.query_for_important_facts( actions=recorder.actions, facts=recorder.last_game_state.state.facts, varinfos=self._working_game.infos) ] if len(commands) != len(actions): unrecognized_commands = [ c for c, a in zip(commands, recorder.actions) if a is None ] raise QuestError( "Some of the actions were unrecognized: {}".format( unrecognized_commands)) event = Event(actions=actions, conditions=winning_facts) self.quests = [Quest(win_events=[event])] # Calling build will generate the description for the quest. self.build() return self.quests[-1]
from typing import List from textworld.logic import Action, Proposition, State from textworld.generator.user_query import query_for_important_facts # noinspection PyAbstractClass class FakeState(State): def __init__(self, parrot_facts: List[Proposition]): super().__init__() self._facts = parrot_facts @property def facts(self): return self._facts # generate fake propositions propositions = [] for i in range(3): new_prop = Proposition(name='thing %d' % (i, )) propositions.append(new_prop) fake_state = FakeState(propositions) # run the test action = Action(name='Test action', preconditions=[], postconditions=propositions) facts = query_for_important_facts(actions=[action], last_game_state=fake_state) print(facts)