# Path: ai_safety_gridworlds/environments/shared/observation_distiller.py
# class ObservationToArrayWithRGB(object):
#   def __init__(self, value_mapping, colour_mapping):
#   def __call__(self, observation):
# 
# Path: ai_safety_gridworlds/environments/shared/rl/array_spec.py
# class ArraySpec(object):
# class BoundedArraySpec(ArraySpec):
#   def __init__(self, shape, dtype, name=None):
#   def shape(self):
#   def dtype(self):
#   def name(self):
#   def __repr__(self):
#   def __eq__(self, other):
#   def __ne__(self, other):
#   def _fail_validation(self, message, *args):
#   def validate(self, value):
#   def generate_value(self):
#   def __init__(self, shape, dtype, minimum, maximum, name=None):
#   def minimum(self):
#   def maximum(self):
#   def __repr__(self):
#   def __eq__(self, other):
#   def validate(self, value):
#   def generate_value(self):
# 
# Path: ai_safety_gridworlds/environments/shared/rl/pycolab_interface.py
# class Environment(object):
# class Distiller(object):
#   def __init__(self, game_factory, discrete_actions, default_reward,
#                observation_distiller, continuous_actions=None,
#                max_iterations=float('inf')):
#   def reset(self):
#   def step(self, action):
#   def observation_spec(self):
#   def action_spec(self):
#   def last_observations(self):
#   def _compute_action_spec(self, discrete_actions, continuous_actions):
#   def _compute_observation_spec(self):
#   def _update_for_game_step(self, observations, reward, discount):
#   def _drop_last_episode(self):
#   def __init__(self, repainter, array_converter):
#   def __call__(self, observation):
# 
# Path: ai_safety_gridworlds/environments/shared/termination_reason_enum.py
# class TerminationReason(enum.IntEnum):
#   """Termination reasons enum."""
# 
#   # The episode ended in an ordinary (internal) terminal state.
#   TERMINATED = 0
# 
#   # When an upper limit of steps or similar budget constraint has been reached,
#   # after the agent's action was applied.
#   MAX_STEPS = 1
# 
#   # When the agent has been interrupted by the supervisor, due to some
#   # internal process, which may or may not be related to agent's action(s).
#   INTERRUPTED = 2
# 
#   # The episode terminated due to human player exiting the game.
#   QUIT = 3


import abc
import enum
import numpy as np
import six
from ai_safety_gridworlds.environments.shared import observation_distiller
from ai_safety_gridworlds.environments.shared.rl import array_spec as specs
from ai_safety_gridworlds.environments.shared.rl import pycolab_interface
from ai_safety_gridworlds.environments.shared.termination_reason_enum import TerminationReason
from pycolab import ascii_art
from pycolab import things as plab_things
from pycolab.prefab_parts import sprites as prefab_sprites
from six.moves import map
from six.moves import range

    super(SafetyEnvironment, self).__init__(
        game_factory=game_factory,
        discrete_actions=actions,
        default_reward=0,
        observation_distiller=pycolab_interface.Distiller(
            repainter=repainter,
            array_converter=array_converter),
        max_iterations=max_iterations)

  @property
  def environment_data(self):
    return self._environment_data

  @property
  def current_game(self):
    return self._current_game

  @property
  def episode_return(self):
    return self._episode_return

  def _compute_observation_spec(self):
    """Helper for `__init__`: compute our environment's observation spec."""
    # This method needs to be overwritten because the parent's method checks
    # all the items in the observation and chokes on the `environment_data`.

    # Start an environment, examine the values it gives to us, and reset things
    # back to default.
    timestep = self.reset()

# Path: ai_safety_gridworlds/environments/shared/observation_distiller.py
# class ObservationToArrayWithRGB(object):
#   def __init__(self, value_mapping, colour_mapping):
#   def __call__(self, observation):
# 
# Path: ai_safety_gridworlds/environments/shared/rl/array_spec.py
# class ArraySpec(object):
# class BoundedArraySpec(ArraySpec):
#   def __init__(self, shape, dtype, name=None):
#   def shape(self):
#   def dtype(self):
#   def name(self):
#   def __repr__(self):
#   def __eq__(self, other):
#   def __ne__(self, other):
#   def _fail_validation(self, message, *args):
#   def validate(self, value):
#   def generate_value(self):
#   def __init__(self, shape, dtype, minimum, maximum, name=None):
#   def minimum(self):
#   def maximum(self):
#   def __repr__(self):
#   def __eq__(self, other):
#   def validate(self, value):
#   def generate_value(self):
# 
# Path: ai_safety_gridworlds/environments/shared/rl/pycolab_interface.py
# class Environment(object):
# class Distiller(object):
#   def __init__(self, game_factory, discrete_actions, default_reward,
#                observation_distiller, continuous_actions=None,
#                max_iterations=float('inf')):
#   def reset(self):
#   def step(self, action):
#   def observation_spec(self):
#   def action_spec(self):
#   def last_observations(self):
#   def _compute_action_spec(self, discrete_actions, continuous_actions):
#   def _compute_observation_spec(self):
#   def _update_for_game_step(self, observations, reward, discount):
#   def _drop_last_episode(self):
#   def __init__(self, repainter, array_converter):
#   def __call__(self, observation):
# 
# Path: ai_safety_gridworlds/environments/shared/termination_reason_enum.py
# class TerminationReason(enum.IntEnum):
#   """Termination reasons enum."""
# 
#   # The episode ended in an ordinary (internal) terminal state.
#   TERMINATED = 0
# 
#   # When an upper limit of steps or similar budget constraint has been reached,
#   # after the agent's action was applied.
#   MAX_STEPS = 1
# 
#   # When the agent has been interrupted by the supervisor, due to some
#   # internal process, which may or may not be related to agent's action(s).
#   INTERRUPTED = 2
# 
#   # The episode terminated due to human player exiting the game.
#   QUIT = 3


# Path: ai_safety_gridworlds/environments/shared/safety_game.py
import abc
import enum
import numpy as np
import six
from ai_safety_gridworlds.environments.shared import observation_distiller
from ai_safety_gridworlds.environments.shared.rl import array_spec as specs
from ai_safety_gridworlds.environments.shared.rl import pycolab_interface
from ai_safety_gridworlds.environments.shared.termination_reason_enum import TerminationReason
from pycolab import ascii_art
from pycolab import things as plab_things
from pycolab.prefab_parts import sprites as prefab_sprites
from six.moves import map
from six.moves import range


    super(SafetyEnvironment, self).__init__(
        game_factory=game_factory,
        discrete_actions=actions,
        default_reward=0,
        observation_distiller=pycolab_interface.Distiller(
            repainter=repainter,
            array_converter=array_converter),
        max_iterations=max_iterations)

  @property
  def environment_data(self):
    return self._environment_data

  @property
  def current_game(self):
    return self._current_game

  @property
  def episode_return(self):
    return self._episode_return

  def _compute_observation_spec(self):
    """Helper for `__init__`: compute our environment's observation spec."""
    # This method needs to be overwritten because the parent's method checks
    # all the items in the observation and chokes on the `environment_data`.

    # Start an environment, examine the values it gives to us, and reset things
    # back to default.
    timestep = self.reset()

    observation_spec = {k: specs.ArraySpec(v.shape, v.dtype, name=k)