Metadata-Version: 2.3
Name: laser-learning-environment
Version: 1.1.2
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Requires-Dist: numpy >=2.1.0
Requires-Dist: multi-agent-rlenv >=1.1.1
Requires-Dist: opencv-python >=4.10.0.84
Summary: Laser Learning Environment (LLE) for Multi-Agent Reinforcement Learning
Author-email: Yannick Molinghen <yannick.molinghen@ulb.be>
Requires-Python: >=3.10, <3.13
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# Laser Learning Environment (LLE)
LLE is a fast Multi-Agent Reinforcement Learning environment written in Rust which has proven to be a difficult exploration benchmark so far. The agents start in the start tiles, must collect the gems and finish the game by reaching the exit tiles. There are five actions: North, South, East, West and Stay. 

When an agent enters a laser of its own colour, it blocks it. Otherwise, it dies and the game ends.

![LLE](docs/lvl6-annotated.png)

# Quick start
## Installation
You can install the Laser Learning Environment with pip or poetry.
```bash
pip install laser-learning-environment # Stable release with pip
poetry add laser-learning-environment  # Stable release with poetry
pip install git+https://github.com/yamoling/lle # latest push on master
```

## Usage
LLE can be used at two levels of abstraction: as an `RLEnv` for cooperative multi-agent reinforcement learning or as a `World` for many other purposes.
### For cooperative multi-agent reinforcement learning
The `LLE` class inherits from the `RLEnv` class in the [rlenv](https://github.com/yamoling/rlenv) framework. Here is an example with the following map: ![LLE](docs/3x1.png)


```python
from lle import LLE

env = LLE.from_str("S0 G X").single_objective()
done = truncated = False
obs = env.reset()
while not (done or truncated):
    # env.render() # Uncomment to render
    actions = env.action_space.sample(env.available_actions())
    obs, reward, done, truncated, info = env.step(actions)
```


### For other purposes or fine grained control
The `World` class provides fine grained control on the environment by exposing the state of the world and the events that happen when the agents move.

```python
from lle import World, Action, EventType

world = World("S0 G X")  # Linear world with start S0, gem G and exit X
world.reset()
available_actions = world.available_actions()[0]  # [Action.STAY, Action.EAST]
events = world.step([Action.EAST])
assert events[0].event_type == EventType.GEM_COLLECTED
events = world.step([Action.EAST])
assert events[0].event_type == EventType.AGENT_EXIT
```

You can also access and force the state of the world
```python
state = world.get_state()
...
events = world.set_state(state)
```

You can query the world on the tiles with `world.start_pos`, `world.exit_pos`, `world.gem_pos`, ...




## Citing our work
The environment has been presented at [EWRL 2023](https://openreview.net/pdf?id=IPfdjr4rIs) and at [BNAIC 2023](https://bnaic2023.tudelft.nl/static/media/BNAICBENELEARN_2023_paper_124.c9f5d29e757e5ee27c44.pdf) where it received the best paper award.

```
@inproceedings{molinghen2023lle,
  title={Laser Learning Environment: A new environment for coordination-critical multi-agent tasks},
  author={Molinghen, Yannick and Avalos, Raphaël and Van Achter, Mark and Nowé, Ann and Lenaerts, Tom},
  year={2023},
  series={BeNeLux Artificial Intelligence Conference},
  booktitle={BNAIC 2023}
}
```

## Development
If you want to modify the environment, you can clone the repo, install the python dependencies then compile it with `maturin`.
```
git clone https://github.com/yamoling/lle
poetry shell # start the virtual environment
poetry install
maturin develop # install lle locally
```


## Building
This project has been set up with maturin. Install maturin in a virtual environment with your preferred manner (manual, venv, uv, poetry, ...) and run
```bash
maturin develop  # For development
maturin build    # For distribution
```

## Tests
This project **does not** respect Rust unit tests convention and takes inspiration from [this structure](http://xion.io/post/code/rust-unit-test-placement.html). Unit tests are in the `src/unit_tests` folder and are explicitely linked to in each file with the `#path` directive. 
Integration tests are written on the python side.

Run unit tests with 
```bash
cargo test
```

Run integration tests with
```bash
maturin develop
pytest
```

