diff --git a/Gallery.md b/Gallery.md
index 0dd06f23..a29b2ad5 100644
--- a/Gallery.md
+++ b/Gallery.md
@@ -54,18 +54,19 @@ Users are also welcome to contribute their own training examples and demos to th
-| Environment/Demo | Tags | Refs |
-|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------------:|:-------------------------------:|
-| [MuJoCo](https://github.com/deepmind/mujoco)
| ![continuous](https://img.shields.io/badge/-continous-green) | [code](./examples/mujoco/) |
-| [CartPole](https://gymnasium.farama.org/environments/classic_control/cart_pole/)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | [code](./examples/cartpole/) |
-| [MPE: Simple Spread](https://pettingzoo.farama.org/environments/mpe/simple_spread/)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![MARL](https://img.shields.io/badge/-MARL-yellow) | [code](./examples/mpe/) |
-| [StarCraft II](https://github.com/oxwhirl/smac)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![MARL](https://img.shields.io/badge/-MARL-yellow) | [code](./examples/smac/) |
-| [Chat Bot](https://openrl-docs.readthedocs.io/en/latest/quick_start/train_nlp.html)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![NLP](https://img.shields.io/badge/-NLP-green) ![Transformer](https://img.shields.io/badge/-Transformer-blue) | [code](./examples/nlp/) |
-| [Atari Pong](https://gymnasium.farama.org/environments/atari/pong/)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![image](https://img.shields.io/badge/-image-red) | [code](./examples/atari/) |
-| [PettingZoo: Tic-Tac-Toe](https://pettingzoo.farama.org/environments/classic/tictactoe/)
| ![selfplay](https://img.shields.io/badge/-selfplay-blue) ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | [code](./examples/selfplay/) |
-| [DeepMind Control](https://shimmy.farama.org/environments/dm_control/)
| ![continuous](https://img.shields.io/badge/-continous-green) | [code](./examples/dm_control/) |
-| [Omniverse Isaac Gym](https://github.com/NVIDIA-Omniverse/OmniIsaacGymEnvs)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | [code](./examples/isaac/) |
-| [GridWorld](./examples/gridworld/)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | [code](./examples/gridworld/) |
-| [Super Mario Bros](https://github.com/Kautenja/gym-super-mario-bros)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![image](https://img.shields.io/badge/-image-red) | [code](./examples/super_mario/) |
-| [Gym Retro](https://github.com/openai/retro)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![image](https://img.shields.io/badge/-image-red) | [code](./examples/retro/) |
+| Environment/Demo | Tags | Refs |
+|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------:|
+| [MuJoCo](https://github.com/deepmind/mujoco)
| ![continuous](https://img.shields.io/badge/-continous-green) | [code](./examples/mujoco/) |
+| [CartPole](https://gymnasium.farama.org/environments/classic_control/cart_pole/)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | [code](./examples/cartpole/) |
+| [MPE: Simple Spread](https://pettingzoo.farama.org/environments/mpe/simple_spread/)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![MARL](https://img.shields.io/badge/-MARL-yellow) | [code](./examples/mpe/) |
+| [StarCraft II](https://github.com/oxwhirl/smac)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![MARL](https://img.shields.io/badge/-MARL-yellow) | [code](./examples/smac/) |
+| [Chat Bot](https://openrl-docs.readthedocs.io/en/latest/quick_start/train_nlp.html)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![NLP](https://img.shields.io/badge/-NLP-green) ![Transformer](https://img.shields.io/badge/-Transformer-blue) | [code](./examples/nlp/) |
+| [Atari Pong](https://gymnasium.farama.org/environments/atari/pong/)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![image](https://img.shields.io/badge/-image-red) | [code](./examples/atari/) |
+| [PettingZoo: Tic-Tac-Toe](https://pettingzoo.farama.org/environments/classic/tictactoe/)
| ![selfplay](https://img.shields.io/badge/-selfplay-blue) ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | [code](./examples/selfplay/) |
+| [DeepMind Control](https://shimmy.farama.org/environments/dm_control/)
| ![continuous](https://img.shields.io/badge/-continous-green) | [code](./examples/dm_control/) |
+| [Omniverse Isaac Gym](https://github.com/NVIDIA-Omniverse/OmniIsaacGymEnvs)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | [code](./examples/isaac/) |
+| [Snake](http://www.jidiai.cn/env_detail?envid=1)
| ![selfplay](https://img.shields.io/badge/-selfplay-blue) ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | [code](./examples/snake/) |
+| [GridWorld](./examples/gridworld/)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | [code](./examples/gridworld/) |
+| [Super Mario Bros](https://github.com/Kautenja/gym-super-mario-bros)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![image](https://img.shields.io/badge/-image-red) | [code](./examples/super_mario/) |
+| [Gym Retro](https://github.com/openai/retro)
| ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![image](https://img.shields.io/badge/-image-red) | [code](./examples/retro/) |
\ No newline at end of file
diff --git a/README.md b/README.md
index 2e4c4aaa..af7befcc 100644
--- a/README.md
+++ b/README.md
@@ -104,7 +104,8 @@ Environments currently supported by OpenRL (for more details, please refer to [G
- [Atari](https://gymnasium.farama.org/environments/atari/)
- [StarCraft II](https://github.com/oxwhirl/smac)
- [Omniverse Isaac Gym](https://github.com/NVIDIA-Omniverse/OmniIsaacGymEnvs)
-- [DeepMind Control](https://shimmy.farama.org/environments/dm_control/)
+- [DeepMind Control](https://shimmy.farama.org/environments/dm_control/)
+- [Snake](http://www.jidiai.cn/env_detail?envid=1)
- [GridWorld](./examples/gridworld/)
- [Super Mario Bros](https://github.com/Kautenja/gym-super-mario-bros)
- [Gym Retro](https://github.com/openai/retro)
diff --git a/README_zh.md b/README_zh.md
index cae5cea6..41822950 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -86,7 +86,8 @@ OpenRL目前支持的环境(更多详情请参考 [Gallery](Gallery.md)):
- [Atari](https://gymnasium.farama.org/environments/atari/)
- [StarCraft II](https://github.com/oxwhirl/smac)
- [Omniverse Isaac Gym](https://github.com/NVIDIA-Omniverse/OmniIsaacGymEnvs)
-- [DeepMind Control](https://shimmy.farama.org/environments/dm_control/)
+- [DeepMind Control](https://shimmy.farama.org/environments/dm_control/)
+- [Snake](http://www.jidiai.cn/env_detail?envid=1)
- [GridWorld](./examples/gridworld/)
- [Super Mario Bros](https://github.com/Kautenja/gym-super-mario-bros)
- [Gym Retro](https://github.com/openai/retro)
diff --git a/docs/images/snakes_1v1.gif b/docs/images/snakes_1v1.gif
new file mode 100644
index 00000000..03b40ab2
Binary files /dev/null and b/docs/images/snakes_1v1.gif differ
diff --git a/examples/dm_control/train_ppo.py b/examples/dm_control/train_ppo.py
index 2a3004a1..aa77222f 100644
--- a/examples/dm_control/train_ppo.py
+++ b/examples/dm_control/train_ppo.py
@@ -4,10 +4,9 @@
from openrl.configs.config import create_config_parser
from openrl.envs.common import make
from openrl.envs.wrappers.base_wrapper import BaseWrapper
-from openrl.envs.wrappers.extra_wrappers import GIFWrapper
+from openrl.envs.wrappers.extra_wrappers import FrameSkip, GIFWrapper
from openrl.modules.common import PPONet as Net
from openrl.runners.common import PPOAgent as Agent
-from openrl.envs.wrappers.extra_wrappers import FrameSkip
env_name = "dm_control/cartpole-balance-v0"
# env_name = "dm_control/walker-walk-v0"
diff --git a/examples/smac/README.md b/examples/smac/README.md
index 5fb14e76..f9d7d2cb 100644
--- a/examples/smac/README.md
+++ b/examples/smac/README.md
@@ -11,4 +11,7 @@ Installation guide for Linux:
Train SMAC with [MAPPO](https://arxiv.org/abs/2103.01955) algorithm:
-`python train_ppo.py --config smac_ppo.yaml`
\ No newline at end of file
+`python train_ppo.py --config smac_ppo.yaml`
+
+## Render replay on Mac
+
diff --git a/examples/snake/README.md b/examples/snake/README.md
new file mode 100644
index 00000000..4adb9cbd
--- /dev/null
+++ b/examples/snake/README.md
@@ -0,0 +1,17 @@
+
+This is the example for the snake game.
+
+## Usage
+
+```bash
+python train_selfplay.py
+```
+
+
+## Submit to JiDi
+
+Submition site: http://www.jidiai.cn/env_detail?envid=1.
+
+Snake senarios: [here](https://github.com/jidiai/ai_lib/blob/7a6986f0cb543994277103dbf605e9575d59edd6/env/config.json#L94)
+Original Snake environment: [here](https://github.com/jidiai/ai_lib/blob/master/env/snakes.py)
+
diff --git a/examples/snake/selfplay.yaml b/examples/snake/selfplay.yaml
new file mode 100644
index 00000000..74de97a0
--- /dev/null
+++ b/examples/snake/selfplay.yaml
@@ -0,0 +1,3 @@
+seed: 0
+callbacks:
+ - id: "ProgressBarCallback"
diff --git a/examples/snake/submissions/random_agent/submission.py b/examples/snake/submissions/random_agent/submission.py
new file mode 100644
index 00000000..b1f468df
--- /dev/null
+++ b/examples/snake/submissions/random_agent/submission.py
@@ -0,0 +1,29 @@
+# -*- coding:utf-8 -*-
+def sample_single_dim(action_space_list_each, is_act_continuous):
+ if is_act_continuous:
+ each = action_space_list_each.sample()
+ else:
+ if action_space_list_each.__class__.__name__ == "Discrete":
+ each = [0] * action_space_list_each.n
+ idx = action_space_list_each.sample()
+ each[idx] = 1
+ elif action_space_list_each.__class__.__name__ == "MultiDiscreteParticle":
+ each = []
+ nvec = action_space_list_each.high - action_space_list_each.low + 1
+ sample_indexes = action_space_list_each.sample()
+
+ for i in range(len(nvec)):
+ dim = nvec[i]
+ new_action = [0] * dim
+ index = sample_indexes[i]
+ new_action[index] = 1
+ each.extend(new_action)
+ return each
+
+
+def my_controller(observation, action_space, is_act_continuous):
+ joint_action = []
+ for i in range(len(action_space)):
+ player = sample_single_dim(action_space[i], is_act_continuous)
+ joint_action.append(player)
+ return joint_action
diff --git a/examples/snake/test_env.py b/examples/snake/test_env.py
new file mode 100644
index 00000000..b3a6bbee
--- /dev/null
+++ b/examples/snake/test_env.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright 2023 The OpenRL Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+""""""
+import time
+
+import numpy as np
+from wrappers import ConvertObs
+
+from openrl.envs.snake.snake import SnakeEatBeans
+from openrl.envs.snake.snake_pettingzoo import SnakeEatBeansAECEnv
+from openrl.selfplay.wrappers.random_opponent_wrapper import RandomOpponentWrapper
+
+
+def test_raw_env():
+ env = SnakeEatBeans()
+
+ obs, info = env.reset()
+
+ done = False
+ while not np.any(done):
+ a1 = np.zeros(4)
+ a1[env.action_space.sample()] = 1
+ a2 = np.zeros(4)
+ a2[env.action_space.sample()] = 1
+ obs, reward, done, info = env.step([a1, a2])
+ print("obs:", obs)
+ print("reward:", reward)
+ print("done:", done)
+ print("info:", info)
+
+
+def test_aec_env():
+ from PIL import Image
+
+ img_list = []
+ env = SnakeEatBeansAECEnv(render_mode="rgb_array")
+ env.reset(seed=0)
+ # time.sleep(1)
+ img = env.render()
+ img_list.append(img)
+ step = 0
+ for player_name in env.agent_iter():
+ if step > 20:
+ break
+ observation, reward, termination, truncation, info = env.last()
+ if termination or truncation:
+ break
+ action = env.action_space(player_name).sample()
+ # if player_name == "player_0":
+ # action = 2
+ # elif player_name == "player_1":
+ # action = 3
+ # else:
+ # raise ValueError("Unknown player name: {}".format(player_name))
+ env.step(action)
+ img = env.render()
+ if player_name == "player_0":
+ img_list.append(img)
+ # time.sleep(1)
+
+ step += 1
+ print("Total steps: {}".format(step))
+
+ save_path = "test.gif"
+ img_list = [Image.fromarray(img) for img in img_list]
+ img_list[0].save(save_path, save_all=True, append_images=img_list[1:], duration=500)
+
+
+def test_vec_env():
+ from openrl.envs.common import make
+
+ env = make(
+ "snakes_1v1",
+ opponent_wrappers=[
+ RandomOpponentWrapper,
+ ],
+ env_wrappers=[ConvertObs],
+ render_mode="group_human",
+ env_num=2,
+ )
+ obs, info = env.reset()
+ step = 0
+ done = False
+ while not np.any(done):
+ action = env.random_action()
+ obs, reward, done, info = env.step(action)
+ time.sleep(0.3)
+ step += 1
+ print("Total steps: {}".format(step))
+
+
+if __name__ == "__main__":
+ test_vec_env()
diff --git a/examples/snake/train_selfplay.py b/examples/snake/train_selfplay.py
new file mode 100644
index 00000000..d466abbe
--- /dev/null
+++ b/examples/snake/train_selfplay.py
@@ -0,0 +1,87 @@
+import numpy as np
+import torch
+from wrappers import ConvertObs
+
+from openrl.configs.config import create_config_parser
+from openrl.envs.common import make
+from openrl.modules.common import PPONet as Net
+from openrl.runners.common import PPOAgent as Agent
+from openrl.selfplay.wrappers.random_opponent_wrapper import RandomOpponentWrapper
+
+
+def train():
+ cfg_parser = create_config_parser()
+ cfg = cfg_parser.parse_args(["--config", "selfplay.yaml"])
+
+ # Create environment
+ env_num = 10
+ render_model = None
+ env = make(
+ "snakes_1v1",
+ render_mode=render_model,
+ env_num=env_num,
+ asynchronous=True,
+ opponent_wrappers=[RandomOpponentWrapper],
+ env_wrappers=[ConvertObs],
+ cfg=cfg,
+ )
+ # Create neural network
+
+ net = Net(env, cfg=cfg, device="cuda" if torch.cuda.is_available() else "cpu")
+ # Create agent
+ agent = Agent(net)
+ # Begin training
+ agent.train(total_time_steps=100000)
+ env.close()
+ agent.save("./selfplay_agent/")
+ return agent
+
+
+def evaluation():
+ from examples.selfplay.tictactoe_utils.tictactoe_render import TictactoeRender
+
+ print("Evaluation...")
+ env_num = 1
+ env = make(
+ "snakes_1v1",
+ env_num=env_num,
+ asynchronous=True,
+ opponent_wrappers=[RandomOpponentWrapper],
+ env_wrappers=[ConvertObs],
+ auto_reset=False,
+ )
+
+ cfg_parser = create_config_parser()
+ cfg = cfg_parser.parse_args()
+ net = Net(env, cfg=cfg, device="cuda" if torch.cuda.is_available() else "cpu")
+
+ agent = Agent(net)
+
+ agent.load("./selfplay_agent/")
+ agent.set_env(env)
+ env.reset(seed=0)
+
+ total_reward = 0.0
+ ep_num = 5
+ for ep_now in range(ep_num):
+ obs, info = env.reset()
+ done = False
+ step = 0
+
+ while not np.any(done):
+ # predict next action based on the observation
+ action, _ = agent.act(obs, info, deterministic=True)
+ obs, r, done, info = env.step(action)
+ step += 1
+
+ if np.any(done):
+ total_reward += np.mean(r) > 0
+ print(f"{ep_now}/{ep_num}: reward: {np.mean(r)}")
+ print(f"win rate: {total_reward/ep_num}")
+ env.close()
+ print("Evaluation finished.")
+
+
+if __name__ == "__main__":
+ train()
+ evaluation()
diff --git a/examples/snake/wrappers.py b/examples/snake/wrappers.py
new file mode 100644
index 00000000..52f3958d
--- /dev/null
+++ b/examples/snake/wrappers.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright 2023 The OpenRL Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+""""""
+import gymnasium as gym
+import numpy as np
+from gymnasium import spaces
+
+from openrl.envs.wrappers.base_wrapper import BaseObservationWrapper
+
+
+def raw2vec(raw_obs, n_player=2):
+ control_index = raw_obs["controlled_snake_index"][0]
+
+ width = raw_obs["board_width"][0]
+ height = raw_obs["board_height"][0]
+ beans = raw_obs[1][0]
+
+ ally_pos = raw_obs[control_index][0]
+ enemy_pos = raw_obs[5 - control_index][0]
+
+ obs = np.zeros(width * height * n_player, dtype=int)
+
+ ally_head_h, ally_head_w = ally_pos[0]
+ enemy_head_h, enemy_head_w = enemy_pos[0]
+ obs[ally_head_h * width + ally_head_w] = 2
+ obs[height * width + ally_head_h * width + ally_head_w] = 4
+ obs[enemy_head_h * width + enemy_head_w] = 4
+ obs[height * width + enemy_head_h * width + enemy_head_w] = 2
+
+ for bean in beans:
+ h, w = bean
+ obs[h * width + w] = 1
+ obs[height * width + h * width + w] = 1
+
+ for p in ally_pos[1:]:
+ h, w = p
+ obs[h * width + w] = 3
+ obs[height * width + h * width + w] = 5
+
+ for p in enemy_pos[1:]:
+ h, w = p
+ obs[h * width + w] = 5
+ obs[height * width + h * width + w] = 3
+
+ obs_ = np.array([])
+ for i in obs:
+ obs_ = np.concatenate([obs_, np.eye(6)[i]])
+ obs_ = obs_.reshape(-1, width * height * n_player * 6)
+
+ return obs_
+
+
+class ConvertObs(BaseObservationWrapper):
+ def __init__(self, env: gym.Env):
+ """Flattens the observations of an environment.
+
+ Args:
+ env: The environment to apply the wrapper
+ """
+ BaseObservationWrapper.__init__(self, env)
+
+ self.observation_space = spaces.Box(
+ low=-np.inf, high=np.inf, shape=(576,), dtype=np.float32
+ )
+
+ def observation(self, observation):
+ """Flattens an observation.
+
+ Args:
+ observation: The observation to flatten
+
+ Returns:
+ The flattened observation
+ """
+
+ return raw2vec(observation)
diff --git a/openrl/algorithms/dqn.py b/openrl/algorithms/dqn.py
index ebd8d727..bbca547b 100644
--- a/openrl/algorithms/dqn.py
+++ b/openrl/algorithms/dqn.py
@@ -167,9 +167,7 @@ def prepare_loss(
)
q_targets = rewards_batch + self.gamma * max_next_q_values * next_masks_batch
- q_loss = torch.mean(
- F.mse_loss(q_values, q_targets.detach())
- ) # 均方误差损失函数
+ q_loss = torch.mean(F.mse_loss(q_values, q_targets.detach())) # 均方误差损失函数
loss_list.append(q_loss)
diff --git a/openrl/algorithms/vdn.py b/openrl/algorithms/vdn.py
index 83bdb5ed..f1215c03 100644
--- a/openrl/algorithms/vdn.py
+++ b/openrl/algorithms/vdn.py
@@ -211,9 +211,7 @@ def prepare_loss(
rewards_batch = rewards_batch.reshape(-1, self.n_agent, 1)
rewards_batch = torch.sum(rewards_batch, dim=1, keepdim=True).view(-1, 1)
q_targets = rewards_batch + self.gamma * max_next_q_values * next_masks_batch
- q_loss = torch.mean(
- F.mse_loss(q_values, q_targets.detach())
- ) # 均方误差损失函数
+ q_loss = torch.mean(F.mse_loss(q_values, q_targets.detach())) # 均方误差损失函数
loss_list.append(q_loss)
return loss_list
diff --git a/openrl/envs/PettingZoo/__init__.py b/openrl/envs/PettingZoo/__init__.py
index e5111afc..fa9e66ca 100644
--- a/openrl/envs/PettingZoo/__init__.py
+++ b/openrl/envs/PettingZoo/__init__.py
@@ -63,7 +63,8 @@ def make_PettingZoo_envs(
Single2MultiAgentWrapper,
)
- env_wrappers = copy.copy(kwargs.pop("opponent_wrappers", [SeedEnv]))
+ env_wrappers = [SeedEnv]
+ env_wrappers += copy.copy(kwargs.pop("opponent_wrappers", []))
env_wrappers += [
Single2MultiAgentWrapper,
RemoveTruncated,
diff --git a/openrl/envs/common/registration.py b/openrl/envs/common/registration.py
index 90f54e82..3a274c2c 100644
--- a/openrl/envs/common/registration.py
+++ b/openrl/envs/common/registration.py
@@ -65,7 +65,14 @@ def make(
id=id, env_num=env_num, render_mode=convert_render_mode, **kwargs
)
else:
- if id.startswith("dm_control/"):
+ if id.startswith("snakes_"):
+ from openrl.envs.snake import make_snake_envs
+
+ env_fns = make_snake_envs(
+ id=id, env_num=env_num, render_mode=convert_render_mode, **kwargs
+ )
+
+ elif id.startswith("dm_control/"):
from openrl.envs.dmc import make_dmc_envs
env_fns = make_dmc_envs(
diff --git a/openrl/envs/dmc/__init__.py b/openrl/envs/dmc/__init__.py
index ad2b113d..4f6ff39e 100644
--- a/openrl/envs/dmc/__init__.py
+++ b/openrl/envs/dmc/__init__.py
@@ -13,10 +13,7 @@ def make_dmc_envs(
render_mode: Optional[Union[str, List[str]]] = None,
**kwargs,
):
- from openrl.envs.wrappers import (
- RemoveTruncated,
- Single2MultiAgentWrapper,
- )
+ from openrl.envs.wrappers import RemoveTruncated, Single2MultiAgentWrapper
from openrl.envs.wrappers.extra_wrappers import ConvertEmptyBoxWrapper
env_wrappers = copy.copy(kwargs.pop("env_wrappers", []))
diff --git a/openrl/envs/mpe/rendering.py b/openrl/envs/mpe/rendering.py
index 65ca66b0..ab1a47db 100644
--- a/openrl/envs/mpe/rendering.py
+++ b/openrl/envs/mpe/rendering.py
@@ -29,10 +29,12 @@
except ImportError:
print(
"Error occured while running `from pyglet.gl import *`",
- "HINT: make sure you have OpenGL install. On Ubuntu, you can run 'apt-get"
- " install python-opengl'. If you're running on a server, you may need a"
- " virtual frame buffer; something like this should work: 'xvfb-run -s"
- ' "-screen 0 1400x900x24" python