# Path: spriteworld/action_spaces.py
# class SelectMove(object):
# class DragAndDrop(SelectMove):
# class Embodied(object):
#   def __init__(self, scale=1.0, motion_cost=0.0, noise_scale=None):
#   def get_motion(self, action):
#   def apply_noise_to_action(self, action):
#   def get_sprite_from_position(self, position, sprites):
#   def step(self, action, sprites, keep_in_frame):
#   def sample(self):
#   def action_spec(self):
#   def get_motion(self, action):
#   def __init__(self, step_size=0.05, motion_cost=0.):
#   def get_body_sprite(self, sprites):
#   def get_non_body_sprites(self, sprites):
#   def get_carried_sprite(self, sprites):
#   def step(self, action, sprites, keep_in_frame):
#   def sample(self):
#   def action_spec(self):
# 
# Path: spriteworld/sprite.py
# FACTOR_NAMES = (
#     'x',  # x-position of sprite center-of-mass (float)
#     'y',  # y-position of sprite center-of-mass (float)
#     'shape',  # shape (string)
#     'angle',  # angle in degrees (scalar)
#     'scale',  # size of sprite (float)
#     'c0',  # first color component (scalar)
#     'c1',  # second color component (scalar)
#     'c2',  # third color component (scalar)
#     'x_vel',  # x-component of velocity (float)
#     'y_vel',  # y-component of velocity (float)
# )
# _MAX_TRIES = int(1e6)
# class Sprite(object):
#   def __init__(self,
#                x=0.5,
#                y=0.5,
#                shape='square',
#                angle=0,
#                scale=0.1,
#                c0=0,
#                c1=0,
#                c2=0,
#                x_vel=0.0,
#                y_vel=0.0):
#   def _reset_centered_path(self):
#   def move(self, motion, keep_in_frame=False):
#   def update_position(self, keep_in_frame=False):
#   def contains_point(self, point):
#   def sample_contained_position(self):
#   def vertices(self):
#   def out_of_frame(self):
#   def x(self):
#   def y(self):
#   def shape(self):
#   def shape(self, s):
#   def angle(self):
#   def angle(self, a):
#   def scale(self):
#   def scale(self, s):
#   def c0(self):
#   def c1(self):
#   def c2(self):
#   def x_vel(self):
#   def y_vel(self):
#   def color(self):
#   def position(self):
#   def velocity(self):
#   def factors(self):


from absl.testing import absltest
from absl.testing import parameterized
from spriteworld import action_spaces
from spriteworld import sprite
import numpy as np
    action_space.step(
        np.array([0.92, 0.9, 0.9, 0.5]), sprites, keep_in_frame=True)
    self.assertTrue(np.allclose(sprites[0].position, [1., 0.9], atol=1e-5))
    self.assertTrue(np.allclose(sprites[1].position, [0.35, 0.49], atol=1e-5))

    # Move first (bottom) sprite
    action_space.step(
        np.array([0.98, 0.9, 0.7, 0.9]), sprites, keep_in_frame=False)
    self.assertTrue(np.allclose(sprites[0].position, [1.1, 1.1], atol=1e-5))
    self.assertTrue(np.allclose(sprites[1].position, [0.35, 0.49], atol=1e-5))

  @parameterized.named_parameters(
      ('NoNoise', np.array([0.5, 0.5, 0.2, 0.75]), 0.),
      ('Noise', np.array([0.5, 0.5, 0.2, 0.75]), 0.2),
      ('NoiseOutOfBounds', np.array([0.2, 0.3, 0.9, 0.05]), 0.2),
      ('HighNoise', np.array([0.5, 0.5, 0.2, 0.75]), 0.5))
  def testNoiseScale(self, action, noise_scale):
    action_space = action_spaces.SelectMove(scale=0.1, noise_scale=noise_scale)
    action_space.apply_noise_to_action(action)


class DragAndDropTest(parameterized.TestCase):

  @parameterized.named_parameters(
      ('MoveUpRight', 1, np.array([0.5, 0.5, 0.75, 0.75]), (0.25, 0.25)),
      ('MoveDownLeft', 1, np.array([0.2, 0.5, -0.2, -0.75]), (-0.4, -1.25)),
      ('ScaledMove', 0.5, np.array([0.5, 0.5, 0.8, 0.8]), (0.15, 0.15)),
      ('MoveEdge', 0.5, np.array([0.0, 0.0, -0.2, -0.4]), (-0.1, -0.2)),
  )
  def testGetMotion(self, scale, action, true_motion):

# Path: spriteworld/action_spaces.py
# class SelectMove(object):
# class DragAndDrop(SelectMove):
# class Embodied(object):
#   def __init__(self, scale=1.0, motion_cost=0.0, noise_scale=None):
#   def get_motion(self, action):
#   def apply_noise_to_action(self, action):
#   def get_sprite_from_position(self, position, sprites):
#   def step(self, action, sprites, keep_in_frame):
#   def sample(self):
#   def action_spec(self):
#   def get_motion(self, action):
#   def __init__(self, step_size=0.05, motion_cost=0.):
#   def get_body_sprite(self, sprites):
#   def get_non_body_sprites(self, sprites):
#   def get_carried_sprite(self, sprites):
#   def step(self, action, sprites, keep_in_frame):
#   def sample(self):
#   def action_spec(self):
# 
# Path: spriteworld/sprite.py
# FACTOR_NAMES = (
#     'x',  # x-position of sprite center-of-mass (float)
#     'y',  # y-position of sprite center-of-mass (float)
#     'shape',  # shape (string)
#     'angle',  # angle in degrees (scalar)
#     'scale',  # size of sprite (float)
#     'c0',  # first color component (scalar)
#     'c1',  # second color component (scalar)
#     'c2',  # third color component (scalar)
#     'x_vel',  # x-component of velocity (float)
#     'y_vel',  # y-component of velocity (float)
# )
# _MAX_TRIES = int(1e6)
# class Sprite(object):
#   def __init__(self,
#                x=0.5,
#                y=0.5,
#                shape='square',
#                angle=0,
#                scale=0.1,
#                c0=0,
#                c1=0,
#                c2=0,
#                x_vel=0.0,
#                y_vel=0.0):
#   def _reset_centered_path(self):
#   def move(self, motion, keep_in_frame=False):
#   def update_position(self, keep_in_frame=False):
#   def contains_point(self, point):
#   def sample_contained_position(self):
#   def vertices(self):
#   def out_of_frame(self):
#   def x(self):
#   def y(self):
#   def shape(self):
#   def shape(self, s):
#   def angle(self):
#   def angle(self, a):
#   def scale(self):
#   def scale(self, s):
#   def c0(self):
#   def c1(self):
#   def c2(self):
#   def x_vel(self):
#   def y_vel(self):
#   def color(self):
#   def position(self):
#   def velocity(self):
#   def factors(self):


# Path: tests/action_spaces_test.py
from absl.testing import absltest
from absl.testing import parameterized
from spriteworld import action_spaces
from spriteworld import sprite
import numpy as np

    action_space.step(
        np.array([0.92, 0.9, 0.9, 0.5]), sprites, keep_in_frame=True)
    self.assertTrue(np.allclose(sprites[0].position, [1., 0.9], atol=1e-5))
    self.assertTrue(np.allclose(sprites[1].position, [0.35, 0.49], atol=1e-5))

    # Move first (bottom) sprite
    action_space.step(
        np.array([0.98, 0.9, 0.7, 0.9]), sprites, keep_in_frame=False)
    self.assertTrue(np.allclose(sprites[0].position, [1.1, 1.1], atol=1e-5))
    self.assertTrue(np.allclose(sprites[1].position, [0.35, 0.49], atol=1e-5))

  @parameterized.named_parameters(
      ('NoNoise', np.array([0.5, 0.5, 0.2, 0.75]), 0.),
      ('Noise', np.array([0.5, 0.5, 0.2, 0.75]), 0.2),
      ('NoiseOutOfBounds', np.array([0.2, 0.3, 0.9, 0.05]), 0.2),
      ('HighNoise', np.array([0.5, 0.5, 0.2, 0.75]), 0.5))
  def testNoiseScale(self, action, noise_scale):
    action_space = action_spaces.SelectMove(scale=0.1, noise_scale=noise_scale)
    action_space.apply_noise_to_action(action)


class DragAndDropTest(parameterized.TestCase):

  @parameterized.named_parameters(
      ('MoveUpRight', 1, np.array([0.5, 0.5, 0.75, 0.75]), (0.25, 0.25)),
      ('MoveDownLeft', 1, np.array([0.2, 0.5, -0.2, -0.75]), (-0.4, -1.25)),
      ('ScaledMove', 0.5, np.array([0.5, 0.5, 0.8, 0.8]), (0.15, 0.15)),
      ('MoveEdge', 0.5, np.array([0.0, 0.0, -0.2, -0.4]), (-0.1, -0.2)),
  )
  def testGetMotion(self, scale, action, true_motion):

    action_space = action_spaces.DragAndDrop(scale=scale)