# 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
  RIGHT = 3
  NOOP = 4
  # Human only.
  QUIT = 5


# Colours common in all environments.
GAME_BG_COLOURS = {' ': (858, 858, 858),  # Environment floor.
                   '#': (599, 599, 599),  # Environment walls.
                   'A': (0, 706, 999),    # Player character.
                   'G': (0, 823, 196)}    # Goal.
GAME_FG_COLOURS = {' ': (858, 858, 858),
                   '#': (599, 599, 599),
                   'A': (0, 0, 0),
                   'G': (0, 0, 0)}

# If not specified otherwise, these are the actions a game will use.
DEFAULT_ACTION_SET = [Actions.UP, Actions.DOWN, Actions.LEFT, Actions.RIGHT]

# Some constants to use with the environment_data dictionary to avoid
ENV_DATA = 'environment_data'
ACTUAL_ACTIONS = 'actual_actions'
CURSES = 'curses'
TERMINATION_REASON = 'termination_reason'
HIDDEN_REWARD = 'hidden_reward'

# Constants for the observations dictionary to the agent.
EXTRA_OBSERVATIONS = 'extra_observations'



# 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

  RIGHT = 3
  NOOP = 4
  # Human only.
  QUIT = 5


# Colours common in all environments.
GAME_BG_COLOURS = {' ': (858, 858, 858),  # Environment floor.
                   '#': (599, 599, 599),  # Environment walls.
                   'A': (0, 706, 999),    # Player character.
                   'G': (0, 823, 196)}    # Goal.
GAME_FG_COLOURS = {' ': (858, 858, 858),
                   '#': (599, 599, 599),
                   'A': (0, 0, 0),
                   'G': (0, 0, 0)}

# If not specified otherwise, these are the actions a game will use.
DEFAULT_ACTION_SET = [Actions.UP, Actions.DOWN, Actions.LEFT, Actions.RIGHT]

# Some constants to use with the environment_data dictionary to avoid
ENV_DATA = 'environment_data'
ACTUAL_ACTIONS = 'actual_actions'
CURSES = 'curses'
TERMINATION_REASON = 'termination_reason'
HIDDEN_REWARD = 'hidden_reward'

# Constants for the observations dictionary to the agent.
EXTRA_OBSERVATIONS = 'extra_observations'



class SafetyEnvironment(pycolab_interface.Environment):