microsoft / TextWorld

​TextWorld is a sandbox learning environment for the training and evaluation of reinforcement learning (RL) agents on text-based games.
Other
1.23k stars 189 forks source link

Can we obtain the game map in a data format? #187

Closed ankitvad closed 5 years ago

ankitvad commented 5 years ago

Hi, I've found out the --overview and --save-overview option which can generate an image representation of the generated game map with the locations and the inventory/objective. Is there a way to obtain the generated game graph/map? Which contains the different rooms and the connection label between the rooms? For example, Kitchen and a connection west to room..etc. in a text/JSON/graph format etc.. something other than an image..

Or maybe there is someplace in the repo. from where I can obtain this information? Thanks.

MarcCote commented 5 years ago

Hi @ankitvad, the underlying representation can be obtained by looking at the facts of the world.

Here a small example. At the moment, the following requires the master branch.

import gym
import textworld
import textworld.gym

options = textworld.GameOptions()
options.seeds = 1234
gamefile, game = textworld.make(options)

env_infos = textworld.EnvInfos(facts=True)
env_id = textworld.gym.register_game(gamefile, env_infos)
env = gym.make(env_id)
obs, infos = env.reset()

from pprint import pprint
pprint(infos["facts"])

# Uncomment the next line to see the overview image.
# textworld.render.visualize(game, interactive=True)

Running the above code, outputs the following

[Proposition('at', (Variable(None, 'P'), Variable('attic', 'r'))),
 Proposition('at', (Variable('type G chest', 'c'), Variable('attic', 'r'))),
 Proposition('in', (Variable('type G key', 'k'), Variable(None, 'I'))),
 Proposition('locked', (Variable('type G chest', 'c'),)),
 Proposition('match', (Variable('type G key', 'k'), Variable('type G chest', 'c')))]

I hope that helps. Let me know if that's not what you were looking for.

ankitvad commented 5 years ago

Hi @MarcCote thanks for the reply. While this is definitely helpful..I was more interested in obtaining the location orientation (wrt each other) information. For example:
https://github.com/microsoft/TextWorld/blob/f1ac489fefeb6a48684ed1f89422b84b7b4a6e4b/textworld/challenges/simple.py#L100

Something like this. Ideally I’d like the whole map information in a parsable and processable way. Something that’s like a graph where the nodes are the different room, then those have sub graphs with nodes representing objects in the room and the property(exactly like the inventory information in the visualize diagram). Primarily, I’d like to get the location information for each room. Ie. let’s say the kitchen has a connection to the bathroom on the east side, as a result kitchen will be east to the kitchen.. etc. Can I call some parameter to give me this information? The info. That is parsed to create the visualize diagram.. that has objects locations and the location orientation wrt to each other. Ie. north of, east of, etc.

MarcCote commented 5 years ago

Yea, so the list of facts contains that information for sure as it is used to generate the overview figures. Each fact can be seen as a named relation between two entities. With the facts, you can generate something like this image

ankitvad commented 5 years ago

Oh.. this is perfect. :D Thanks! I wasn’t able to find the N/E/W/S information in the example above. But I get it.. that’s just a single room. Thanks for the information.

MarcCote commented 5 years ago

Great! PS: in order to generate the figure above, I had to alter the facts a bit (e.g. even though we see an exit node in the graph, there's no such thing in TW - at the moment). So, do not hesitate to reach out to us if you need help.

ankitvad commented 5 years ago

I’m sorry, I’m not able to see the exit node. Where is that exactly? In the diagram?

MarcCote commented 5 years ago

My bad. I was thinking of another figure. There's indeed no exit node. So, another example of graph manipulation would be the link(r, d, r') predicate which is used in TextWorld to indicate two rooms are connected to each via a door. However, that link predicate doesn't tell you in which direction the two rooms are connected. For that, you have to look for the corresponding {dir}_of(r, r') predicates.

For instance,

link(kitchen, door, living room)
north_of(kitchen, living room)  # Read as the kitchen is north of the living room.
south_of(livingroom, kitchen)

has been translated to

north_of(door, kitchen)  # Read as the door is on the north wall of the kitchen.
south_of(door, livingroom)
ankitvad commented 5 years ago

Hi, @MarcCote I had one additional question. If I’m using the EnvInfo filter to obtain all admissible commands at each step, is there a way to retain the env state?
I’m consulting this: https://colab.research.google.com/github/yfletberliac/rlss-2019/blob/master/labs/final_project/TextWorld.ipynb#scrollTo=Ig7o6cMPEGqg

Every time I do something like - r1 = env.step(“some command”) the env state changes. If at an env state there are 5 commands that are admissible And I’d like to run all of them one by one to see the change in description/state and reward for the initial state. Is there any way to accomplish this without resetting the environment and playing the whole game till that point again? Can I maybe copy the environment? But not a reference copy like a complete separate element? Or something else? Or maybe there’s a way to go back 1 step? Any info. Will be helpful? Thanks.

MarcCote commented 5 years ago

Unfortunately, the only way to achieve what you want at the moment is to do a reset and replay the previous commands. The main reason is that we depend on the state of the game interpreter (here git-glulx) which is running in another process.

That said, I can think of a way we could support a "snapshot" functionality but that would require some tinkering. If you don't mind, can you create an issue for this?

PS: is that your colab notebook? It looks great. EDIT: oh I see it was part of a summer school. @yfletberliac I like it.

ankitvad commented 5 years ago

@MarcCote Yup. Makes sense. Thanks. Sure, I'll create an issue.
Yes, it's part of this repo - https://github.com/yfletberliac/rlss-2019.

ankitvad commented 5 years ago

Yea, so the list of facts contains that information for sure as it is used to generate the overview figures. Each fact can be seen as a named relation between two entities. With the facts, you can generate something like this image @MarcCote Also, is there an option in TextWorld to obtain an overview of the map like in the image? Or should I parse the facts and create this knowledge graph myself? Could you share the script you used to generate the KG from the facts?

MarcCote commented 5 years ago

@ankitvad can you try this PR https://github.com/microsoft/TextWorld/pull/189 Check the example section of the docstring for textworld.render.graph.show_graph.