def create_arena_with_red_houses(t=DEFAULT_TIME_LIMIT): arena = Arena(t=t, items=[]) centers, radiuses = [], [] for idx in range(4): not_good_center = True while not_good_center: not_good_center = False radius = np.random.uniform(2, 4) center = np.random.randint(5, 35, 2) for _center, _radius in zip(centers, radiuses): distance = np.sqrt(np.sum((center - _center)**2)) if distance < radius + _radius + 4: not_good_center = True centers.append(center) radiuses.append(radius) goal_size = float(np.random.uniform(1, 2)) _add_red_circle_to_arena(arena, center=center, radius=radius, goal_size=goal_size) if idx < 2: arena.items.append( Item(name='GoodGoalMulti', sizes=[Vector3(1, 1, 1)], positions=[Vector3(center[0], 0, center[1])])) return arena
def _get_cell_walls_positions_and_sizes(cell, wall_thickness, n_cells, height): centers = np.linspace(0, 40, n_cells, endpoint=False)[1:].tolist() positions, sizes = [], [] cell_x_idx = cell.x cell_z_idx = cell.y # horizontal walls if cell_z_idx < n_cells - 1 and 's' in cell.walls: wall_length = (40 - n_cells*wall_thickness)/n_cells if not cell_x_idx or cell_x_idx == n_cells -1: wall_length += wall_thickness/2 sizes.append(Vector3(wall_length, height, wall_thickness)) if not cell_x_idx: x = centers[cell_x_idx] - wall_length/2 - wall_thickness/2 else: x = centers[cell_x_idx - 1] + wall_length/2 + wall_thickness/2 positions.append(Vector3(x, 0, centers[cell_z_idx])) # vertical walls if cell_x_idx < n_cells - 1 and 'e' in cell.walls: wall_length = (40 - n_cells*wall_thickness)/n_cells if not cell_z_idx or cell_z_idx == n_cells -1: wall_length += wall_thickness/2 sizes.append(Vector3(wall_thickness, height, wall_length)) if not cell_z_idx: z = centers[cell_z_idx] - wall_length/2 - wall_thickness/2 else: z = centers[cell_z_idx - 1] + wall_length/2 + wall_thickness/2 positions.append(Vector3(centers[cell_x_idx], 0, z)) return positions, sizes
def create_arena_with_small_goal(t): arena = Arena(t=t, items=[]) if np.random.randint(0, 2): arena.items.append( Item(name='GoodGoalMulti', sizes=[Vector3(0.5, 0.5, 0.5)])) else: arena.items.append( Item(name='GoodGoal', sizes=[Vector3(0.5, 0.5, 0.5)])) return arena
def _add_agent_to_arena(arena): while 1: try: x, z = np.random.uniform(1, 39, 2).tolist() goal = Item(name='Agent', sizes=[Vector3(*[1] * 3)]) goal.positions = [Vector3(x, 0, z)] detect_collisions(goal, arena.items) arena.items.append(goal) break except CollisionDetected: pass
def create_arena_with_bouncing_goal(t): arena = Arena(t=t, items=[]) size = float(np.random.choice([0.5, 1])) if np.random.randint(0, 2): arena.items.append( Item(name='GoodGoalMultiBounce', sizes=[Vector3(size, size, size)])) else: arena.items.append( Item(name='GoodGoalBounce', sizes=[Vector3(size, size, size)])) return arena
def _add_center_blocking_wall(arena): inmovable_objects = ['Wall', 'WallTransparent'] name = str(np.random.choice(inmovable_objects)) colors = [GRAY] sizes = [ Vector3(float(np.random.randint(15, 25)), float(np.random.randint(2, 10)), float(np.random.randint(15, 25))) ] positions = [Vector3(20, 0, 20)] item = Item(name=name, sizes=sizes, colors=colors, positions=positions) arena.items.append(item)
def _add_simple_goal(arena): while 1: try: x, z = np.random.uniform(1, 39, 2).tolist() goal = Item(name='GoodGoalMulti', sizes=[Vector3(*[1] * 3)], rotations=[0]) goal.positions = [Vector3(x, 0, z)] detect_collisions(goal, arena.items) arena.items.append(goal) break except CollisionDetected: pass
def _add_wall_to_arena(arena, orientation, position, goal_size): x_range = np.linspace(goal_size / 2, 40 - goal_size / 2, int((40 - goal_size) / (goal_size + 0.5))).tolist() x_range.pop(np.random.randint(len(x_range))) if orientation == 'horizontal': positions = [Vector3(float(position), 0, float(z)) for z in x_range] elif orientation == 'vertical': positions = [Vector3(float(x), 0, float(position)) for x in x_range] else: raise Exception('Unknown orientation: %s' % orientation) sizes = [Vector3(goal_size, goal_size, goal_size)] * len(positions) goal = Item(name='BadGoal', sizes=sizes, positions=positions) arena.items.append(goal)
def _get_pillars_positions(n_cells): centers = np.linspace(0, 40, n_cells, endpoint=False)[1:].tolist() positions = [] for x in centers: for z in centers: positions.append(Vector3(x, 0, z)) return positions
def _add_red_circle_to_arena(arena, center, radius, goal_size): theta_range = np.linspace(0, np.pi * 2, int((2 * np.pi * radius) / (goal_size + 0.5)), endpoint=False) theta_range += np.random.uniform(0, np.pi) theta_range = theta_range.tolist() theta_range.pop(np.random.randint(len(theta_range))) positions = [ Vector3(float(radius * np.cos(theta) + center[0]), 0, float(radius * np.sin(theta) + center[1])) for theta in theta_range ] sizes = [Vector3(goal_size, goal_size, goal_size)] * len(positions) goal = Item(name='BadGoal', sizes=sizes, positions=positions) arena.items.append(goal)
def _get_object_vertices(item, ref_angle, item_idx=0): try: size = item.sizes[item_idx] center = item.positions[item_idx] except IndexError: # This case happens when using random goals, that is why they are placed at the last position # when sampling return [] try: angles = [item.rotations[item_idx] - ref_angle] except IndexError: # If no rotation is given try with 0, 45 and 90 angles = [-ref_angle, 45 - ref_angle, 90 - ref_angle] object_radius = np.sqrt(size.x**2 + size.z**2) / 2 vertices = [] for angle in angles: for vertex_idx in range(4): if vertex_idx == 0: vertex_angle = np.arctan2(size.z, size.x) elif vertex_idx == 1: vertex_angle = -np.arctan2(size.z, size.x) elif vertex_idx == 2: vertex_angle = np.pi + np.arctan2(size.z, size.x) elif vertex_idx == 3: vertex_angle = np.pi - np.arctan2(size.z, size.x) vertex_angle -= angle * np.pi / 180 vertex = Vector3( np.cos(vertex_angle) * object_radius + center.x, 0, np.sin(vertex_angle) * object_radius + center.z) vertices.append(vertex) return vertices
def _add_goal_above_hot_zone(arena): while 1: try: zone = _create_random_zone(['HotZone']) border_distance = np.max([zone.sizes[0].x, zone.sizes[0].z]) * 1.2 x, z = np.random.uniform(border_distance, 40 - border_distance, 2).tolist() zone.positions = [Vector3(x, 0, z)] detect_collisions(zone, arena.items) arena.items.append(zone) break except CollisionDetected: pass goal = Item(name='GoodGoalMulti', sizes=[Vector3(*[1] * 3)], positions=[Vector3(x, 0, z)]) arena.items.append(goal)
def _create_random_box(): movable_objects = ['Cardbox1', 'Cardbox2'] name = str(np.random.choice(movable_objects)) x, z = np.random.randint(1, 6, 2).tolist() y = float(np.random.randint(1, 3)) sizes = [Vector3(x, y, z)] item = Item(name=name, sizes=sizes) return item
def _create_random_platform(): name = 'Wall' colors = [BLUE] x, z = np.random.randint(4, 8, 2).tolist() y = float(np.random.randint(1, 3)) sizes = [Vector3(x, y, z)] item = Item(name=name, sizes=sizes, colors=colors, rotations=[0]) return item
def _create_goal_in_front_of_agent(x, z, angle, goal_type='BadGoalBounce', min_distance=15, max_distance=20, size=-1): while 1: distance = np.random.randint(min_distance, max_distance) x_new, z_new = get_position_in_front_of_agent(x, z, angle, distance) if x_new > 0 + size / 2 and x_new < 40 - size / 2 and z_new > 0 + size / 2 and z_new < 40 - size / 2: break goal = Item(name=goal_type, positions=[Vector3(x_new, 0, z_new)], sizes=[Vector3(size, size, size)], rotations=[normalize_angle(angle + 180)]) return goal
def _add_goal_on_top_of_box(arena): while 1: try: box = _create_random_box() border_distance = np.max([box.sizes[0].x, box.sizes[0].z]) * 1.2 x, z = np.random.uniform(border_distance, 40 - border_distance, 2).tolist() box.positions = [Vector3(x, 0, z)] detect_collisions(box, arena.items) arena.items.append(box) break except CollisionDetected: pass goal = Item(name='GoodGoalMulti', sizes=[Vector3(*[1] * 3)], positions=[Vector3(x, box.sizes[0].y, z)]) arena.items.append(goal)
def _create_random_zone(zone_types=None): if zone_types is None: zone_types = ['DeathZone', 'HotZone'] name = str(np.random.choice(zone_types)) sizes = [Vector3(*np.random.randint(2, 10, 3).tolist())] item = Item(name=name, sizes=sizes, rotations=[float(np.random.randint(0, 360))]) return item
def _add_goals_and_agent_to_platform_maze(arena, n_cells, wall_thickness): centers = np.linspace(0, 40, n_cells, endpoint=False).tolist() wall_length = (40 - n_cells*wall_thickness)/n_cells if n_cells % 2 == 1: x_indexes = [0, n_cells//2, n_cells -1] else: x_indexes = [0, np.random.choice([n_cells//2, n_cells//2-1]), n_cells -1] z_indexes = x_indexes.copy() np.random.shuffle(x_indexes) np.random.shuffle(z_indexes) for idx in range(3): x = float(centers[x_indexes[idx]] + wall_length/2 + wall_thickness/2) z = float(centers[z_indexes[idx]] + wall_length/2 + wall_thickness/2) item = Item(name='GoodGoalMulti', sizes=[Vector3(*[1]*3)], positions=[Vector3(x, PLATFORM_HEIGHT, z)]) if not idx: item.name = 'Agent' arena.items.append(item)
def _add_goal_inside_cillinder(arena): while 1: try: cillinder = _create_random_cillinder() border_distance = np.max( [cillinder.sizes[0].x, cillinder.sizes[0].z]) * 1.2 x, z = np.random.uniform(border_distance, 40 - border_distance, 2).tolist() cillinder.positions = [Vector3(x, 0, z)] detect_collisions(cillinder, arena.items) arena.items.append(cillinder) break except CollisionDetected: pass goal = Item(name='GoodGoalMulti', sizes=[Vector3(*[1] * 3)], positions=[Vector3(x, 0, z)]) arena.items.append(goal)
def _add_random_inmovable_object(arena): inmovable_objects = [ 'Wall', 'WallTransparent', 'Ramp', 'CylinderTunnelTransparent', 'CylinderTunnel' ] name = str(np.random.choice(inmovable_objects)) if name in ['Wall', 'CylinderTunnel']: colors = [GRAY] elif name == 'Ramp': colors = [PINK] else: colors = [] if 'Wall' in name or name == 'Ramp': sizes = [Vector3(*np.random.randint(1, 10, 3).tolist())] else: sizes = [Vector3(*np.random.randint(3, 10, 3).tolist())] item = Item(name=name, sizes=sizes, colors=colors) arena.items.append(item)
def _create_random_cillinder(): inmovable_objects = ['CylinderTunnelTransparent', 'CylinderTunnel'] name = str(np.random.choice(inmovable_objects)) if name == 'CylinderTunnel': colors = [GRAY] else: colors = [] sizes = [Vector3(*np.random.randint(3, 10, 3).tolist())] item = Item(name=name, sizes=sizes, colors=colors) return item
def test_vector3(): vector3 = Vector3(x=10, y=15, z=20) assert vector3.x == 10 assert vector3.y == 15 assert vector3.z == 20 vector3_proto = vector3.to_proto() assert vector3_proto.x == 10 assert vector3_proto.y == 15 assert vector3_proto.z == 20
def _create_wall_in_front_of_agent(x, z, angle, wall_type='WallTransparent', min_distance=15, max_distance=20): size = 1 while 1: distance = np.random.randint(min_distance, max_distance) x_new, z_new = get_position_in_front_of_agent(x, z, angle, distance) if x_new > 0 + size / 2 and x_new < 40 - size / 2 and z_new > 0 + size / 2 and z_new < 40 - size / 2: break height = np.random.uniform(5, 10) width = np.random.uniform(10, 20) thickness = np.random.uniform(1, 2) wall = Item(name=wall_type, positions=[Vector3(x_new, 0, z_new)], sizes=[Vector3(width, height, thickness)], rotations=[normalize_angle(angle)]) return wall
def create_death_zone_arena_config(n_arenas=16, t=250): arena_config = ArenaConfig() for i in range(n_arenas): # サイズを指定: オリジナルは(1,0,1) - (40,0,40) sx = np.random.randint(1, 35) # 1~34まで sz = np.random.randint(1, 35) # 1~34まで size = Vector3(x=sx, y=0, z=sz) arena = create_death_zone_arena(size, t) arena_config.arenas[i] = arena return arena_config
def create_arena_with_red_wall(t=DEFAULT_TIME_LIMIT): arena = Arena(t=t, items=[]) orientation = np.random.choice(['horizontal', 'vertical']) goal_size = float(np.random.choice([1, 2, 3])) _add_wall_to_arena(arena, orientation='horizontal', position=np.random.randint(10, 30), goal_size=goal_size) if orientation == 'horizontal': arena.items.append( Item(name='GoodGoalMulti', sizes=[Vector3(1, 1, 1)] * 2, positions=[ Vector3(-1, 0, float(np.random.randint(1, 7))), Vector3(-1, 0, 40 - float(np.random.randint(1, 7))) ])) else: arena.items.append( Item(name='GoodGoalMulti', sizes=[Vector3(1, 1, 1)] * 2, positions=[ Vector3(float(np.random.randint(1, 7)), 0, -1), Vector3(40 - float(np.random.randint(1, 7)), 0, -1) ])) return arena
def _add_goal_on_top_of_platform(arena, empty_platform=False): while 1: try: platform = _create_random_platform() border_distance = np.max( [platform.sizes[0].x, platform.sizes[0].z]) * 1.2 x, z = np.random.uniform(border_distance, 40 - border_distance, 2).tolist() platform.positions = [Vector3(x, 0, z)] ramp = _create_ramp_for_platform(platform) detect_collisions(ramp, arena.items) detect_collisions(platform, arena.items) arena.items.append(platform) arena.items.append(ramp) break except CollisionDetected: pass if not empty_platform: goal = Item(name='GoodGoalMulti', sizes=[Vector3(*[1] * 3)], positions=[Vector3(x, platform.sizes[0].y, z)]) arena.items.append(goal)
def _add_reward_to_arena(arena, reward=DEFAULT_REWARD): remaining_reward = reward while remaining_reward: new_reward = np.random.uniform(0, remaining_reward) if new_reward < 0.5: new_reward = 0.5 if remaining_reward - new_reward < 0.5: new_reward = remaining_reward remaining_reward -= new_reward goal = Item(name='GoodGoalMulti', sizes=[Vector3(new_reward, new_reward, new_reward)]) arena.items.append(goal) return arena
def _create_ramp_for_platform(platform, rotation=None): """ Creates a ramp that allows to climb the platform Parameters ---------- platform : Item rotation : int If given the ramp will be placed with that orientation, otherwise it will be randomly sampled from 0, 90, 180, 270 """ position = platform.positions[0] size = platform.sizes[0] if rotation is None: rotation = float(np.random.choice([0, 90, 180, 270])) else: assert rotation in [0, 90, 180, 270] sizes = platform.sizes ramp_length = size.y * np.random.uniform(1, 3) if rotation == 0: sizes = [Vector3(size.x, size.y, ramp_length)] displacement = (size.z + ramp_length) / 2 positions = [ Vector3(position.x, position.y, position.z + displacement) ] elif rotation == 180: sizes = [Vector3(size.x, size.y, ramp_length)] displacement = (size.z + ramp_length) / 2 positions = [ Vector3(position.x, position.y, position.z - displacement) ] elif rotation == 90: sizes = [Vector3(size.z, size.y, ramp_length)] displacement = (size.x + ramp_length) / 2 positions = [ Vector3(position.x + displacement, position.y, position.z) ] elif rotation == 270: sizes = [Vector3(size.z, size.y, ramp_length)] displacement = (size.x + ramp_length) / 2 positions = [ Vector3(position.x - displacement, position.y, position.z) ] item = Item(name='Ramp', sizes=sizes, colors=[PINK], rotations=[rotation], positions=positions) return item
def create_arena_with_platform_maze(t, difficulty=None): arena = Arena(t=t, items=[]) if difficulty is None: difficulty = np.random.choice(DIFFICULTY_LEVELS) else: assert difficulty in DIFFICULTY_LEVELS if difficulty == 'easy': n_cells = 3 elif difficulty == 'medium': n_cells = np.random.randint(3, 5) elif difficulty == 'hard': n_cells = 4 else: raise Exception('Unknown difficulty: %s' % difficulty) wall_thickness = 6 _add_platform_maze(arena, n_cells=n_cells, wall_thickness=wall_thickness) _apply_color_to_platform_maze(arena) _add_goals_and_agent_to_platform_maze(arena, n_cells, wall_thickness) item = Item(name='DeathZone', sizes=[Vector3(40, 0, 40)], positions=[Vector3(20, 0, 20)], rotations=[0]) arena.items.append(item) return arena
def _add_zones_to_arena(arena, n_zones): for _ in range(n_zones): while 1: try: zone = _create_random_zone() border_distance = np.max([zone.sizes[0].x, zone.sizes[0].z ]) * 1.2 x, z = np.random.uniform(border_distance, 40 - border_distance, 2).tolist() zone.positions = [Vector3(x, 0, z)] detect_collisions(zone, arena.items) arena.items.append(zone) break except CollisionDetected: pass