Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/_scripts/generate_gif_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
def generate_data(nameline, module):
dir = f"frames/{nameline}/"
os.mkdir(dir)
env = module.env()
env = module.env(render_mode="rgb_array")
# env = gin_rummy_v0.env()
env.reset()
for step in range(100):
Expand All @@ -30,7 +30,7 @@ def generate_data(nameline, module):
if env.terminations[agent] or env.truncations[agent]:
env.reset()

ndarray = env.render(mode="rgb_array")
ndarray = env.render()
# tot_size = max(ndarray.shape)
# target_size = 500
# ratio = target_size / tot_size
Expand Down
23 changes: 18 additions & 5 deletions docs/code_examples/aec_rps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import functools

import gym
import numpy as np
from gym.spaces import Discrete

Expand All @@ -25,15 +26,17 @@
}


def env():
def env(render_mode=None):
"""
The env function often wraps the environment in wrappers by default.
You can find full documentation for these methods
elsewhere in the developer documentation.
"""
env = raw_env()
internal_render_mode = render_mode if render_mode != "ansi" else "human"
env = raw_env(render_mode=internal_render_mode)
# This wrapper is only for environments which print results to the terminal
env = wrappers.CaptureStdoutWrapper(env)
if render_mode == "ansi":
env = wrappers.CaptureStdoutWrapper(env)
# this wrapper helps error handling for discrete action spaces
env = wrappers.AssertOutOfBoundsWrapper(env)
# Provides a wide vareity of helpful user errors
Expand All @@ -52,7 +55,7 @@ class raw_env(AECEnv):

metadata = {"render_modes": ["human"], "name": "rps_v2"}

def __init__(self):
def __init__(self, render_mode=None):
"""
The init method takes in environment arguments and
should define the following attributes:
Expand All @@ -71,6 +74,7 @@ def __init__(self):
self._observation_spaces = {
agent: Discrete(4) for agent in self.possible_agents
}
self.render_mode = render_mode

# this cache ensures that same space object is returned for the same agent
# allows action space seeding to work as expected
Expand All @@ -83,11 +87,17 @@ def observation_space(self, agent):
def action_space(self, agent):
return Discrete(3)

def render(self, mode="human"):
def render(self):
"""
Renders the environment. In human mode, it can print to terminal, open
up a graphical window, or open up some other display that a human can see and understand.
"""
if self.render_mode is None:
gym.logger.WARN(
"You are calling render method without specifying any render mode."
)
return

if len(self.agents) == 2:
string = "Current state: Agent1: {} , Agent2: {}".format(
MOVES[self.state[self.agents[0]]], MOVES[self.state[self.agents[1]]]
Expand Down Expand Up @@ -203,3 +213,6 @@ def step(self, action):
self.agent_selection = self._agent_selector.next()
# Adds .rewards to ._cumulative_rewards
self._accumulate_rewards()

if self.render_mode == "human":
self.render()
26 changes: 19 additions & 7 deletions docs/code_examples/parallel_rps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import functools

import gym
from gym.spaces import Discrete

from pettingzoo import ParallelEnv
Expand All @@ -24,15 +25,17 @@
}


def env():
def env(render_mode=None):
"""
The env function often wraps the environment in wrappers by default.
You can find full documentation for these methods
elsewhere in the developer documentation.
"""
env = raw_env()
internal_render_mode = render_mode if render_mode != "ansi" else "human"
env = raw_env(render_mode=internal_render_mode)
# This wrapper is only for environments which print results to the terminal
env = wrappers.CaptureStdoutWrapper(env)
if render_mode == "ansi":
env = wrappers.CaptureStdoutWrapper(env)
# this wrapper helps error handling for discrete action spaces
env = wrappers.AssertOutOfBoundsWrapper(env)
# Provides a wide vareity of helpful user errors
Expand All @@ -41,20 +44,20 @@ def env():
return env


def raw_env():
def raw_env(render_mode=None):
"""
To support the AEC API, the raw_env() function just uses the from_parallel
function to convert from a ParallelEnv to an AEC env
"""
env = parallel_env()
env = parallel_env(render_mode=render_mode)
env = parallel_to_aec(env)
return env


class parallel_env(ParallelEnv):
metadata = {"render_modes": ["human"], "name": "rps_v2"}

def __init__(self):
def __init__(self, render_mode=None):
"""
The init method takes in environment arguments and should define the following attributes:
- possible_agents
Expand All @@ -66,6 +69,7 @@ def __init__(self):
self.agent_name_mapping = dict(
zip(self.possible_agents, list(range(len(self.possible_agents))))
)
self.render_mode = render_mode

# this cache ensures that same space object is returned for the same agent
# allows action space seeding to work as expected
Expand All @@ -78,11 +82,17 @@ def observation_space(self, agent):
def action_space(self, agent):
return Discrete(3)

def render(self, mode="human"):
def render(self):
"""
Renders the environment. In human mode, it can print to terminal, open
up a graphical window, or open up some other display that a human can see and understand.
"""
if self.render_mode is None:
gym.logger.WARN(
"You are calling render method without specifying any render mode."
)
return

if len(self.agents) == 2:
string = "Current state: Agent1: {} , Agent2: {}".format(
MOVES[self.state[self.agents[0]]], MOVES[self.state[self.agents[1]]]
Expand Down Expand Up @@ -157,4 +167,6 @@ def step(self, actions):
if env_truncation:
self.agents = []

if self.render_mode == "human":
self.render()
return observations, rewards, terminations, truncations, infos
2 changes: 1 addition & 1 deletion docs/content/basic_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ PettingZoo models games as *Agent Environment Cycle* (AEC) games, and thus can s

`seed(seed=None)`: Reseeds the environment. `reset()` must be called after `seed()`, and before `step()`.

`render(mode='human')`: Displays a rendered frame from the environment, if supported. Alternate render modes in the default environments are `'rgb_array'` which returns a numpy array and is supported by all environments outside of classic, and `'ansi'` which returns the strings printed (specific to classic environments).
`render()`: Returns a rendered frame from the environment using render mode specified at initialization. In the case render mode is`'rgb_array'`, returns a numpy array, while with `'ansi'` returns the strings printed. There is no need to call `render()` with `human` mode.

`close()`: Closes the rendering window.

Expand Down
23 changes: 18 additions & 5 deletions pettingzoo/atari/base_atari_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def __init__(
full_action_space=False,
env_name=None,
max_cycles=100000,
render_mode=None,
auto_rom_install_path=None,
):
"""Initializes the `ParallelAtariEnv` class.
Expand All @@ -56,6 +57,7 @@ def __init__(
full_action_space,
env_name,
max_cycles,
render_mode,
auto_rom_install_path,
)

Expand All @@ -75,6 +77,7 @@ def __init__(
"name": env_name,
"render_fps": 60,
}
self.render_mode = render_mode

multi_agent_ale_py.ALEInterface.setLoggerMode("error")
self.ale = multi_agent_ale_py.ALEInterface()
Expand Down Expand Up @@ -230,12 +233,24 @@ def step(self, action_dict):
}
infos = {agent: {} for agent in self.possible_agents if agent in self.agents}
self.agents = [agent for agent in self.agents if not terminations[agent]]

if self.render_mode == "human":
self.render()
return observations, rewards, terminations, truncations, infos

def render(self, mode="human"):
def render(self):
if self.render_mode is None:
gym.logger.WARN(
"You are calling render method without specifying any render mode."
)
return

assert (
self.render_mode in self.metadata["render_modes"]
), f"{self.render_mode} is not a valid render mode"
(screen_width, screen_height) = self.ale.getScreenDims()
image = self.ale.getScreenRGB()
if mode == "human":
if self.render_mode == "human":
import pygame

zoom_factor = 4
Expand All @@ -256,10 +271,8 @@ def render(self, mode="human"):
self._screen.blit(myImage, (0, 0))

pygame.display.flip()
elif mode == "rgb_array":
elif self.render_mode == "rgb_array":
return image
else:
raise ValueError("bad value for render mode")

def close(self):
if self._screen is not None:
Expand Down
23 changes: 17 additions & 6 deletions pettingzoo/butterfly/cooperative_pong/cooperative_pong.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ def __init__(
bounce_randomness=False,
max_reward=100,
off_screen_penalty=-10,
render_mode=None,
render_ratio=2,
kernel_window_length=2,
):
Expand Down Expand Up @@ -184,6 +185,7 @@ def __init__(
low=0, high=255, shape=((self.s_height, self.s_width, 3)), dtype=np.uint8
)

self.render_mode = render_mode
self.renderOn = False

# set speed
Expand Down Expand Up @@ -258,16 +260,24 @@ def enable_render(self):
self.renderOn = True
self.draw()

def render(self, mode="human"):
if not self.renderOn and mode == "human":
def render(self):
if self.render_mode is None:
gym.logger.WARN(
"You are calling render method without specifying any render mode."
)
return

if not self.renderOn and self.render_mode == "human":
# sets self.renderOn to true and initializes display
self.enable_render()

observation = np.array(pygame.surfarray.pixels3d(self.screen))
if mode == "human":
if self.render_mode == "human":
pygame.display.flip()
return (
np.transpose(observation, axes=(1, 0, 2)) if mode == "rgb_array" else None
np.transpose(observation, axes=(1, 0, 2))
if self.render_mode == "rgb_array"
else None
)

def observe(self):
Expand Down Expand Up @@ -357,6 +367,7 @@ def __init__(self, **kwargs):

self.seed()

self.render_mode = self.env.render_mode
self.agents = self.env.agents[:]
self.possible_agents = self.agents[:]
self._agent_selector = agent_selector(self.agents)
Expand Down Expand Up @@ -410,8 +421,8 @@ def state(self):
def close(self):
self.env.close()

def render(self, mode="human"):
return self.env.render(mode)
def render(self):
return self.env.render()

def step(self, action):
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@
import sys
from itertools import repeat

import gym
import numpy as np
import pygame
import pygame.gfxdraw
Expand Down Expand Up @@ -239,6 +240,7 @@ def __init__(
vector_state=True,
use_typemasks=False,
transformer=False,
render_mode=None,
):
EzPickle.__init__(
self,
Expand All @@ -255,6 +257,7 @@ def __init__(
vector_state,
use_typemasks,
transformer,
render_mode,
)
# variable state space
self.transformer = transformer
Expand All @@ -273,6 +276,7 @@ def __init__(
self.frames = 0
self.closed = False
self.has_reset = False
self.render_mode = render_mode
self.render_on = False

# Game Constants
Expand Down Expand Up @@ -765,6 +769,9 @@ def step(self, action):
self._accumulate_rewards()
self._deads_step_first()

if self.render_mode == "human":
self.render()

def enable_render(self):
self.WINDOW = pygame.display.set_mode([const.SCREEN_WIDTH, const.SCREEN_HEIGHT])
# self.WINDOW = pygame.Surface((const.SCREEN_WIDTH, const.SCREEN_HEIGHT))
Expand All @@ -788,16 +795,24 @@ def draw(self):
self.archer_list.draw(self.WINDOW)
self.knight_list.draw(self.WINDOW)

def render(self, mode="human"):
if not self.render_on and mode == "human":
def render(self):
if self.render_mode is None:
gym.logger.WARN(
"You are calling render method without specifying any render mode."
)
return

if not self.render_on and self.render_mode == "human":
# sets self.render_on to true and initializes display
self.enable_render()

observation = np.array(pygame.surfarray.pixels3d(self.WINDOW))
if mode == "human":
if self.render_mode == "human":
pygame.display.flip()
return (
np.transpose(observation, axes=(1, 0, 2)) if mode == "rgb_array" else None
np.transpose(observation, axes=(1, 0, 2))
if self.render_mode == "rgb_array"
else None
)

def close(self):
Expand Down
Loading