multi-agent-rlenv 3.3.0__tar.gz → 3.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/.github/workflows/ci.yaml +4 -4
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/.github/workflows/docs.yaml +1 -1
- multi_agent_rlenv-3.3.0/README.md → multi_agent_rlenv-3.3.1/PKG-INFO +59 -2
- multi_agent_rlenv-3.3.0/PKG-INFO → multi_agent_rlenv-3.3.1/README.md +24 -17
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/pyproject.toml +21 -1
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/__init__.py +1 -1
- multi_agent_rlenv-3.3.1/src/marlenv/adapters/__init__.py +42 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/adapters/overcooked_adapter.py +43 -13
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/env_builder.py +26 -49
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/env_pool.py +0 -1
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/models/observation.py +6 -1
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/tests/test_adapters.py +56 -24
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/tests/test_serialization.py +7 -1
- multi_agent_rlenv-3.3.0/src/marlenv/adapters/__init__.py +0 -32
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/.gitignore +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/LICENSE +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/adapters/gym_adapter.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/adapters/pettingzoo_adapter.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/adapters/pymarl_adapter.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/adapters/smac_adapter.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/exceptions.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/mock_env.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/models/__init__.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/models/env.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/models/episode.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/models/spaces.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/models/state.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/models/step.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/models/transition.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/py.typed +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/__init__.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/agent_id_wrapper.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/available_actions_mask.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/available_actions_wrapper.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/blind_wrapper.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/centralised.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/delayed_rewards.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/last_action_wrapper.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/paddings.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/penalty_wrapper.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/rlenv_wrapper.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/time_limit.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/video_recorder.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/tests/__init__.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/tests/test_episode.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/tests/test_models.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/tests/test_pool.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/tests/test_spaces.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/tests/test_wrappers.py +0 -0
- {multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/tests/utils.py +0 -0
|
@@ -21,8 +21,8 @@ jobs:
|
|
|
21
21
|
matrix:
|
|
22
22
|
os:
|
|
23
23
|
- ubuntu-latest
|
|
24
|
-
- windows-latest
|
|
25
24
|
- macOS-latest
|
|
25
|
+
- windows-latest
|
|
26
26
|
target:
|
|
27
27
|
- x86_64
|
|
28
28
|
- aarch64
|
|
@@ -43,16 +43,16 @@ jobs:
|
|
|
43
43
|
- name: Install uv
|
|
44
44
|
uses: yezz123/setup-uv@v4
|
|
45
45
|
with:
|
|
46
|
-
uv-version: 0.
|
|
46
|
+
uv-version: 0.6.4
|
|
47
47
|
- name: Install dependencies and run pytest
|
|
48
48
|
run: |
|
|
49
|
-
uv sync
|
|
49
|
+
uv sync --extra overcooked --extra gym --extra pettingzoo
|
|
50
50
|
uv run pytest
|
|
51
51
|
|
|
52
52
|
build:
|
|
53
53
|
name: 📦 Build package
|
|
54
54
|
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
|
|
55
|
-
needs: test
|
|
55
|
+
needs: [test]
|
|
56
56
|
runs-on: ubuntu-latest
|
|
57
57
|
steps:
|
|
58
58
|
- uses: actions/checkout@v4
|
|
@@ -1,8 +1,65 @@
|
|
|
1
|
-
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: multi-agent-rlenv
|
|
3
|
+
Version: 3.3.1
|
|
4
|
+
Summary: A strongly typed Multi-Agent Reinforcement Learning framework
|
|
5
|
+
Project-URL: repository, https://github.com/yamoling/multi-agent-rlenv
|
|
6
|
+
Author-email: Yannick Molinghen <yannick.molinghen@ulb.be>
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Requires-Python: <4,>=3.10
|
|
11
|
+
Requires-Dist: numpy>=2.0.0
|
|
12
|
+
Requires-Dist: opencv-python>=4.0
|
|
13
|
+
Requires-Dist: typing-extensions>=4.0
|
|
14
|
+
Provides-Extra: all
|
|
15
|
+
Requires-Dist: gymnasium>0.29.1; extra == 'all'
|
|
16
|
+
Requires-Dist: overcooked-ai; extra == 'all'
|
|
17
|
+
Requires-Dist: pettingzoo>=1.20; extra == 'all'
|
|
18
|
+
Requires-Dist: pymunk>=6.0; extra == 'all'
|
|
19
|
+
Requires-Dist: pysc2; extra == 'all'
|
|
20
|
+
Requires-Dist: scipy>=1.10; extra == 'all'
|
|
21
|
+
Requires-Dist: smac; extra == 'all'
|
|
22
|
+
Provides-Extra: gym
|
|
23
|
+
Requires-Dist: gymnasium>=0.29.1; extra == 'gym'
|
|
24
|
+
Provides-Extra: overcooked
|
|
25
|
+
Requires-Dist: overcooked-ai>=1.1.0; extra == 'overcooked'
|
|
26
|
+
Requires-Dist: scipy>=1.10; extra == 'overcooked'
|
|
27
|
+
Provides-Extra: pettingzoo
|
|
28
|
+
Requires-Dist: pettingzoo>=1.20; extra == 'pettingzoo'
|
|
29
|
+
Requires-Dist: pymunk>=6.0; extra == 'pettingzoo'
|
|
30
|
+
Requires-Dist: scipy>=1.10; extra == 'pettingzoo'
|
|
31
|
+
Provides-Extra: smac
|
|
32
|
+
Requires-Dist: pysc2; extra == 'smac'
|
|
33
|
+
Requires-Dist: smac; extra == 'smac'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# `marlenv` - A unified framework for muti-agent reinforcement learning
|
|
37
|
+
**Documentation: [https://yamoling.github.io/multi-agent-rlenv](https://yamoling.github.io/multi-agent-rlenv)**
|
|
38
|
+
|
|
2
39
|
The objective of `marlenv` is to provide a common (typed) interface for many different reinforcement learning environments.
|
|
3
40
|
|
|
4
41
|
As such, `marlenv` provides high level abstractions of RL concepts such as `Observation`s or `Transition`s that are commonly represented as mere (confusing) lists or tuples.
|
|
5
42
|
|
|
43
|
+
## Installation
|
|
44
|
+
Install with you preferred package manager (`uv`, `pip`, `poetry`, ...):
|
|
45
|
+
```bash
|
|
46
|
+
$ pip install marlenv[all] # Enable all features
|
|
47
|
+
$ pip install marlenv # Basic installation
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
There are multiple optional dependencies if you want to support specific libraries and environments. Available options are:
|
|
51
|
+
- `smac` for StarCraft II environments
|
|
52
|
+
- `gym` for OpenAI Gym environments
|
|
53
|
+
- `pettingzoo` for PettingZoo environments
|
|
54
|
+
- `overcooked` for Overcooked environments
|
|
55
|
+
|
|
56
|
+
Install them with:
|
|
57
|
+
```bash
|
|
58
|
+
$ pip install marlenv[smac] # Install SMAC
|
|
59
|
+
$ pip install marlenv[gym,smac] # Install Gym & smac support
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
|
|
6
63
|
## Using `marlenv` with existing libraries
|
|
7
64
|
`marlenv` unifies multiple popular libraries under a single interface. Namely, `marlenv` supports `smac`, `gymnasium` and `pettingzoo`.
|
|
8
65
|
|
|
@@ -32,7 +89,7 @@ from marlenv import RLEnv, DiscreteActionSpace, Observation
|
|
|
32
89
|
N_AGENTS = 3
|
|
33
90
|
N_ACTIONS = 5
|
|
34
91
|
|
|
35
|
-
class CustomEnv(
|
|
92
|
+
class CustomEnv(MARLEnv[DiscreteActionSpace]):
|
|
36
93
|
def __init__(self, width: int, height: int):
|
|
37
94
|
super().__init__(
|
|
38
95
|
action_space=DiscreteActionSpace(N_AGENTS, N_ACTIONS),
|
|
@@ -1,23 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Summary: A strongly typed Multi-Agent Reinforcement Learning framework
|
|
5
|
-
Project-URL: repository, https://github.com/yamoling/multi-agent-rlenv
|
|
6
|
-
Author-email: Yannick Molinghen <yannick.molinghen@ulb.be>
|
|
7
|
-
License-File: LICENSE
|
|
8
|
-
Classifier: Operating System :: OS Independent
|
|
9
|
-
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Requires-Python: <4,>=3.10
|
|
11
|
-
Requires-Dist: gymnasium>=0.29.1
|
|
12
|
-
Requires-Dist: numpy>=2.0.0
|
|
13
|
-
Requires-Dist: opencv-python>=4.10.0.84
|
|
14
|
-
Description-Content-Type: text/markdown
|
|
15
|
-
|
|
16
|
-
# `marlenv` - A unified interface for muti-agent reinforcement learning
|
|
1
|
+
# `marlenv` - A unified framework for muti-agent reinforcement learning
|
|
2
|
+
**Documentation: [https://yamoling.github.io/multi-agent-rlenv](https://yamoling.github.io/multi-agent-rlenv)**
|
|
3
|
+
|
|
17
4
|
The objective of `marlenv` is to provide a common (typed) interface for many different reinforcement learning environments.
|
|
18
5
|
|
|
19
6
|
As such, `marlenv` provides high level abstractions of RL concepts such as `Observation`s or `Transition`s that are commonly represented as mere (confusing) lists or tuples.
|
|
20
7
|
|
|
8
|
+
## Installation
|
|
9
|
+
Install with you preferred package manager (`uv`, `pip`, `poetry`, ...):
|
|
10
|
+
```bash
|
|
11
|
+
$ pip install marlenv[all] # Enable all features
|
|
12
|
+
$ pip install marlenv # Basic installation
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
There are multiple optional dependencies if you want to support specific libraries and environments. Available options are:
|
|
16
|
+
- `smac` for StarCraft II environments
|
|
17
|
+
- `gym` for OpenAI Gym environments
|
|
18
|
+
- `pettingzoo` for PettingZoo environments
|
|
19
|
+
- `overcooked` for Overcooked environments
|
|
20
|
+
|
|
21
|
+
Install them with:
|
|
22
|
+
```bash
|
|
23
|
+
$ pip install marlenv[smac] # Install SMAC
|
|
24
|
+
$ pip install marlenv[gym,smac] # Install Gym & smac support
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
|
|
21
28
|
## Using `marlenv` with existing libraries
|
|
22
29
|
`marlenv` unifies multiple popular libraries under a single interface. Namely, `marlenv` supports `smac`, `gymnasium` and `pettingzoo`.
|
|
23
30
|
|
|
@@ -47,7 +54,7 @@ from marlenv import RLEnv, DiscreteActionSpace, Observation
|
|
|
47
54
|
N_AGENTS = 3
|
|
48
55
|
N_ACTIONS = 5
|
|
49
56
|
|
|
50
|
-
class CustomEnv(
|
|
57
|
+
class CustomEnv(MARLEnv[DiscreteActionSpace]):
|
|
51
58
|
def __init__(self, width: int, height: int):
|
|
52
59
|
super().__init__(
|
|
53
60
|
action_space=DiscreteActionSpace(N_AGENTS, N_ACTIONS),
|
|
@@ -7,13 +7,28 @@ authors = [
|
|
|
7
7
|
]
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
requires-python = ">=3.10, <4"
|
|
10
|
-
dependencies = ["numpy>=2.0.0", "opencv-python>=4.10.0.84", "gymnasium>=0.29.1"]
|
|
11
10
|
urls = { "repository" = "https://github.com/yamoling/multi-agent-rlenv" }
|
|
12
11
|
classifiers = [
|
|
13
12
|
"Programming Language :: Python :: 3",
|
|
14
13
|
"Operating System :: OS Independent",
|
|
15
14
|
]
|
|
16
15
|
|
|
16
|
+
dependencies = ["numpy>=2.0.0", "opencv-python>=4.0", "typing_extensions>=4.0"]
|
|
17
|
+
|
|
18
|
+
[project.optional-dependencies]
|
|
19
|
+
gym = ["gymnasium>=0.29.1"]
|
|
20
|
+
smac = ["smac", "pysc2"]
|
|
21
|
+
pettingzoo = ["pettingzoo>=1.20", "pymunk>=6.0", "scipy>=1.10"]
|
|
22
|
+
overcooked = ["overcooked-ai>=1.1.0", "scipy>=1.10"]
|
|
23
|
+
all = [
|
|
24
|
+
"gymnasium>0.29.1",
|
|
25
|
+
"pettingzoo>=1.20",
|
|
26
|
+
"overcooked-ai",
|
|
27
|
+
"smac",
|
|
28
|
+
"pysc2",
|
|
29
|
+
"pymunk>=6.0",
|
|
30
|
+
"scipy>=1.10",
|
|
31
|
+
]
|
|
17
32
|
|
|
18
33
|
[build-system]
|
|
19
34
|
requires = ["hatchling"]
|
|
@@ -35,5 +50,10 @@ pythonpath = "src"
|
|
|
35
50
|
# Ignore deprecation warnings caused by SMAC
|
|
36
51
|
filterwarnings = "ignore::DeprecationWarning"
|
|
37
52
|
|
|
53
|
+
[tool.uv.sources]
|
|
54
|
+
smac = { git = "https://github.com/oxwhirl/smac.git" }
|
|
55
|
+
pysc2 = { git = "https://github.com/google-deepmind/pysc2.git" }
|
|
56
|
+
|
|
57
|
+
|
|
38
58
|
[dependency-groups]
|
|
39
59
|
dev = ["orjson>=3.10.12", "pdoc>=15.0.1", "pytest>=8.3.2"]
|
|
@@ -62,7 +62,7 @@ print(env.extras_shape) # (1, )
|
|
|
62
62
|
If you want to create a new environment, you can simply create a class that inherits from `MARLEnv`. If you want to create a wrapper around an existing `MARLEnv`, you probably want to subclass `RLEnvWrapper` which implements a default behaviour for every method.
|
|
63
63
|
"""
|
|
64
64
|
|
|
65
|
-
__version__ = "3.3.
|
|
65
|
+
__version__ = "3.3.1"
|
|
66
66
|
|
|
67
67
|
from . import models
|
|
68
68
|
from . import wrappers
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from importlib.util import find_spec
|
|
2
|
+
from .pymarl_adapter import PymarlAdapter
|
|
3
|
+
|
|
4
|
+
HAS_GYM = False
|
|
5
|
+
if find_spec("gymnasium") is not None:
|
|
6
|
+
from .gym_adapter import Gym
|
|
7
|
+
|
|
8
|
+
HAS_GYM = True
|
|
9
|
+
|
|
10
|
+
HAS_PETTINGZOO = False
|
|
11
|
+
if find_spec("pettingzoo") is not None:
|
|
12
|
+
from .pettingzoo_adapter import PettingZoo
|
|
13
|
+
|
|
14
|
+
HAS_PETTINGZOO = True
|
|
15
|
+
|
|
16
|
+
HAS_SMAC = False
|
|
17
|
+
if find_spec("smac") is not None:
|
|
18
|
+
from .smac_adapter import SMAC
|
|
19
|
+
|
|
20
|
+
HAS_SMAC = True
|
|
21
|
+
|
|
22
|
+
HAS_OVERCOOKED = False
|
|
23
|
+
if find_spec("overcooked_ai_py.mdp") is not None:
|
|
24
|
+
import numpy
|
|
25
|
+
|
|
26
|
+
# Overcooked assumes a version of numpy <2.0 where np.Inf is available.
|
|
27
|
+
setattr(numpy, "Inf", numpy.inf)
|
|
28
|
+
from .overcooked_adapter import Overcooked
|
|
29
|
+
|
|
30
|
+
HAS_OVERCOOKED = True
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
"PymarlAdapter",
|
|
34
|
+
"Gym",
|
|
35
|
+
"PettingZoo",
|
|
36
|
+
"SMAC",
|
|
37
|
+
"Overcooked",
|
|
38
|
+
"HAS_GYM",
|
|
39
|
+
"HAS_PETTINGZOO",
|
|
40
|
+
"HAS_SMAC",
|
|
41
|
+
"HAS_OVERCOOKED",
|
|
42
|
+
]
|
{multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/adapters/overcooked_adapter.py
RENAMED
|
@@ -1,41 +1,71 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import pygame
|
|
3
|
-
import cv2
|
|
4
1
|
import sys
|
|
5
|
-
from
|
|
2
|
+
from dataclasses import dataclass
|
|
6
3
|
from typing import Literal, Sequence
|
|
4
|
+
|
|
5
|
+
import cv2
|
|
6
|
+
import numpy as np
|
|
7
7
|
import numpy.typing as npt
|
|
8
|
-
|
|
8
|
+
import pygame
|
|
9
|
+
from marlenv.models import ContinuousSpace, DiscreteActionSpace, MARLEnv, Observation, State, Step
|
|
10
|
+
|
|
9
11
|
from overcooked_ai_py.mdp.overcooked_env import OvercookedEnv
|
|
12
|
+
from overcooked_ai_py.mdp.overcooked_mdp import Action, OvercookedGridworld, OvercookedState
|
|
10
13
|
from overcooked_ai_py.visualization.state_visualizer import StateVisualizer
|
|
11
|
-
from dataclasses import dataclass
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
@dataclass
|
|
15
17
|
class Overcooked(MARLEnv[Sequence[int] | npt.NDArray, DiscreteActionSpace]):
|
|
18
|
+
horizon: int
|
|
19
|
+
|
|
16
20
|
def __init__(self, oenv: OvercookedEnv):
|
|
17
21
|
self._oenv = oenv
|
|
18
22
|
assert isinstance(oenv.mdp, OvercookedGridworld)
|
|
19
23
|
self._mdp = oenv.mdp
|
|
20
24
|
self.visualizer = StateVisualizer()
|
|
25
|
+
shape = tuple(int(s) for s in self._mdp.get_lossless_state_encoding_shape())
|
|
26
|
+
shape = (shape[2], shape[0], shape[1])
|
|
21
27
|
super().__init__(
|
|
22
|
-
action_space=DiscreteActionSpace(
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
action_space=DiscreteActionSpace(
|
|
29
|
+
n_agents=self._mdp.num_players,
|
|
30
|
+
n_actions=Action.NUM_ACTIONS,
|
|
31
|
+
action_names=[Action.ACTION_TO_CHAR[a] for a in Action.ALL_ACTIONS],
|
|
32
|
+
),
|
|
33
|
+
observation_shape=shape,
|
|
34
|
+
extras_shape=(1,),
|
|
35
|
+
extras_meanings=["timestep"],
|
|
36
|
+
state_shape=shape,
|
|
37
|
+
state_extra_shape=(1,),
|
|
38
|
+
reward_space=ContinuousSpace.from_shape(1),
|
|
25
39
|
)
|
|
40
|
+
self.horizon = int(self._oenv.horizon)
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def state(self) -> OvercookedState:
|
|
44
|
+
"""Current state of the environment"""
|
|
45
|
+
return self._oenv.state
|
|
46
|
+
|
|
47
|
+
def set_state(self, state: State):
|
|
48
|
+
raise NotImplementedError("Not yet implemented")
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def time_step(self):
|
|
52
|
+
return self.state.timestep
|
|
26
53
|
|
|
27
54
|
def _state_data(self):
|
|
28
|
-
state = self.
|
|
29
|
-
state = np.array(self._mdp.lossless_state_encoding(state))
|
|
55
|
+
state = np.array(self._mdp.lossless_state_encoding(self.state))
|
|
30
56
|
# Use axes (agents, channels, height, width) instead of (agents, height, width, channels)
|
|
31
57
|
state = np.transpose(state, (0, 3, 1, 2))
|
|
32
58
|
return state
|
|
33
59
|
|
|
34
60
|
def get_state(self):
|
|
35
|
-
return State(self._state_data())
|
|
61
|
+
return State(self._state_data()[0], np.array([self.time_step / self.horizon]))
|
|
36
62
|
|
|
37
63
|
def get_observation(self) -> Observation:
|
|
38
|
-
return Observation(
|
|
64
|
+
return Observation(
|
|
65
|
+
data=self._state_data(),
|
|
66
|
+
available_actions=self.available_actions(),
|
|
67
|
+
extras=np.array([[self.time_step / self.horizon]] * self.n_agents),
|
|
68
|
+
)
|
|
39
69
|
|
|
40
70
|
def available_actions(self):
|
|
41
71
|
available_actions = np.full((self.n_agents, self.n_actions), False)
|
|
@@ -1,32 +1,27 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from typing import Generic, Literal, Optional, TypeVar, overload
|
|
3
|
-
|
|
4
3
|
import numpy as np
|
|
5
4
|
import numpy.typing as npt
|
|
6
5
|
|
|
7
6
|
from . import wrappers
|
|
7
|
+
from marlenv import adapters
|
|
8
8
|
from .models import ActionSpace, MARLEnv
|
|
9
|
-
from .adapters import PettingZoo
|
|
10
9
|
|
|
11
10
|
A = TypeVar("A")
|
|
12
11
|
AS = TypeVar("AS", bound=ActionSpace)
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
if adapters.HAS_PETTINGZOO:
|
|
14
|
+
from .adapters import PettingZoo
|
|
15
15
|
from pettingzoo import ParallelEnv
|
|
16
16
|
|
|
17
17
|
@overload
|
|
18
|
-
def make(
|
|
19
|
-
env: ParallelEnv,
|
|
20
|
-
) -> PettingZoo: ...
|
|
21
|
-
|
|
22
|
-
HAS_PETTINGZOO = True
|
|
23
|
-
except ImportError:
|
|
24
|
-
HAS_PETTINGZOO = False
|
|
18
|
+
def make(env: ParallelEnv) -> PettingZoo: ...
|
|
25
19
|
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
from gymnasium import Env
|
|
21
|
+
if adapters.HAS_GYM:
|
|
29
22
|
from .adapters import Gym
|
|
23
|
+
from gymnasium import Env
|
|
24
|
+
import gymnasium
|
|
30
25
|
|
|
31
26
|
@overload
|
|
32
27
|
def make(env: Env) -> Gym: ...
|
|
@@ -37,25 +32,21 @@ try:
|
|
|
37
32
|
Make an RLEnv from the `gymnasium` registry (e.g: "CartPole-v1").
|
|
38
33
|
"""
|
|
39
34
|
|
|
40
|
-
HAS_GYM = True
|
|
41
|
-
except ImportError:
|
|
42
|
-
HAS_GYM = False
|
|
43
35
|
|
|
44
|
-
|
|
45
|
-
from smac.env import StarCraft2Env
|
|
36
|
+
if adapters.HAS_SMAC:
|
|
46
37
|
from .adapters import SMAC
|
|
38
|
+
from smac.env import StarCraft2Env
|
|
47
39
|
|
|
48
40
|
@overload
|
|
49
41
|
def make(env: StarCraft2Env) -> SMAC: ...
|
|
50
42
|
|
|
51
|
-
HAS_SMAC = True
|
|
52
|
-
except ImportError:
|
|
53
|
-
HAS_SMAC = False
|
|
54
43
|
|
|
44
|
+
if adapters.HAS_OVERCOOKED:
|
|
45
|
+
from .adapters import Overcooked
|
|
46
|
+
from overcooked_ai_py.mdp.overcooked_env import OvercookedEnv
|
|
55
47
|
|
|
56
|
-
@overload
|
|
57
|
-
def make(env:
|
|
58
|
-
"""Why would you do this ?"""
|
|
48
|
+
@overload
|
|
49
|
+
def make(env: OvercookedEnv) -> Overcooked: ...
|
|
59
50
|
|
|
60
51
|
|
|
61
52
|
def make(env, **kwargs):
|
|
@@ -64,32 +55,18 @@ def make(env, **kwargs):
|
|
|
64
55
|
case MARLEnv():
|
|
65
56
|
return env
|
|
66
57
|
case str(env_id):
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if isinstance(env, ParallelEnv):
|
|
80
|
-
return PettingZoo(env)
|
|
81
|
-
except ImportError:
|
|
82
|
-
pass
|
|
83
|
-
try:
|
|
84
|
-
from smac.env import StarCraft2Env
|
|
85
|
-
|
|
86
|
-
from marlenv.adapters import SMAC
|
|
87
|
-
|
|
88
|
-
if isinstance(env, StarCraft2Env):
|
|
89
|
-
return SMAC(env)
|
|
90
|
-
except ImportError:
|
|
91
|
-
pass
|
|
92
|
-
|
|
58
|
+
if adapters.HAS_GYM:
|
|
59
|
+
gym_env = gymnasium.make(env_id, render_mode="rgb_array", **kwargs)
|
|
60
|
+
return Gym(gym_env)
|
|
61
|
+
|
|
62
|
+
if adapters.HAS_PETTINGZOO and isinstance(env, ParallelEnv):
|
|
63
|
+
return PettingZoo(env) # type: ignore
|
|
64
|
+
if adapters.HAS_SMAC and isinstance(env, StarCraft2Env):
|
|
65
|
+
return SMAC(env)
|
|
66
|
+
if adapters.HAS_OVERCOOKED and isinstance(env, OvercookedEnv):
|
|
67
|
+
return Overcooked(env) # type: ignore
|
|
68
|
+
if adapters.HAS_GYM and isinstance(env, Env):
|
|
69
|
+
return Gym(env)
|
|
93
70
|
raise ValueError(f"Unknown environment type: {type(env)}")
|
|
94
71
|
|
|
95
72
|
|
|
@@ -58,9 +58,14 @@ class Observation:
|
|
|
58
58
|
available_actions=self.available_actions[agent_id],
|
|
59
59
|
)
|
|
60
60
|
|
|
61
|
+
@property
|
|
62
|
+
def shape(self) -> tuple[int, ...]:
|
|
63
|
+
"""The individual shape of the observation data"""
|
|
64
|
+
return self.data[0].shape
|
|
65
|
+
|
|
61
66
|
@property
|
|
62
67
|
def extras_shape(self) -> tuple[int, ...]:
|
|
63
|
-
"""The shape of the observation extras"""
|
|
68
|
+
"""The individual shape of the observation extras"""
|
|
64
69
|
return self.extras[0].shape
|
|
65
70
|
|
|
66
71
|
def __hash__(self):
|
|
@@ -1,31 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
import gymnasium
|
|
3
|
-
|
|
4
|
-
skip_gym = False
|
|
5
|
-
except ImportError:
|
|
6
|
-
skip_gym = True
|
|
7
|
-
|
|
8
|
-
try:
|
|
9
|
-
import pettingzoo
|
|
10
|
-
|
|
11
|
-
skip_pettingzoo = False
|
|
12
|
-
except ImportError:
|
|
13
|
-
skip_pettingzoo = True
|
|
14
|
-
|
|
15
|
-
try:
|
|
16
|
-
import smac
|
|
17
|
-
|
|
18
|
-
skip_smac = False
|
|
19
|
-
except ImportError:
|
|
20
|
-
skip_smac = True
|
|
21
|
-
|
|
1
|
+
from importlib.util import find_spec
|
|
22
2
|
|
|
23
3
|
import numpy as np
|
|
24
4
|
import pytest
|
|
25
5
|
|
|
26
6
|
import marlenv
|
|
27
|
-
from marlenv import DiscreteActionSpace, DiscreteMockEnv, MARLEnv, Observation, State
|
|
28
|
-
from marlenv.adapters import
|
|
7
|
+
from marlenv import ContinuousActionSpace, DiscreteActionSpace, DiscreteMockEnv, MARLEnv, Observation, State
|
|
8
|
+
from marlenv.adapters import PymarlAdapter
|
|
9
|
+
|
|
10
|
+
skip_gym = find_spec("gymnasium") is None
|
|
11
|
+
skip_pettingzoo = find_spec("pettingzoo") is None
|
|
12
|
+
skip_smac = find_spec("smac") is None
|
|
13
|
+
# Check for "overcooked_ai_py.mdp" specifically because after uninstalling, the package
|
|
14
|
+
# can still be found because of some remaining .pkl file.
|
|
15
|
+
skip_overcooked = find_spec("overcooked_ai_py.mdp") is None
|
|
29
16
|
|
|
30
17
|
|
|
31
18
|
@pytest.mark.skipif(skip_gym, reason="Gymnasium is not installed")
|
|
@@ -113,7 +100,10 @@ def test_pettingzoo_adapter_continuous_action():
|
|
|
113
100
|
assert isinstance(env.action_space, marlenv.ContinuousActionSpace)
|
|
114
101
|
|
|
115
102
|
|
|
116
|
-
def _check_env_3m(env
|
|
103
|
+
def _check_env_3m(env):
|
|
104
|
+
from marlenv.adapters import SMAC
|
|
105
|
+
|
|
106
|
+
assert isinstance(env, SMAC)
|
|
117
107
|
obs = env.reset()
|
|
118
108
|
assert isinstance(obs, Observation)
|
|
119
109
|
assert env.n_agents == 3
|
|
@@ -147,6 +137,48 @@ def test_smac_render():
|
|
|
147
137
|
env.render()
|
|
148
138
|
|
|
149
139
|
|
|
140
|
+
@pytest.mark.skipif(skip_overcooked, reason="Overcooked is not installed")
|
|
141
|
+
def test_overcooked_attributes():
|
|
142
|
+
from overcooked_ai_py.mdp.overcooked_mdp import Action
|
|
143
|
+
|
|
144
|
+
from marlenv.adapters import Overcooked
|
|
145
|
+
|
|
146
|
+
env = Overcooked.from_layout("simple_o")
|
|
147
|
+
height, width = env._mdp.shape
|
|
148
|
+
assert env.n_agents == 2
|
|
149
|
+
assert env.n_actions == Action.NUM_ACTIONS
|
|
150
|
+
assert env.observation_shape == (26, height, width)
|
|
151
|
+
assert env.reward_space.shape == (1,)
|
|
152
|
+
assert env.extras_shape == (1,)
|
|
153
|
+
assert not env.is_multi_objective
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@pytest.mark.skipif(skip_overcooked, reason="Overcooked is not installed")
|
|
157
|
+
def test_overcooked_obs_state():
|
|
158
|
+
from marlenv.adapters import Overcooked
|
|
159
|
+
|
|
160
|
+
HORIZON = 100
|
|
161
|
+
env = Overcooked.from_layout("coordination_ring", horizon=HORIZON)
|
|
162
|
+
height, width = env._mdp.shape
|
|
163
|
+
obs, state = env.reset()
|
|
164
|
+
for i in range(HORIZON):
|
|
165
|
+
assert obs.shape == (26, height, width)
|
|
166
|
+
assert obs.extras_shape == (1,)
|
|
167
|
+
assert state.shape == (26, height, width)
|
|
168
|
+
assert state.extras_shape == (1,)
|
|
169
|
+
|
|
170
|
+
assert np.all(obs.extras == i / HORIZON)
|
|
171
|
+
assert np.all(state.extras == i / HORIZON)
|
|
172
|
+
|
|
173
|
+
step = env.random_step()
|
|
174
|
+
obs = step.obs
|
|
175
|
+
state = step.state
|
|
176
|
+
if i < HORIZON - 1:
|
|
177
|
+
assert not step.done
|
|
178
|
+
else:
|
|
179
|
+
assert step.done
|
|
180
|
+
|
|
181
|
+
|
|
150
182
|
def test_pymarl():
|
|
151
183
|
LIMIT = 20
|
|
152
184
|
N_AGENTS = 2
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import pickle
|
|
2
|
-
import
|
|
2
|
+
from importlib.util import find_spec
|
|
3
|
+
|
|
3
4
|
import numpy as np
|
|
4
5
|
import orjson
|
|
6
|
+
import pytest
|
|
5
7
|
|
|
8
|
+
import marlenv
|
|
6
9
|
from marlenv import DiscreteMockEnv
|
|
7
10
|
|
|
11
|
+
skip_gym = find_spec("gymnasium") is None
|
|
12
|
+
|
|
8
13
|
|
|
9
14
|
def test_registry():
|
|
10
15
|
env = DiscreteMockEnv(4)
|
|
@@ -17,6 +22,7 @@ def test_registry():
|
|
|
17
22
|
assert restored_env.n_actions == env.n_actions
|
|
18
23
|
|
|
19
24
|
|
|
25
|
+
@pytest.mark.skipif(skip_gym, reason="Gymnasium is not installed")
|
|
20
26
|
def test_registry_gym():
|
|
21
27
|
env = marlenv.make("CartPole-v1")
|
|
22
28
|
restored_env = pickle.loads(pickle.dumps(env))
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
from .pymarl_adapter import PymarlAdapter
|
|
2
|
-
from typing import Any
|
|
3
|
-
|
|
4
|
-
__all__ = ["PymarlAdapter"]
|
|
5
|
-
try:
|
|
6
|
-
from .gym_adapter import Gym
|
|
7
|
-
|
|
8
|
-
__all__.append("Gym")
|
|
9
|
-
except ImportError:
|
|
10
|
-
Gym = Any
|
|
11
|
-
|
|
12
|
-
try:
|
|
13
|
-
from .pettingzoo_adapter import PettingZoo
|
|
14
|
-
|
|
15
|
-
__all__.append("PettingZoo")
|
|
16
|
-
except ImportError:
|
|
17
|
-
PettingZoo = Any
|
|
18
|
-
|
|
19
|
-
try:
|
|
20
|
-
from .smac_adapter import SMAC
|
|
21
|
-
|
|
22
|
-
__all__.append("SMAC")
|
|
23
|
-
except ImportError:
|
|
24
|
-
SMAC = Any
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
try:
|
|
28
|
-
from .overcooked_adapter import Overcooked
|
|
29
|
-
|
|
30
|
-
__all__.append("Overcooked")
|
|
31
|
-
except ImportError:
|
|
32
|
-
Overcooked = Any
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/adapters/pettingzoo_adapter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/agent_id_wrapper.py
RENAMED
|
File without changes
|
{multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/available_actions_mask.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{multi_agent_rlenv-3.3.0 → multi_agent_rlenv-3.3.1}/src/marlenv/wrappers/last_action_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|