# 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/environment.py
# class TimeStep(collections.namedtuple(
#     'TimeStep', ['step_type', 'reward', 'discount', 'observation'])):
# class StepType(enum.IntEnum):
# class Base(object):
#   def first(self):
#   def mid(self):
#   def last(self):
#   def first(self):
#   def mid(self):
#   def last(self):
#   def reset(self):
#   def step(self, action):
#   def observation_spec(self):
#   def action_spec(self):
#   def close(self):
#   def __enter__(self):
#   def __exit__(self, unused_exception_type, unused_exc_value, unused_traceback):
# def restart(observation):
# def transition(reward, observation, discount=1.0):
# def termination(reward, observation):
# def truncation(reward, observation, discount=1.0):
#   FIRST = 0
#   MID = 1
#   LAST = 2


from ai_safety_gridworlds.environments.shared.rl import array_spec as specs
from ai_safety_gridworlds.environments.shared.rl import environment
from six.moves import zip
import numpy as np
import six
  def action_spec(self):
    return self._valid_actions

  @property
  def last_observations(self):
    """Distill and return the last observation."""
    # A "bare" numpy array will be placed in a dict under the key "board".
    if isinstance(self._last_observations, dict):
      observation = self._last_observations
    else:
      observation = {'board': self._last_observations}

    return observation

  ### Various helpers. ###

  def _compute_action_spec(self, discrete_actions, continuous_actions):
    """Helper for `__init__`: compute our environment's action spec."""
    valid_actions = []

    # First discrete actions:
    if discrete_actions is not None:
      try:
        # Get an array of upper and lower bounds for each discrete action.
        min_, max_ = list(zip(*discrete_actions))
        # Total number of discrete actions provided on each time step.
        shape = (len(discrete_actions),)
      except TypeError:
        min_, max_ = discrete_actions  # Enforces 2-tuple.
        shape = (1,)

# 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/environment.py
# class TimeStep(collections.namedtuple(
#     'TimeStep', ['step_type', 'reward', 'discount', 'observation'])):
# class StepType(enum.IntEnum):
# class Base(object):
#   def first(self):
#   def mid(self):
#   def last(self):
#   def first(self):
#   def mid(self):
#   def last(self):
#   def reset(self):
#   def step(self, action):
#   def observation_spec(self):
#   def action_spec(self):
#   def close(self):
#   def __enter__(self):
#   def __exit__(self, unused_exception_type, unused_exc_value, unused_traceback):
# def restart(observation):
# def transition(reward, observation, discount=1.0):
# def termination(reward, observation):
# def truncation(reward, observation, discount=1.0):
#   FIRST = 0
#   MID = 1
#   LAST = 2


# Path: ai_safety_gridworlds/environments/shared/rl/pycolab_interface.py
from ai_safety_gridworlds.environments.shared.rl import array_spec as specs
from ai_safety_gridworlds.environments.shared.rl import environment
from six.moves import zip
import numpy as np
import six

  def action_spec(self):
    return self._valid_actions

  @property
  def last_observations(self):
    """Distill and return the last observation."""
    # A "bare" numpy array will be placed in a dict under the key "board".
    if isinstance(self._last_observations, dict):
      observation = self._last_observations
    else:
      observation = {'board': self._last_observations}

    return observation

  ### Various helpers. ###

  def _compute_action_spec(self, discrete_actions, continuous_actions):
    """Helper for `__init__`: compute our environment's action spec."""
    valid_actions = []

    # First discrete actions:
    if discrete_actions is not None:
      try:
        # Get an array of upper and lower bounds for each discrete action.
        min_, max_ = list(zip(*discrete_actions))
        # Total number of discrete actions provided on each time step.
        shape = (len(discrete_actions),)
      except TypeError:
        min_, max_ = discrete_actions  # Enforces 2-tuple.
        shape = (1,)

      spec = specs.BoundedArraySpec(shape=shape,