Exemplo n.º 1
0
        def begin_poison_collision(arbiter, space, *args, **kwargs):

            # Remove the previous shape
            shapes = arbiter.shapes
            for shape in shapes:
                if shape.collision_type == 3:
                    self.poisons.remove(shape.body.entity)
                    space.remove((shape, shape.body))

                    # Update the measurements
                    self.agent.update_meas('items', 1)
                    self.agent.update_health(shape.body.entity.reward, self.mode)
                    self.agent.update_meas('poisons', 1)
                    self.agent.reward += shape.body.entity.reward

            if self.poison_params['respawn']:
                if self.mapp_:
                    self.poison_params['position'] = self.mapp_.generate_random_point()[-1]
                self.poisons.append(Edible(**self.poison_params))

            return False
Exemplo n.º 2
0
    def __init__(self, **kwargs):
        """
        Instantiate a game with the given parameters
        :param horizon: int, time horizon of an episode
        :param done: bool, True if the episode is terminated
        :param mode: 'goal' or 'health':
            - if 'goal' : we use the field goal to create a goal and the simulation ends
                when the goal is reached or when we reach the horizon
            - if 'survival', the health measurements in initialized to 100 and the simulation
                ends when the health reaches 0 or when we reach the horizon
        :param shape: size 2 tuple with height and width of the environment
        :param goal: dict with the following fields, only useful if mode is 'goal'
            - size: float, size of the goal
            - position: size 2 tuple giving the position or 'random'
        :param walls: dict with the following fields:
            - number: int, number of walls in the environment
            - size: float, size of the walls
            - position: array of coordinates or 'random'
        :param poisons: dict with the following fields
            - number: int, number of poisons in the environment
            - size: float, size of the poisons
            - reap: bool, whether another poison object reappears when one is consumed
        :param fruits: dict with the following fields
             - number: int, number of fruits in the environment
             - size: float, size of the fruits
             - reap: bool, whether another fruit object reappears when one is consumed
        :param agent: the agent evolving in the environment
        :param display: bool, whether to display the task or not
        """

        # Save the arguments for reset
        self.parameters = kwargs

        if not kwargs['map']:
            self.mapp_ = False

        self.done = False
        self.t = 0
        self.horizon = kwargs['horizon']
        self.width, self.height = kwargs['shape']
        self.display = kwargs['display']
        if self.display:
            self.screen = pygame.display.set_mode((self.width, self.height))
            self.screen.set_alpha(None)
        else:
            self.screen = pygame.Surface((self.width, self.height))
            self.screen.set_alpha(None)
        self.clock = pygame.time.Clock()

        self.npimage = np.zeros((self.width, self.height, 3))

        # Set a surface to compute Sensors

        # Initialize pymunk space
        self.space = pymunk.Space()
        self.space.gravity = pymunk.Vec2d(0., 0.)
        self.space.collision_slop = 0
        self.space.collision_persistence = 1
        self.space.collision_bias = 0
        self.handle_collisions()

        # Define the external walls
        texture_params = kwargs['walls_texture']
        self.obstacles = [
            Obstacle(shape='rectangle',
                     position=(self.width / 2, 5),
                     angle=0,
                     texture=texture_params,
                     environment=self,
                     length=self.width,
                     width=10),
            Obstacle(shape='rectangle',
                     position=(self.width / 2, self.height - 5),
                     angle=0,
                     texture=texture_params,
                     environment=self,
                     length=self.width,
                     width=10),
            Obstacle(shape='rectangle',
                     position=(5, self.height / 2),
                     angle=math.pi / 2,
                     texture=texture_params,
                     environment=self,
                     length=self.height,
                     width=10),
            Obstacle(shape='rectangle',
                     position=(self.width - 5, self.height / 2),
                     angle=math.pi / 2,
                     texture=texture_params,
                     environment=self,
                     length=self.height,
                     width=10)
        ]

        # Add obstacles
        if not kwargs['map']:
            for obstacle_params in kwargs['obstacles']:
                obstacle_params['environment'] = self
                obstacle = Obstacle(**obstacle_params)
                self.obstacles.append(obstacle)

        if kwargs['map']:
            #create map object and check for connectivity
            self.mapp_ = Dungeons(space_size=(self.width, self.height),
                                  n_rooms=kwargs['n_rooms'])
            while not self.mapp_.topology.geom_type == 'Polygon':
                self.mapp_ = Dungeons(space_size=(self.width, self.height),
                                      n_rooms=kwargs['n_rooms'])
                print(self.mapp_.topology.geom_type)
            #arrange walls
            for wall in self.mapp_.walls:
                self.obstacles.append(
                    Obstacle(shape='rectangle',
                             position=(wall.x, self.height - wall.y),
                             angle=0,
                             texture=wall.texture,
                             environment=self,
                             width=wall.height,
                             length=wall.width))

        # Define the episode mode
        self.mode = kwargs['mode']

        # Create the goal in goal mode
        if self.mode == 'goal':
            self.goal_size = kwargs['goal']['size']
            self.goal = self.create_goal(kwargs['goal']['position'])
            if 'goal' not in kwargs['agent']['measurements']:
                kwargs['agent']['measurements'].append('goal')

        # Make sure we have the right measurements in survival mode
        if self.mode == 'survival':
            if 'health' not in kwargs['agent']['measurements']:
                kwargs['agent']['measurements'].append('health')
            if 'dead' not in kwargs['agent']['measurements']:
                kwargs['agent']['measurements'].append('dead')

        # Create the poisons
        self.poison_params = kwargs['poisons'].copy()
        self.poisons = []
        self.poison_params['environment'] = self
        self.poison_params['collision_type'] = 3
        if self.poison_params['positions'] == 'random':
            positions = ['random'] * self.poison_params['number']
            if kwargs['map']:
                positions = self.mapp_.generate_random_point(
                    self.poison_params['number'])
        else:
            positions = self.poison_params['positions']
        for position in positions:
            poison = Edible(position=position, **self.poison_params)
            self.poisons.append(poison)

        # Once the poisons have been created, we switch to random position for the new poisons
        self.poison_params['position'] = 'random'

        # Create the fruits
        self.fruit_params = kwargs['fruits'].copy()
        self.fruits = []
        self.fruit_params['environment'] = self
        self.fruit_params['collision_type'] = 2
        if self.fruit_params['positions'] == 'random':
            positions = ['random'] * self.fruit_params['number']
            if kwargs['map']:
                positions = self.mapp_.generate_random_point(
                    self.fruit_params['number'])
        else:
            positions = self.fruit_params['positions']
        for position in positions:
            fruit = Edible(position=position, **self.fruit_params)
            self.fruits.append(fruit)

        # Once the fruits have been created, we switch to random position for the new fruits
        self.fruit_params['position'] = 'random'

        # Add the agent
        self.agent_param = kwargs['agent'].copy()
        if kwargs['map']:
            self.agent_param['position'] = self.mapp_.generate_random_point(
            )[-1]
        #print(self.agent_param['position'])
        self.agent = Agent(environment=self, **self.agent_param)

        # Set a surface to compute Sensors
        # TODO: change when multiple body parts
        self.sizeAroundAgent = max([x.fovRange for x in self.agent.sensors
                                    ]) + self.agent.radius

        self.agent.update_state()