def __init__(self, size=(200, 200), **playground_params): super().__init__(size=size, **playground_params) endgoal_01 = VisibleEndGoal(reward=50) self.add_element(endgoal_01, ((20, 180), 0)) deathtrap_01 = VisibleDeathTrap() self.add_element(deathtrap_01, ((180, 180), 0)) poison = Poison() self.add_element(poison, ((15, 15), 0)) poison_area = CoordinateSampler(area_shape='rectangle', center=(100, 150), size=(20, 20)) for _ in range(5): poison = Poison() self.add_element(poison, poison_area) candy_area = CoordinateSampler(area_shape='rectangle', center=(50, 100), size=(20, 20)) for _ in range(5): candy = Candy() self.add_element(candy, candy_area) # outside on purpose outside_area = CoordinateSampler(area_shape='rectangle', center=(200, 100), size=(50, 50)) for _ in range(8): candy = Candy() self.add_element(candy, outside_area)
def _assign_areas(self): list_coord = [(50, 50), (50, 150), (150, 150), (150, 50)] random.shuffle(list_coord) # Starting area of the agent area_start_center = list_coord.pop() area_start = CoordinateSampler(center=area_start_center, area_shape='rectangle', size=(80, 80)) agent_starting_area = area_start # invisible endzone at one corner of the game vm_center = list_coord.pop() prod_center = list_coord.pop() area_prod = CoordinateSampler(center=prod_center, area_shape='rectangle', size=(80, 80)) area_vm = CoordinateSampler(center=vm_center, area_shape='rectangle', size=(80, 80)) return agent_starting_area, area_prod, area_vm
def __init__(self, element_produced: Type[SceneElement], element_produced_params: Optional[Dict] = None, production_limit: Optional[int] = None, production_area: Optional[Union[SceneElement, CoordinateSampler]] = None, production_range: Optional[float] = None, **kwargs): """ Default: pink circle of radius 15. Args: element_produced: Class of the entity produced by the dispenser. element_produced_params: Dictionary of additional parameters for the entity_produced. production_area: PositionAreaSampler. If no production_area has been set, the entities will be produced around the dispenser. **kwargs: other params to configure entity. Refer to Entity class. Keyword Args: production_limit: maximum number of entities produced. Default: 15. """ super().__init__(config_key=ElementTypes.DISPENSER, **kwargs) self.elem_class_produced = element_produced if not element_produced_params: element_produced_params = {} self.element_produced_params = element_produced_params self._recompute_center = False self._center_elem = None if not production_area: production_area = self if isinstance(production_area, SceneElement): assert production_range self._recompute_center = True self._center_elem = production_area radius = production_area.radius + production_range min_radius = production_area.radius self._coordinates_sampler = CoordinateSampler( area_shape='circle', center=(0, 0), radius=radius, min_radius=min_radius) else: assert isinstance(production_area, CoordinateSampler) self._coordinates_sampler = production_area self.production_limit = production_limit self.produced_entities: List[SceneElement] = []
def __init__( self, time_limit=1000, wall_texture_seed=None, ): super().__init__(size=(450, 150), number_rooms=3, doorstep_size=60, wall_type='colorful', playground_seed=wall_texture_seed) self.time_limit = time_limit doorstep_1 = self.grid_rooms[0, 1].doorstep_right door = doorstep_1.generate_door() self.add_element(door) lock = Lock(door=door) lock_position = self.grid_rooms[0, 1].get_random_position_on_wall( 'right', element=lock) self.add_element(lock, lock_position) area_key = self.grid_rooms[0, 0].get_area_sampler() key = Key(graspable=True, locked_elem=lock) self.add_element(key, area_key, allow_overlapping=False) vm_center, vm_shape = self.grid_rooms[0, 2].get_partial_area('up-right') area_vm = CoordinateSampler(center=vm_center, area_shape='rectangle', size=vm_shape) vm = VendingMachine(reward=5) self.add_element(vm, area_vm, allow_overlapping=False) dispenser_center, dispenser_shape = self.grid_rooms[ 0, 2].get_partial_area('down-right') area_dispenser = CoordinateSampler(center=dispenser_center, area_shape='rectangle', size=dispenser_shape) area_prod = self.grid_rooms[0, 0].get_area_sampler() dispenser = Dispenser(Coin, production_area=area_prod, entity_produced_params={ 'graspable': True, 'vending_machine': vm }) self.add_element(dispenser, area_dispenser, allow_overlapping=False) self.initial_agent_coordinates = self.grid_rooms[0, 1].get_area_sampler()
def __init__(self, size=(200, 200), **playground_params): super().__init__(size=size, **playground_params) area_1 = CoordinateSampler(area_shape='rectangle', center=(70, 70), size=(30, 100)) spawner = Spawner(Poison, production_area=area_1) self.add_spawner(spawner) area_2 = CoordinateSampler(area_shape='rectangle', center=(200, 70), size=(50, 50)) spawner = Spawner(Candy, production_area=area_2) self.add_spawner(spawner)
def test_add_remove_agent_in_area(base_forward_agent_random): playground_1 = SingleRoom((800, 400)) agent = base_forward_agent_random areas = { 'up': [0, 800, 0, 200], 'down': [0, 800, 200, 400], 'right': [400, 800, 0, 400], 'left': [0, 400, 0, 400], 'up-right': [400, 800, 0, 200], 'up-left': [0, 400, 0, 200], 'down-right': [400, 800, 200, 400], 'down-left': [0, 400, 200, 400], 'center': [200, 600, 100, 300] } for area_name, coord in areas.items(): location, size = playground_1.grid_rooms[0][0].get_partial_area( area_name) pos_area_sampler = CoordinateSampler(location, area_shape='rectangle', size=size) playground_1.add_agent(agent, pos_area_sampler) min_x, max_x, min_y, max_y = coord assert min_x < agent.position[0] < max_x assert min_y < agent.position[1] < max_y playground_1.remove_agent(agent)
def test_dispenser_limit(base_forward_interactive_agent_external): playground = SingleRoom(size=(200, 200)) agent = base_forward_interactive_agent_external dispenser = Dispenser( element_produced=Candy, production_area=CoordinateSampler(center=(50, 100), area_shape='circle', radius=10), production_limit=1, invisible_range=40, element_produced_params={'reward': 1}) playground.add_agent(agent, ((100, 100), 0)) playground.add_element(dispenser, ((140, 100), 0)) engine = Engine(playground, time_limit=100) total_rew = 0 while engine.game_on: if engine.elapsed_time < 50: actions = {agent: {agent.activate: 1}} else: actions = {agent: {agent.longitudinal_force: -1.}} engine.step(actions) total_rew += agent.reward assert total_rew == 1
def get_area_sampler(self): width, length = self.size width -= 2 * self._wall_depth length -= 2 * self._wall_depth return CoordinateSampler(center=self.center, area_shape='rectangle', size=(width, length))
def __init__(self, size=(300, 700), **playground_params): super().__init__(size=size, **playground_params) pos_left = (100, 100) pos_right = (200, 100) vis_beam = InvisibleBeam(destination=(pos_right, math.pi)) self.add_element(vis_beam, (pos_left, 0)) pos_left = pos_left[0], pos_left[1] + 100 pos_right = pos_right[0], pos_right[1] + 100 coord_sampler = CoordinateSampler(pos_right, area_shape='circle', radius=20) vis_beam = InvisibleBeam(destination=coord_sampler, keep_inertia=False) self.add_element(vis_beam, (pos_left, 0)) pos_left = pos_left[0], pos_left[1] + 100 pos_right = pos_right[0], pos_right[1] + 100 target = Physical(config_key='circle', radius=5) self.add_element(target, (pos_right, 0)) homing = VisibleBeamHoming(destination=target, keep_inertia=True, relative_teleport=False) self.add_element(homing, (pos_left, math.pi)) pos_left = pos_left[0], pos_left[1] + 100 pos_right = pos_right[0], pos_right[1] + 100 target = Physical(config_key='circle', radius=5) self.add_element(target, (pos_right, math.pi / 2)) homing = VisibleBeamHoming(destination=target, relative_teleport=True, keep_inertia=False) self.add_element(homing, (pos_left, 0)) pos_left = pos_left[0], pos_left[1] + 100 pos_right = pos_right[0], pos_right[1] + 100 target = Traversable(config_key='circle', radius=10) self.add_element(target, (pos_right, math.pi / 2)) homing = VisibleBeamHoming(destination=target, relative_teleport=True, keep_inertia=False) self.add_element(homing, (pos_left, 0)) pos_left = pos_left[0] - 90, pos_left[1] + 100 pos_right = pos_right[0] + 90, pos_right[1] + 100 portal_red = Portal(color=PortalColor.RED) self.add_element(portal_red, (pos_left, 0)) portal_blue = Portal(color=PortalColor.BLUE) self.add_element(portal_blue, (pos_right, math.pi)) portal_red.destination = portal_blue portal_blue.destination = portal_red
def __init__(self, size=(300, 300), **playground_params): super().__init__(size=size, room_layout=(2, 2), doorstep_size=40, **playground_params) doorstep_1 = self.grid_rooms[0, 0].doorstep_right door_1 = doorstep_1.generate_door() self.add_element(door_1) switch_1 = OpenCloseSwitch(door=door_1) self.add_element( switch_1, self.grid_rooms[0, 0].get_random_position_on_wall('right', switch_1)) doorstep_2 = self.grid_rooms[0, 0].doorstep_down door_2 = doorstep_2.generate_door() self.add_element(door_2) timer = CountDownTimer(duration=100) switch_2 = TimerSwitch(door=door_2, timer=timer) self.add_element( switch_2, self.grid_rooms[0, 0].get_random_position_on_wall('down', switch_2)) self.add_timer(timer, switch_2) doorstep_3 = self.grid_rooms[1, 0].doorstep_right door_3 = doorstep_3.generate_door() self.add_element(door_3) lock = Lock(door=door_3) self.add_element( lock, self.grid_rooms[1, 0].get_random_position_on_wall('left', lock)) key = Key(locked_elem=lock, graspable=True, mass=5) center, size = self.grid_rooms[1, 0].get_partial_area('left-down') area_sampler = CoordinateSampler(center=center, size=size, area_shape='rectangle') self.add_element(key, area_sampler) doorstep_4 = self.grid_rooms[1, 1].doorstep_up door_4 = doorstep_4.generate_door() self.add_element(door_4) switch_4 = ContactSwitch(door=door_4) self.add_element( switch_4, self.grid_rooms[1, 1].get_random_position_on_wall('up', switch_4))
def __init__( self, time_limit=1000, reward_reached_time_limit=-10, reward_reached_endgoal=10, reward_reached_deathtrap=-10, playground_seed: Optional[int] = None, ): super().__init__(size=(200, 200), playground_seed=playground_seed) # Starting area of the agent area_center = self.grid_rooms[0][0].center area_start = CoordinateSampler(center=area_center, area_shape='rectangle', size=(100, 100)) self.initial_agent_coordinates = area_start # Visual Cues for the agent to orient itself. obstacle_1 = Physical(config_key='pentagon', radius=9) self.add_element(obstacle_1, ((60, 30), 0.34)) obstacle_2 = Physical(config_key='rectangle', size=[8, 12]) self.add_element(obstacle_2, ((130, 150), 1.7)) obstacle_3 = Physical(config_key='square', radius=8) self.add_element(obstacle_3, ((40, 140), 0.4)) obstacle_4 = Physical(physical_shape='triangle', radius=14, texture=(150, 200, 200)) self.add_element(obstacle_4, ((160, 60), 0)) self.goal = None self.cue = None self.goal_locations = (((20, 20), 0), ((180, 20), 0), ((180, 180), 0), ((20, 180), 0)) self.cue_colors = ((200, 50, 200), (50, 200, 50), (200, 50, 50), (50, 50, 200)) self.reward_goal = reward_reached_endgoal self.reward_deathtrap = reward_reached_deathtrap self._set_goal() self.time_limit = time_limit self.time_limit_reached_reward = reward_reached_time_limit
def __init__(self, time_limit=100, probability_production=0.4): super().__init__(size=(200, 200)) fireball_texture = { 'texture_type': 'centered_random_tiles', 'size_tiles': 4 } # First Fireball text_1 = {'color_min': [220, 0, 200], 'color_max': [255, 100, 220]} trajectory = Trajectory('waypoints', trajectory_duration=300, waypoints=[[20, 20], [20, 180], [180, 180], [180, 20]]) fireball = Fireball(reward=-1, texture={**fireball_texture, **text_1}) self.add_element(fireball, trajectory) # Second Fireball text_2 = {'color_min': [180, 0, 0], 'color_max': [220, 100, 0]} trajectory = Trajectory('waypoints', trajectory_duration=150, waypoints=[[40, 40], [160, 160]]) fireball = Fireball(reward=-2, texture={**fireball_texture, **text_2}) self.add_element(fireball, trajectory) # Third Fireball text_3 = {'color_min': [220, 100, 0], 'color_max': [255, 120, 0]} trajectory = Trajectory('waypoints', trajectory_duration=180, waypoints=[[40, 160], [160, 40]]) fireball = Fireball(reward=-5, texture={**fireball_texture, **text_3}) self.add_element(fireball, trajectory) # Foraging area_prod = CoordinateSampler(center=(100, 100), area_shape='rectangle', size=(150, 150)) spawner = Spawner(Candy, production_area=area_prod, probability=probability_production) self.add_spawner(spawner) self.time_limit = time_limit
def test_beam_area(base_forward_interactive_agent_external): playground = SingleRoom(size=(200, 200)) agent = base_forward_interactive_agent_external area = CoordinateSampler(center=(50, 50), area_shape='rectangle', size=(20, 20)) beam = InvisibleBeam(destination=area) playground.add_agent(agent, ((100, 100), 0)) playground.add_element(beam, ((140, 100), 0)) engine = Engine(playground, time_limit=100) actions = {agent: {agent.longitudinal_force: 1}} while not agent.has_teleported: engine.step(actions) assert 30 <= agent.position[0] <= 80 assert 30 <= agent.position[1] <= 80
def __init__( self, time_limit=1000, playground_seed: Optional[int] = None, ): super().__init__(size=(450, 450), room_layout=(3, 3), wall_type='colorful', playground_seed=playground_seed, doorstep_size=60) # Starting area of the agent area_start = CoordinateSampler(center=(225, 225), area_shape='rectangle', size=(450, 450)) self.initial_agent_coordinates = area_start # invisible endzone at one corner of the game invisible_endzone = GoalZone(reward=10) self.add_element(invisible_endzone, ((20, 20), 0)) self.time_limit = time_limit
def __init__( self, size: Tuple[int, int], room_layout: Union[List[int], Tuple[int, int]], doorstep_size: float, random_doorstep_position: bool = True, wall_type: Optional[str] = 'classic', wall_depth: Optional[float] = WALL_DEPTH, playground_seed: Optional[int] = None, wall_texture: Optional[Union[Texture, Dict, Tuple[int, int, int]]] = None, ): """ Args: size: room_layout: doorstep_size: doorstep_type: wall_type: wall_texture_seed: **wall_params: Wall texture takes priority on wall type. Several wall types are already implemented: classic, light, dark, colorful """ # Playground Layout assert isinstance(room_layout, (list, tuple)) assert len(room_layout) == 2\ and isinstance(room_layout[0], int)\ and isinstance(room_layout[1], int) self.width_room = size[0] / room_layout[1] self.length_room = size[1] / room_layout[0] # Check that there is enough space for doorsteps if self.width_room - 2*wall_depth < doorstep_size \ or self.length_room - 2*wall_depth < doorstep_size: raise ValueError("Doorstep too large wrt room size") super().__init__() self._size = size self._width, self._length = self._size self._center = (self._width / 2, self._length / 2) self._size_door = (wall_depth, doorstep_size) self.rng_playground = np.random.default_rng(playground_seed) # If wall texture is provided, use it if isinstance(wall_texture, Dict): wall_texture = TextureGenerator.create(**wall_texture, rng=self.rng_playground) elif isinstance(wall_texture, (tuple, list)): wall_texture = ColorTexture(color=wall_texture) # if not, use default if not wall_texture: # Wall parameters default_wall_texture_params = parse_configuration( 'playground', wall_type) wall_texture = TextureGenerator.create(** default_wall_texture_params, rng=self.rng_playground) assert isinstance(wall_texture, Texture) self._wall_texture = wall_texture self._wall_depth = wall_depth # Set random texture for possible replication self.grid_rooms = self._generate_rooms(room_layout, random_doorstep_position, doorstep_size) # By default, an agent starts in a random position of the first room first_room = self.grid_rooms[0, 0] assert isinstance(first_room, RectangleRoom) center_first_room = first_room.center size_first_room = first_room.width - 2 * wall_depth, first_room.length - 2 * wall_depth self.initial_agent_coordinates = CoordinateSampler( center=center_first_room, area_shape='rectangle', size=size_first_room)
class Dispenser(ActivableElement): """Dispenser produces a new entity in an area of the playground when activated. """ def __init__(self, element_produced: Type[SceneElement], element_produced_params: Optional[Dict] = None, production_limit: Optional[int] = None, production_area: Optional[Union[SceneElement, CoordinateSampler]] = None, production_range: Optional[float] = None, **kwargs): """ Default: pink circle of radius 15. Args: element_produced: Class of the entity produced by the dispenser. element_produced_params: Dictionary of additional parameters for the entity_produced. production_area: PositionAreaSampler. If no production_area has been set, the entities will be produced around the dispenser. **kwargs: other params to configure entity. Refer to Entity class. Keyword Args: production_limit: maximum number of entities produced. Default: 15. """ super().__init__(config_key=ElementTypes.DISPENSER, **kwargs) self.elem_class_produced = element_produced if not element_produced_params: element_produced_params = {} self.element_produced_params = element_produced_params self._recompute_center = False self._center_elem = None if not production_area: production_area = self if isinstance(production_area, SceneElement): assert production_range self._recompute_center = True self._center_elem = production_area radius = production_area.radius + production_range min_radius = production_area.radius self._coordinates_sampler = CoordinateSampler( area_shape='circle', center=(0, 0), radius=radius, min_radius=min_radius) else: assert isinstance(production_area, CoordinateSampler) self._coordinates_sampler = production_area self.production_limit = production_limit self.produced_entities: List[SceneElement] = [] def activate(self, _): elem_add = None if not self.production_limit or len( self.produced_entities) < self.production_limit: self.activated = True if self._recompute_center: initial_coordinate = self._coordinates_sampler.sample( self._center_elem.coordinates) else: initial_coordinate = self._coordinates_sampler.sample() elem = self.elem_class_produced(temporary=True, **self.element_produced_params) self.produced_entities.append(elem) elem_add = [(elem, initial_coordinate)] return None, elem_add def reset(self): self.produced_entities = [] super().reset()
def __init__(self, size=(200, 400), **playground_params): super().__init__(size=size, **playground_params) self.initial_agent_coordinates = ((100, 50), 3.14) x_dispenser = 50 x_area = 150 # Dispenser on Area area = CoordinateSampler(area_shape='rectangle', center=(x_area, 50), size=(20, 60), angle=math.pi / 3) dispenser = Dispenser( element_produced=Poison, element_produced_params={'reward': -5}, production_area=area, production_limit=20, ) self.add_element(dispenser, ((x_dispenser, 50), 0)) # Dispenser on Area area = CoordinateSampler(area_shape='circle', center=(x_area, 100), radius=30) dispenser = Dispenser( element_produced=Poison, element_produced_params={'reward': -5}, production_area=area, ) self.add_element(dispenser, ((x_dispenser, 100), 0)) # Dispenser on Area area = CoordinateSampler(area_shape='circle', center=(x_area, 150), radius=50, min_radius=30) dispenser = Dispenser( element_produced=Candy, element_produced_params={'reward': 5}, production_area=area, ) self.add_element(dispenser, ((x_dispenser, 150), 0)) # Dispenser on Area area = CoordinateSampler(area_shape='gaussian', center=(x_area, 200), std=30, radius=60) dispenser = Dispenser( element_produced=Poison, element_produced_params={'reward': -5}, production_area=area, ) self.add_element(dispenser, ((x_dispenser, 200), 0)) # Dispenser on Area area = CoordinateSampler(area_shape='gaussian', center=(x_area, 250), std=40, radius=60, min_radius=20) dispenser = Dispenser( element_produced=Candy, element_produced_params={'reward': 5}, production_area=area, ) self.add_element(dispenser, ((x_dispenser, 250), 0)) # Dispenser on Dispenser dispenser = Dispenser(element_produced=Candy, element_produced_params={'reward': 5}, production_range=20, graspable=True) self.add_element(dispenser, ((x_dispenser, 300), 0)) # Dispenser on Element pentagon_01 = Physical(config_key='pentagon', radius=15, graspable=True, mass=5) self.add_element(pentagon_01, ((x_area, 350), math.pi / 2)) dispenser = Dispenser(element_produced=Candy, element_produced_params={'reward': 5}, production_range=20, production_area=pentagon_01) self.add_element(dispenser, ((x_dispenser, 350), 0))