def test_get_obs_has_correct_shape(data: st.DataObject) -> None: """ Make sure that a returned observation has the correct shape. """ env = data.draw(bst.envs()) env.reset() pos = data.draw(bst.positions(env=env)) ob = env._get_obs(pos) assert ob.shape == env.observation_space.shape
def test_get_obs_has_no_out_of_range_elements(data: st.DataObject) -> None: """ Make sure that a returned observation only contains 0 or 1. """ env = data.draw(bst.envs()) env.reset() pos = data.draw(bst.positions(env=env)) ob = env._get_obs(pos) for elem in np.nditer(ob): assert elem in (0.0, 1.0)
def update_pos(self, data: st.DataObject) -> None: pos = data.draw(bst.positions(env=self.env)) move = data.draw(bst.moves(env=self.env)) new_pos = self.env._update_pos(pos, move) if pos[0] != new_pos[0]: assert pos[1] == new_pos[1] assert abs(pos[0] - new_pos[0]) == 1 if pos[1] != new_pos[1]: assert pos[0] == new_pos[0] assert abs(pos[1] - new_pos[1]) == 1
def test_env_place_no_double_place_homo(data: st.DataObject) -> None: """ Tests that env gets angry if you try to double up h**o objs. """ env = data.draw(strategies.envs()) pos = data.draw(strategies.positions(env=env)) env.reset() homo_obj_type_ids = set( env.obj_type_ids.values()) - env.heterogeneous_obj_type_ids obj_type_id = data.draw(st.sampled_from(list(homo_obj_type_ids))) if not env._obj_exists(obj_type_id, pos): env._place(obj_type_id, pos) with pytest.raises(ValueError): env._place(obj_type_id, pos)
def test_get_obs_has_correct_objects(data: st.DataObject) -> None: """ Make sure that a returned observation is accurate w.r.t. ``env.grid``. """ env = data.draw(bst.envs()) env.reset() pos = data.draw(bst.positions(env=env)) ob = env._get_obs(pos) for i in range(ob.shape[1]): for j in range(ob.shape[2]): ob_pos = (pos[0] + i - env.sight_len, pos[1] + j - env.sight_len) if 0 <= ob_pos[0] < env.width and 0 <= ob_pos[1] < env.height: ob_square = ob[:, i, j] env_square = env.grid[ob_pos] assert np.all(ob_square == env_square) else: assert np.all(ob[:, i, j] == np.zeros((env.num_obj_types,)))
def test_mate_executes_action(data: st.DataObject) -> None: """ Tests children are created when they're suppsed to. """ env = data.draw(bst.envs()) assume(env.height * env.width >= 3) # Generate two adjacent positions. mom_pos = data.draw(bst.positions(env=env)) open_positions = env._get_adj_positions(mom_pos) dad_pos = data.draw(st.sampled_from(open_positions)) # Create a mom and dad. mom = Agent( config=env.config, num_actions=env.num_actions, pos=mom_pos, initial_health=1.0, ) dad = Agent( config=env.config, num_actions=env.num_actions, pos=dad_pos, initial_health=1.0, ) mom.is_mature = True dad.is_mature = True mom.mating_cooldown = 0 dad.mating_cooldown = 0 mom_id = env._new_agent_id() dad_id = env._new_agent_id() env.agents[mom_id] = mom env.agents[dad_id] = dad env._place(env.obj_type_ids["agent"], mom_pos, mom_id) env._place(env.obj_type_ids["agent"], dad_pos, dad_id) # Construct subactions. mom_move = data.draw(bst.moves(env=env)) dad_move = data.draw(bst.moves(env=env)) mom_consumption = data.draw(bst.consumptions(env=env)) dad_consumption = data.draw(bst.consumptions(env=env)) mom_action = (mom_move, mom_consumption, env.MATE) dad_action = (dad_move, dad_consumption, env.MATE) action_dict = {mom_id: mom_action, dad_id: dad_action} child_ids = env._mate(action_dict) assert len(child_ids) == 1 child = env.agents[child_ids.pop()] def adjacent(pos1: Tuple[int, int], pos2: Tuple[int, int]) -> bool: """ Decide whether or not two positions are orthogonally adjacent. """ return abs(pos1[0] - pos2[0]) + abs(pos1[1] - pos2[1]) == 1 assert len(env.agents) == 3 assert adjacent(child.pos, mom.pos) or adjacent(child.pos, dad.pos)
def test_obj_exists_detects_bad_id_map(data: st.DataObject) -> None: """ Make sure error is raised when ``id_map`` disagrees with ``grid``. """ env = data.draw(bst.envs()) obj_type_id = env.obj_type_ids["agent"] pos = data.draw(bst.positions(env=env)) x = pos[0] y = pos[1] grid_idx = pos + (obj_type_id, ) singleton_id_set = set([data.draw(st.integers(min_value=0, max_value=3))]) env.id_map[x][y][obj_type_id] = singleton_id_set raised_value_error = False try: _ = env._obj_exists(obj_type_id, pos) except ValueError: raised_value_error = True if env.grid[grid_idx] == 0: assert raised_value_error else: assert not raised_value_error
def test_obj_exists_handles_invalid_obj_type_ids(data: st.DataObject) -> None: """ Make sure the correct error is raised. """ env = data.draw(bst.envs()) obj_type_id = data.draw(st.integers(min_value=-10, max_value=10)) pos = data.draw(bst.positions(env=env)) raised_value_error = False try: existence = env._obj_exists(obj_type_id, pos) except ValueError as err: raised_value_error = True value_error = err # If the obj_type_id is invalid, should raise ValueError. if obj_type_id not in env.obj_type_names: assert raised_value_error # Otherwise, should raise no error. else: try: assert not raised_value_error except AssertionError: raise value_error