Skip to content

Commit

Permalink
Merge pull request #127 from MarcCote/enh_readme
Browse files Browse the repository at this point in the history
Enh readme
  • Loading branch information
MarcCote committed Feb 7, 2019
2 parents 58857c2 + fd6cacc commit 9406fa3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 44 deletions.
67 changes: 35 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# TextWorld
[![Build Status](https://travis-ci.org/Microsoft/TextWorld.svg?branch=master)](https://travis-ci.org/Microsoft/TextWorld) [![PyPI version](https://badge.fury.io/py/textworld.svg)](https://badge.fury.io/py/textworld)

A text-based game generator and extensible sandbox learning environment for training and testing reinforcement learning (RL) agents. Also check out aka.ms/textworld for more info about TextWorld and its creators.
A text-based game generator and extensible sandbox learning environment for training and testing reinforcement learning (RL) agents. Also check out [aka.ms/textworld](aka.ms/textworld) for more info about TextWorld and its creators.

## Installation

Expand All @@ -12,12 +12,14 @@ TextWorld requires __Python 3__ and only supports __Linux__ and __macOS__ system
TextWorld requires some system libraries for its native components.
On a Debian/Ubuntu-based system, these can be installed with

sudo apt install build-essential libffi-dev python3-dev curl git
sudo apt update && sudo apt install build-essential libffi-dev python3-dev curl git

And on macOS, with

brew install libffi curl git

> **Note:** We advise our users to use virtual environments to avoid Python packages from different projects to interfere with each other. Popular choices are [Conda Environments](https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) and [Virtualenv](https://virtualenv.pypa.io/en/stable/)
### Installing TextWorld

The easiest way to install TextWorld is via [`pip`](https://pypi.org/):
Expand All @@ -28,76 +30,77 @@ Or, after cloning the repo, go inside the root folder of the project (i.e. along

pip install .

### Extras
#### Extras

In order to use the `take_screenshot` or `visualize` functions in `textworld.render`, you'll need to install either the [Chrome](https://sites.google.com/a/chromium.org/chromedriver/) or [Firefox](https://github.com/mozilla/geckodriver) webdriver (depending on which browser you have installed).
If you have Chrome already installed you can use the following command to install chromedriver

pip install chromedriver_installer


## Usage

### Generating a game

TextWorld provides an easy way of generating simple text-based games via the `tw-make` script. For instance,

tw-make custom --world-size 5 --nb-objects 10 --quest-length 5 --seed 1234 --output gen_games/
tw-make custom --world-size 5 --nb-objects 10 --quest-length 5 --seed 1234 --output tw_games/custom_game.ulx

where `custom` indicates we want to customize the game using the following options: `--world-size` controls the number of rooms in the world, `--nb-objects` controls the number of objects that can be interacted with (excluding doors) and `--quest-length` controls the minimum number of commands that is required to type in order to win the game. Once done, the game `game_1234.ulx` will be saved in the `gen_games/` folder.
where `custom` indicates we want to customize the game using the following options: `--world-size` controls the number of rooms in the world, `--nb-objects` controls the number of objects that can be interacted with (excluding doors) and `--quest-length` controls the minimum number of commands that is required to type in order to win the game. Once done, the game `custom_game.ulx` will be saved in the `tw_games/` folder.


### Playing a game (terminal)

To play a game, one can use the `tw-play` script. For instance, the command to play the game generated in the previous section would be

tw-play gen_games/simple_game.ulx
tw-play tw_games/custom_game.ulx

> **Note:** Only Z-machine's games (*.z1 through *.z8) and Glulx's games (*.ulx) are supported.
### Playing a game (Python)
### Playing a game (Python + [Gym](https://github.com/openai/gym))

Here's how you can interact with a text-based game from within Python.
Here's how you can interact with a text-based game from within Python using OpenAI's Gym framework.

```python
import textworld

env = textworld.start("gen_games/game_1234.ulx") # Start an existing game.
agent = textworld.agents.NaiveAgent() # Or your own `textworld.Agent` subclass.
import gym
import textworld.gym

# Collect some statistics: nb_steps, final reward.
avg_moves, avg_scores = [], []
N = 10
for no_episode in range(N):
agent.reset(env) # Tell the agent a new episode is starting.
game_state = env.reset() # Start new episode.
# Register a text-based game as a new Gym's environment.
env_id = textworld.gym.register_game("tw_games/custom_game.ulx",
max_episode_steps=50)

reward = 0
done = False
for no_step in range(100):
command = agent.act(game_state, reward, done)
game_state, reward, done = env.step(command)
env = gym.make(env_id) # Start the environment.

if done:
break
obs, infos = env.reset() # Start new episode.
env.render()

# See https://textworld-docs.maluuba.com/textworld.html#textworld.core.GameState
avg_moves.append(game_state.nb_moves)
avg_scores.append(game_state.score)
score, moves, done = 0, 0, False
while not done:
command = input("> ")
obs, score, done, infos = env.step(command)
env.render()
moves += 1

env.close()
print("avg. steps: {:5.1f}; avg. score: {:4.1f} / 1.".format(sum(avg_moves)/N, sum(avg_scores)/N))
print("moves: {}; score: {}".format(moves, score))
```

> **Note:** To play text-based games without Gym, see [Playing text-based games with TextWorld.ipynb](notebooks/Playing%20text-based%20games%20with%20TextWorld.ipynb)
## Documentation

For more information about TextWorld, check the [documentation](https://aka.ms/textworld-docs).

## Notebooks
Check the [notebooks](notebooks) provided with the framework to see how the framework can be used.

Check the [notebooks](notebooks) provided with the framework to see what you can do with it. You will need the [Jupyter Notebook](https://jupyter.org/install) to run them. You can install it with

pip install jupyter

## Citing TextWorld

If you use TextWorld, please cite the following BibTex:
```

```text
@Article{cote18textworld,
author = {Marc-Alexandre C\^ot\'e and
\'Akos K\'ad\'ar and
Expand Down
18 changes: 6 additions & 12 deletions textworld/generator/inform7/world2inform7.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,7 @@ def gen_source(self, seed: int = 1234) -> str:
else:
center "*** You lost! ***";
say paragraph break;
let X be the turn count;
if restrict commands option is true:
let X be the turn count minus one;
say "You scored [score] out of a possible [maximum score], in [X] turn(s).";
say "You scored [score] out of a possible [maximum score], in [turn count] turn(s).";
[wait for any key;
stop game abruptly;]
rule succeeds.
Expand Down Expand Up @@ -660,10 +657,6 @@ def gen_source(self, seed: int = 1234) -> str:
try looking;
say "[line break]-=STATE STOP=-";
When play begins:
if print state option is true:
try printing the entire state;
Every turn:
if extra description command option is true:
say "<description>";
Expand Down Expand Up @@ -768,7 +761,7 @@ def gen_source(self, seed: int = 1234) -> str:
Turning on the extra description command option is an action applying to nothing.
Carry out turning on the extra description command option:
Decrease turn count by 1;
Decrease turn count by 1; [Internal framework commands shouldn't count as a turn.]
Now the extra description command option is true.
Understand "tw-extra-infos description" as turning on the extra description command option.
Expand All @@ -782,7 +775,7 @@ def gen_source(self, seed: int = 1234) -> str:
Turning on the extra inventory command option is an action applying to nothing.
Carry out turning on the extra inventory command option:
Decrease turn count by 1;
Decrease turn count by 1; [Internal framework commands shouldn't count as a turn.]
Now the extra inventory command option is true.
Understand "tw-extra-infos inventory" as turning on the extra inventory command option.
Expand All @@ -796,7 +789,7 @@ def gen_source(self, seed: int = 1234) -> str:
Turning on the extra score command option is an action applying to nothing.
Carry out turning on the extra score command option:
Decrease turn count by 1;
Decrease turn count by 1; [Internal framework commands shouldn't count as a turn.]
Now the extra score command option is true.
Understand "tw-extra-infos score" as turning on the extra score command option.
Expand All @@ -810,6 +803,7 @@ def gen_source(self, seed: int = 1234) -> str:
Tracing the actions is an action applying to nothing.
Carry out tracing the actions:
Decrease turn count by 1; [Internal framework commands shouldn't count as a turn.]
trace the actions;
Understand "tw-trace-actions" as tracing the actions.
Expand All @@ -823,7 +817,7 @@ def gen_source(self, seed: int = 1234) -> str:
Turning on the restrict commands option is an action applying to nothing.
Carry out turning on the restrict commands option:
Decrease turn count by 1;
Decrease turn count by 1; [Internal framework commands shouldn't count as a turn.]
Now the restrict commands option is true.
Understand "restrict commands" as turning on the restrict commands option.
Expand Down

0 comments on commit 9406fa3

Please sign in to comment.