예제 #1
0
파일: organism.py 프로젝트: hayoc/peepo
    def __init__(self, name, network, graphical, pos=(0, 0), obstacles=None):
        super().__init__(network)

        self.graphical = graphical
        self.name = name
        self.rect = pg.Rect(pos, SurvivalPeepo.SIZE)
        self.rect.center = pos
        self.rotation = 0
        self.edge_right = end_line(SurvivalPeepo.RADIUS, self.rotation + 30, self.rect.center)
        self.edge_left = end_line(SurvivalPeepo.RADIUS, self.rotation - 30, self.rect.center)
        self.edge_middle = end_line(SurvivalPeepo.RADIUS, self.rotation, self.rect.center)

        if self.graphical:
            self.image = self.make_image()
            self.image_original = self.image.copy()

        self.health = 0

        self.obstacles = obstacles or []
        self.motor = {
            LEFT: False,
            RIGHT: False
        }
        self.view = {
            '1': False,
            '2': False,
            '3': False,
            '4': False,
            '5': False,
            '6': False,
        }
        self.generative_model = GenerativeModel(self, n_jobs=1)
예제 #2
0
파일: sandbox.py 프로젝트: hayoc/peepo
 def __init__(self, network, action_space, observation_space):
     super().__init__(network)
     self.action_space = action_space
     self.observation_space = observation_space
     self.obs = np.empty(4)
     self.reward = 0
     self.done = False
     self.act = 0
     self.generative_model = GenerativeModel(self, n_jobs=4)
예제 #3
0
    def __init__(self, name, network, pos=(0, 0)):
        super().__init__(network)

        self.name = name
        self.rect = pg.Rect(pos, Portia.SIZE)
        self.rect.center = pos
        self.rotation = 0

        self.image = self.make_image()
        self.image_original = self.image.copy()

        self.generative_model = GenerativeModel(self, n_jobs=1)
예제 #4
0
파일: sandbox.py 프로젝트: hayoc/peepo
class PeepoAgent(Peepo):
    def __init__(self, network, action_space, observation_space):
        super().__init__(network)
        self.action_space = action_space
        self.observation_space = observation_space
        self.obs = np.empty(4)
        self.reward = 0
        self.done = False
        self.act = 0
        self.generative_model = GenerativeModel(self, n_jobs=4)

    def update(self, obz, rewardz, donez):
        self.obs = obz
        self.reward = rewardz
        self.done = donez

        self.generative_model.process()

        return self.act

    def observation(self, name):
        if VISION.lower() in name.lower():
            quad = self.get_quadrant(name)
            return self.normalized_distribution(
                self.obs[quad], self.observation_space.low[quad],
                self.observation_space.high[quad])
        if MOTOR.lower() in name.lower():
            return [0.1, 0.9] if self.act else [0.9, 0.1]

        logging.warning(
            'Reached code which should not be reached in observation')
        return [0.5, 0.5]

    def action(self, node, prediction):
        self.act = np.argmax(prediction)

    @staticmethod
    def normalized_distribution(value, mini, maxi, target_min=0, target_max=1):
        if str(maxi) == '3.4028235e+38':
            mini, maxi = -1, 1
        x = target_max * ((value - mini) / (maxi - mini)) + target_min
        return np.array([x, 1 - x])

    @staticmethod
    def get_quadrant(name):
        for quad in ['0', '1', '2', '3']:
            if quad.lower() in name.lower():
                return int(quad)
        raise ValueError('Unexpected node name %s, could not find 0,1,2,3',
                         name)
예제 #5
0
파일: organism.py 프로젝트: hayoc/peepo
    def __init__(self, name, network, graphical, pos=(0, 0)):
        super().__init__(network)

        self.graphical = graphical
        self.name = name
        self.rect = pg.Rect(pos, AntPeepo.SIZE)
        self.rect.center = pos
        self.rotation = 0

        if self.graphical:
            self.image = self.make_image()
            self.image_original = self.image.copy()

        self.motor = {LEFT: False, RIGHT: False}
        self.generative_model = GenerativeModel(self, n_jobs=1)

        self.path = []
예제 #6
0
class Portia(Peepo):
    SIZE = (4, 4)
    RADIUS = 50
    SPEED = 2

    def __init__(self, name, network, pos=(0, 0)):
        super().__init__(network)

        self.name = name
        self.rect = pg.Rect(pos, Portia.SIZE)
        self.rect.center = pos
        self.rotation = 0

        self.image = self.make_image()
        self.image_original = self.image.copy()

        self.generative_model = GenerativeModel(self, n_jobs=1)

    def observation(self, name):
        return [0.0, 0.0]

    def action(self, node, prediction):
        pass

    def update(self):
        self.generative_model.process()

        self.rect.x += Portia.SPEED * math.cos(math.radians(self.rotation))
        self.rect.y += Portia.SPEED * math.sin(math.radians(self.rotation))

        self.image = pg.transform.rotate(self.image_original, -self.rotation)
        self.rect = self.image.get_rect(center=self.rect.center)

        if self.rect.x < 0 or self.rect.y < 0 or self.rect.x > 800 or self.rect.y > 800:
            self.rect.x, self.rect.y = 400, 400

    def draw(self, surface):
        surface.blit(self.image, self.rect)

    def make_image(self):
        image = pg.Surface(self.rect.size).convert_alpha()
        image.fill((0, 0, 0, 0))
        image_rect = image.get_rect()
        pg.draw.rect(image, pg.Color("black"), image_rect)
        pg.draw.rect(image, pg.Color("green"), image_rect.inflate(-2, -2))
        return image
예제 #7
0
파일: organism2.py 프로젝트: hayoc/peepo
    def __init__(self,
                 name,
                 network,
                 graphical,
                 pos=(0, 0),
                 ennemies=None,
                 food=None):
        self.graphical = graphical
        self.name = name
        self.network = network
        self.rect = pg.Rect(pos, Peepo.SIZE)
        self.rect.center = pos
        self.rotation = 0
        self.edge_right = end_line(Peepo.RADIUS, self.rotation + 30,
                                   self.rect.center)
        self.edge_left = end_line(Peepo.RADIUS, self.rotation - 30,
                                  self.rect.center)
        self.edge_middle = end_line(Peepo.RADIUS, self.rotation,
                                    self.rect.center)

        if self.graphical:
            self.image = self.make_image()
            self.image_original = self.image.copy()

        self.stomach = 0
        self.bang = 0

        self.ennemies = ennemies or []
        self.food = food or []
        self.obstacles = []
        self.assemble_obstacles()
        self.motor = {LEFT: False, RIGHT: False}
        self.view = {
            '1': False,
            '2': False,
            '3': False,
            '4': False,
        }
        self.is_an_enemy = False
        self.is_food = False
        self.generative_model = GenerativeModel(network,
                                                SensoryInputPeepo(self),
                                                n_jobs=1)
    def __init__(self, peepo_actor, actors):
        super().__init__(self.create_model())

        self.peepo_actor = peepo_actor
        self.actors = actors

        self.motor_output = {pg.K_LEFT: False,
                             pg.K_RIGHT: False}
        self.obstacle_input = {'1': False,
                               '2': False,
                               '3': False,
                               '4': False,
                               '5': False,
                               '6': False}
        self.wander_left_chance = 0
        self.wander_right_chance = 0
        self.wandering_left = False
        self.wandering_right = False

        self.genmodel = GenerativeModel(self)
예제 #9
0
def create_network():
    network = BayesianModel([('A', 'B')])

    cpd_a = TabularCPD(variable='A', variable_card=2, values=[[0.2, 0.8]])
    cpd_b = TabularCPD(variable='B',
                       variable_card=2,
                       values=[[0.1, 0.7], [0.9, 0.3]],
                       evidence=['A'],
                       evidence_card=[2])
    network.add_cpds(cpd_a, cpd_b)
    network.check_model()

    return GenerativeModel(TestSensoryInput(), network)
예제 #10
0
 def test_topology(self):
     self.networx_test = self.networx.copy()
     self.pgmpy_test   = self.pgmpy.copy()
     model = {'main': GenerativeModel(SensoryInputVirtualPeepo(self), self.pgmpy_test)}
     expected_result = [0,0,0]
     ''' ------ going through all possible "colors'''
     for color in range(0, self.number_of_colors):
         states = self.colors_table[:,color]
         shape = self.colors_cpd.values.shape
         reshaped_cpd = self.colors_cpd.values.reshape(shape[0], int(np.prod(shape) / shape[0]))
         expected_result = reshaped_cpd[:,int(color)]
         for i, pixel in enumerate(states):
             cardinality = self.pgmpy_test.get_cardinality('BENS_'+str(i))
             self.pgmpy_test.get_cpds('BENS_' + str(i)).values = CPD.create_fixed_parent(cardinality, state = int(pixel))
         self.do_inference(model ,expected_result)
예제 #11
0
def create_network_for_add_edge():
    """ Note: adding an edge where the values are duplicated from the existing connecting nodes won't change
        predictions at all. Since it will just take on the value of the pre-existing state, given that we duplicate
        the values... Maybe go back to 0.5 0.5 defaults?
    """
    network = BayesianModel([('A', 'B'), ('C', 'D')])

    cpd_a = TabularCPD(variable='A', variable_card=2, values=[[0.4, 0.6]])
    cpd_b = TabularCPD(variable='B',
                       variable_card=2,
                       values=[[0.1, 0.9], [0.9, 0.1]],
                       evidence=['A'],
                       evidence_card=[2])
    cpd_c = TabularCPD(variable='C', variable_card=2, values=[[0.6, 0.4]])
    cpd_d = TabularCPD(variable='D',
                       variable_card=2,
                       values=[[0.8, 0.9], [0.2, 0.1]],
                       evidence=['C'],
                       evidence_card=[2])
    network.add_cpds(cpd_a, cpd_b, cpd_c, cpd_d)
    network.check_model()

    return GenerativeModel(TestSensoryInput(), network)
예제 #12
0
파일: organism.py 프로젝트: hayoc/peepo
class GoLPeepo(Peepo):
    """
    This organism represents peepo. Each peepo takes as parameters a name, an initial position and the list of
    obstacles present in its environment.
    """

    SIZE = (4, 4)
    RADIUS = 50
    SPEED = 2

    def __init__(self,
                 name,
                 network,
                 graphical,
                 pos=(0, 0),
                 ennemies=None,
                 food=None):
        super().__init__(network)

        self.graphical = graphical
        self.name = name
        self.rect = pg.Rect(pos, GoLPeepo.SIZE)
        self.rect.center = pos
        self.rotation = 0
        self.edge_right = end_line(GoLPeepo.RADIUS, self.rotation + 30,
                                   self.rect.center)
        self.edge_left = end_line(GoLPeepo.RADIUS, self.rotation - 30,
                                  self.rect.center)

        if self.graphical:
            self.image = self.make_image()
            self.image_original = self.image.copy()

        self.stomach = 0
        self.bang = 0

        self.ennemies = ennemies or []
        self.food = food or []
        self.obstacles = []
        self.assemble_obstacles()
        self.motor = {LEFT: False, RIGHT: False}
        self.view = {
            '1': False,
            '2': False,
            '3': False,
            '4': False,
            '5': False,
            '6': False,
        }
        self.is_an_enemy = False
        self.is_food = False
        self.generative_model = GenerativeModel(self, n_jobs=1)

    def assemble_obstacles(self):
        for i, x in enumerate(self.food):
            self.obstacles.append([x, 0, i])
        for i, x in enumerate(self.ennemies):
            self.obstacles.append([x, 1, i])

    def observation(self, name):
        if VISION.lower() in name.lower():
            return [0.1, 0.9
                    ] if self.view[self.get_quadrant(name)] else [0.9, 0.1]
        if MOTOR.lower() in name.lower():
            return [0.1, 0.9
                    ] if self.motor[self.get_direction(name)] else [0.9, 0.1]
        if ID_ENNEMY.lower() in name.lower():
            return [0.1, 0.9] if self.is_an_enemy else [0.9, 0.1]
        if ID_FOOD.lower() in name.lower():
            return [0.1, 0.9] if self.is_food else [0.9, 0.1]

    def action(self, node, prediction):
        if np.argmax(prediction) == 0:
            self.motor[self.get_direction(node)] = False
        else:
            self.motor[self.get_direction(node)] = True

    @staticmethod
    def get_quadrant(name):
        for quad in ['1', '2', '3', '4', '5', '6']:
            if quad.lower() in name.lower():
                return quad
        raise ValueError('Unexpected node name %s, could not find 1,2,3,4,5,6',
                         name)

    @staticmethod
    def get_direction(name):
        for direction in [LEFT, RIGHT]:
            if direction.lower() in name.lower():
                return direction
        raise ValueError('Unexpected node name %s, could not find LEFT, RIGHT',
                         name)

    def update(self):
        self.generative_model.process()

        self.rect.x += GoLPeepo.SPEED * math.cos(math.radians(self.rotation))
        self.rect.y += GoLPeepo.SPEED * math.sin(math.radians(self.rotation))

        if self.motor[LEFT]:
            self.rotation -= 10
            if self.rotation < 0:
                self.rotation = 360
        if self.motor[RIGHT]:
            self.rotation += 10
            if self.rotation > 360:
                self.rotation = 0

        self.calculate_obstacles()

        if self.graphical:
            self.image = pg.transform.rotate(self.image_original,
                                             -self.rotation)
            self.rect = self.image.get_rect(center=self.rect.center)

        self.edge_right = end_line(GoLPeepo.RADIUS, self.rotation + 30,
                                   self.rect.center)
        self.edge_left = end_line(GoLPeepo.RADIUS, self.rotation - 30,
                                  self.rect.center)

        if self.rect.x < 0 or self.rect.y < 0 or self.rect.x > 800 or self.rect.y > 800:
            self.rect.x, self.rect.y = 400, 400

    def draw(self, surface):
        surface.blit(self.image, self.rect)
        pg.draw.line(surface, pg.Color("red"), self.rect.center,
                     self.edge_right, 2)
        pg.draw.line(surface, pg.Color("green"), self.rect.center,
                     self.edge_left, 2)

    def make_image(self):
        image = pg.Surface(self.rect.size).convert_alpha()
        image.fill(TRANSPARENT)
        image_rect = image.get_rect()
        pg.draw.rect(image, pg.Color("black"), image_rect)
        pg.draw.rect(image, pg.Color("green"), image_rect.inflate(-2, -2))
        return image

    def calculate_obstacles(self):
        self.view = {x: False for x in self.view}
        self.is_an_enemy = False
        self.is_food = False
        observations = self.obstacles
        for obstacle in observations:
            if self.rect.colliderect(obstacle[0].rect):
                if obstacle[1] == 0:
                    self.stomach += 1
                    self.obstacles.remove(obstacle)
                else:
                    self.bang += 1
                    # self.obstacles.remove(obstacle)

            peepo_vec = pg.math.Vector2(self.rect.center)
            if collision(obstacle[0].rect, peepo_vec, self.edge_left,
                         self.edge_right, GoLPeepo.RADIUS):
                edge1 = end_line(GoLPeepo.RADIUS, self.rotation - 30,
                                 self.rect.center)
                edge2 = end_line(GoLPeepo.RADIUS, self.rotation - 20,
                                 self.rect.center)
                edge3 = end_line(GoLPeepo.RADIUS, self.rotation - 10,
                                 self.rect.center)
                edge4 = end_line(GoLPeepo.RADIUS, self.rotation,
                                 self.rect.center)
                edge5 = end_line(GoLPeepo.RADIUS, self.rotation + 10,
                                 self.rect.center)
                edge6 = end_line(GoLPeepo.RADIUS, self.rotation + 20,
                                 self.rect.center)
                edge7 = end_line(GoLPeepo.RADIUS, self.rotation + 30,
                                 self.rect.center)

                self.view['1'] = collision(obstacle[0].rect, peepo_vec, edge1,
                                           edge2, GoLPeepo.RADIUS)
                self.view['2'] = collision(obstacle[0].rect, peepo_vec, edge2,
                                           edge3, GoLPeepo.RADIUS)
                self.view['3'] = collision(obstacle[0].rect, peepo_vec, edge3,
                                           edge4, GoLPeepo.RADIUS)
                self.view['4'] = collision(obstacle[0].rect, peepo_vec, edge4,
                                           edge5, GoLPeepo.RADIUS)
                self.view['5'] = collision(obstacle[0].rect, peepo_vec, edge5,
                                           edge6, GoLPeepo.RADIUS)
                self.view['6'] = collision(obstacle[0].rect, peepo_vec, edge6,
                                           edge7, GoLPeepo.RADIUS)
                if obstacle[1] == 1:
                    self.is_an_enemy = True
                if obstacle[1] == 0:
                    self.is_food = True
        self.food = []
        [self.food.append(x[0]) for x in self.obstacles if x[1] == 0]
예제 #13
0
파일: organism.py 프로젝트: hayoc/peepo
class SurvivalPeepo(Peepo):
    """
    This organism represents peepo. Each peepo takes as parameters a name, an initial position and the list of
    obstacles present in its environment.
    """

    SIZE = (4, 4)
    RADIUS = 50
    SPEED = 2

    def __init__(self, name, network, graphical, pos=(0, 0), obstacles=None):
        super().__init__(network)

        self.graphical = graphical
        self.name = name
        self.rect = pg.Rect(pos, SurvivalPeepo.SIZE)
        self.rect.center = pos
        self.rotation = 0
        self.edge_right = end_line(SurvivalPeepo.RADIUS, self.rotation + 30, self.rect.center)
        self.edge_left = end_line(SurvivalPeepo.RADIUS, self.rotation - 30, self.rect.center)
        self.edge_middle = end_line(SurvivalPeepo.RADIUS, self.rotation, self.rect.center)

        if self.graphical:
            self.image = self.make_image()
            self.image_original = self.image.copy()

        self.health = 0

        self.obstacles = obstacles or []
        self.motor = {
            LEFT: False,
            RIGHT: False
        }
        self.view = {
            '1': False,
            '2': False,
            '3': False,
            '4': False,
            '5': False,
            '6': False,
        }
        self.generative_model = GenerativeModel(self, n_jobs=1)

    def observation(self, name):
        if VISION.lower() in name.lower():
            return [0.1, 0.9] if self.view[self.get_quadrant(name)] else [0.9, 0.1]
        if MOTOR.lower() in name.lower():
            return [0.1, 0.9] if self.motor[self.get_direction(name)] else [0.9, 0.1]
        return [0.5, 0.5]

    def action(self, node, prediction):
        if np.argmax(prediction) == 0:
            self.motor[self.get_direction(node)] = False
        else:
            self.motor[self.get_direction(node)] = True

    @staticmethod
    def get_quadrant(name):
        for quad in ['1', '2', '3', '4', '5', '6']:
            if quad.lower() in name.lower():
                return quad
        raise ValueError('Unexpected node name %s, could not find 1,2,3,4,5,6', name)

    @staticmethod
    def get_direction(name):
        for direction in [LEFT, RIGHT]:
            if direction.lower() in name.lower():
                return direction
        raise ValueError('Unexpected node name %s, could not find LEFT, RIGHT', name)

    def update(self):
        self.generative_model.process()

        self.rect.x += SurvivalPeepo.SPEED * math.cos(math.radians(self.rotation))
        self.rect.y += SurvivalPeepo.SPEED * math.sin(math.radians(self.rotation))

        if self.motor[LEFT]:
            self.rotation -= 10
            if self.rotation < 0:
                self.rotation = 360
        if self.motor[RIGHT]:
            self.rotation += 10
            if self.rotation > 360:
                self.rotation = 0
        self.edge_middle = end_line(SurvivalPeepo.RADIUS, self.rotation, self.rect.center)
        self.calculate_obstacles()

        if self.graphical:
            self.image = pg.transform.rotate(self.image_original, -self.rotation)
            self.rect = self.image.get_rect(center=self.rect.center)

        self.edge_right = end_line(SurvivalPeepo.RADIUS, self.rotation + 30, self.rect.center)
        self.edge_left = end_line(SurvivalPeepo.RADIUS, self.rotation - 30, self.rect.center)

        if self.rect.x < 0 or self.rect.y < 0 or self.rect.x > 800 or self.rect.y > 800:
            self.rect.x, self.rect.y = 400, 400

    def draw(self, surface):
        surface.blit(self.image, self.rect)
        pg.draw.line(surface, pg.Color("red"), self.rect.center, self.edge_right, 2)
        pg.draw.line(surface, pg.Color("green"), self.rect.center, self.edge_left, 2)

    def make_image(self):
        image = pg.Surface(self.rect.size).convert_alpha()
        image.fill(TRANSPARENT)
        image_rect = image.get_rect()
        pg.draw.rect(image, pg.Color("black"), image_rect)
        pg.draw.rect(image, pg.Color("green"), image_rect.inflate(-2, -2))
        return image

    def calculate_obstacles(self):
        self.view = {x: False for x in self.view}

        peepo_vec = pg.math.Vector2(self.rect.center)
        min_distance = 1000
        closest_obstacle = None

        for obstacle in self.obstacles:
            if self.rect.colliderect(obstacle.rect):
                self.health += 1
                self.obstacles.remove(obstacle)

            if collision(obstacle.rect, peepo_vec, self.edge_left, self.edge_right, SurvivalPeepo.RADIUS):
                distance = math.hypot(obstacle.rect.x - self.rect.x, obstacle.rect.y - self.rect.y)
                if distance <= min_distance:
                    closest_obstacle = obstacle
                    min_distance = distance

        if closest_obstacle:
            edge1 = end_line(SurvivalPeepo.RADIUS, self.rotation - 30, self.rect.center)
            edge2 = end_line(SurvivalPeepo.RADIUS, self.rotation - 20, self.rect.center)
            edge3 = end_line(SurvivalPeepo.RADIUS, self.rotation - 10, self.rect.center)
            edge4 = end_line(SurvivalPeepo.RADIUS, self.rotation, self.rect.center)
            edge5 = end_line(SurvivalPeepo.RADIUS, self.rotation + 10, self.rect.center)
            edge6 = end_line(SurvivalPeepo.RADIUS, self.rotation + 20, self.rect.center)
            edge7 = end_line(SurvivalPeepo.RADIUS, self.rotation + 30, self.rect.center)

            self.view['1'] = collision(closest_obstacle.rect, peepo_vec, edge1, edge2, SurvivalPeepo.RADIUS)
            self.view['2'] = collision(closest_obstacle.rect, peepo_vec, edge2, edge3, SurvivalPeepo.RADIUS)
            self.view['3'] = collision(closest_obstacle.rect, peepo_vec, edge3, edge4, SurvivalPeepo.RADIUS)
            self.view['4'] = collision(closest_obstacle.rect, peepo_vec, edge4, edge5, SurvivalPeepo.RADIUS)
            self.view['5'] = collision(closest_obstacle.rect, peepo_vec, edge5, edge6, SurvivalPeepo.RADIUS)
            self.view['6'] = collision(closest_obstacle.rect, peepo_vec, edge6, edge7, SurvivalPeepo.RADIUS)
예제 #14
0
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)


class Baby:

    def __init__(self):
        self.limbs = {
            md.LEFT_ARM: False,
            md.RIGHT_ARM: False,
            md.LEFT_FOOT: False,
            md.RIGHT_FOOT: False
        }


model = GenerativeModel(md.baby_model(), SensoryInputCribBaby(Baby(), Crib()))

while True:
    model.process()

# def run():
#     model = GenerativeModel(SensoryInputCribBaby(Baby(), Crib()), md.fully_connected_model())
#     # model.process()
#     original_model = model.network.copy()
#     edges = original_model.edges()
#
#     result = {}
#
#     for x in range(0, len(edges) + 1):
#         subresult = []
#         for cmb in itertools.combinations(edges, x):
예제 #15
0
파일: Raptor_model.py 프로젝트: hayoc/peepo
    def create_networks(self):
        gamma = 1  # this controls how steep the discrimination will be between the classes (gamma << 1 low discrimination, gamma >> 1 : high discrimination
        sigma = 1  # this controls how steep the squeezing of the action will be
        index_jump = int(
            self.raptor_actor.alfa_increment / self.resolution
        )  #calculates the number of "sector  jumps"  dpeending on the tuple alfa_ainvrement and sector_resolution
        index_jump = 2
        #         print("Index gamma ", index_gamma)
        ParentNodes = []
        ParentNodes.append("MEM_vision_left")
        ParentNodes.append("MEM_vision_right")
        ParentNodes.append("BEN_Correction")
        ParentNodes.append("BEN_Direction")

        #ParentNodes.append("Reward_Predicted")
        count = 0
        while count < len(ParentNodes):
            self.network.add_node(ParentNodes[count])
            count = count + 1

        LeafNodes = []
        LeafNodes.append("LEN_vision_left")
        LeafNodes.append("LEN_vision_right")
        LeafNodes.append("LEN_motor_Correction")
        LeafNodes.append("LEN_motor_Direction")

        count = 0
        while count < len(LeafNodes):
            self.network.add_node(LeafNodes[count])
            count = count + 1
        self.network.add_edge(ParentNodes[0], LeafNodes[0])
        self.network.add_edge(ParentNodes[2], LeafNodes[0])
        self.network.add_edge(ParentNodes[3], LeafNodes[0])
        self.network.add_edge(ParentNodes[1], LeafNodes[1])
        self.network.add_edge(ParentNodes[2], LeafNodes[1])
        self.network.add_edge(ParentNodes[3], LeafNodes[1])
        self.network.add_edge(ParentNodes[2], LeafNodes[2])
        self.network.add_edge(ParentNodes[3], LeafNodes[3])

        CPD_Parents = []
        CPD_Parents.append(
            CPD.parent_cpd(
                ParentNodes[0], self.cardinality_vision,
                int(random.uniform(0, self.cardinality_vision - 0.4)),
                sigma / 2, "fixed"))
        CPD_Parents.append(
            CPD.parent_cpd(
                ParentNodes[1], self.cardinality_vision,
                int(random.uniform(0, self.cardinality_vision - 0.4)),
                sigma / 2, "fixed"))
        CPD_Parents.append(
            CPD.parent_cpd(
                ParentNodes[2], self.cardinality_correction,
                int(random.uniform(0, self.cardinality_correction - 0.4)),
                sigma / 2, "fixed"))
        CPD_Parents.append(
            CPD.parent_cpd(
                ParentNodes[3], self.cardinality_direction,
                int(random.uniform(0, self.cardinality_direction - 0.4)),
                sigma / 2, "fixed"))

        for n in range(0, len(CPD_Parents)):
            self.network.add_cpds(CPD_Parents[n])

        CPD_Leafs = []
        CPD_Leafs.append(
            CPD.leaf_cpd(LeafNodes[0], self.cardinality_vision, [
                self.cardinality_vision, self.cardinality_correction,
                self.cardinality_direction
            ], [ParentNodes[0], ParentNodes[2], ParentNodes[3]], 'left_vision',
                         index_jump))
        CPD_Leafs.append(
            CPD.leaf_cpd(LeafNodes[1], self.cardinality_vision, [
                self.cardinality_vision, self.cardinality_correction,
                self.cardinality_direction
            ], [ParentNodes[1], ParentNodes[2], ParentNodes[3]],
                         'right_vision', index_jump))
        CPD_Leafs.append(
            CPD.leaf_cpd(LeafNodes[2], self.cardinality_correction,
                         [self.cardinality_correction], [ParentNodes[2]],
                         'one_2_one', index_jump))
        CPD_Leafs.append(
            CPD.leaf_cpd(LeafNodes[3], self.cardinality_direction,
                         [self.cardinality_direction], [ParentNodes[3]],
                         'one_2_one', index_jump))
        for n in range(0, len(CPD_Leafs)):
            self.network.add_cpds(CPD_Leafs[n])
        self.network.check_model()
        #draw_network(self.network)
        '''for n in range(0,len(CPD_Latents)):
            print("Latents :")
            print(CPD_Latents[n])'''
        for n in range(0, len(CPD_Leafs)):
            print("Leafs :")
            print(CPD_Leafs[n])
        #wait = input("PRESS ENTER TO CONTINUE.")
        relevant_parent_nodes = [2, 3]

        return {
            'main': GenerativeModel(SensoryInputVirtualPeepo(self),
                                    self.network)
        }
예제 #16
0
파일: organism.py 프로젝트: hayoc/peepo
class AntPeepo(Peepo):
    """
    This organism represents peepo.
    """

    SIZE = (4, 4)
    RADIUS = 50
    SPEED = 2

    def __init__(self, name, network, graphical, pos=(0, 0)):
        super().__init__(network)

        self.graphical = graphical
        self.name = name
        self.rect = pg.Rect(pos, AntPeepo.SIZE)
        self.rect.center = pos
        self.rotation = 0

        if self.graphical:
            self.image = self.make_image()
            self.image_original = self.image.copy()

        self.motor = {LEFT: False, RIGHT: False}
        self.generative_model = GenerativeModel(self, n_jobs=1)

        self.path = []

    def observation(self, name):
        if MOTOR.lower() in name.lower():
            return [0.1, 0.9
                    ] if self.motor[self.get_direction(name)] else [0.9, 0.1]
        return [0.5, 0.5]

    def action(self, node, prediction):
        if np.argmax(prediction) == 0:
            self.motor[self.get_direction(node)] = False
        else:
            self.motor[self.get_direction(node)] = True

    @staticmethod
    def get_direction(name):
        for direction in [LEFT, RIGHT]:
            if direction.lower() in name.lower():
                return direction
        raise ValueError('Unexpected node name %s, could not find LEFT, RIGHT',
                         name)

    def update(self):
        self.generative_model.process()
        self.drift_hypotheses()

        self.rect.x += AntPeepo.SPEED * math.cos(math.radians(self.rotation))
        self.rect.y += AntPeepo.SPEED * math.sin(math.radians(self.rotation))

        if self.motor[LEFT]:
            self.rotation -= 10
            if self.rotation < 0:
                self.rotation = 360
        if self.motor[RIGHT]:
            self.rotation += 10
            if self.rotation > 360:
                self.rotation = 0

        if self.graphical:
            self.image = pg.transform.rotate(self.image_original,
                                             -self.rotation)
            self.rect = self.image.get_rect(center=self.rect.center)

        if self.rect.x < 0:
            self.rect.x = 799
        if self.rect.x > 800:
            self.rect.x = 1
        if self.rect.y < 0:
            self.rect.y = 799
        if self.rect.y > 800:
            self.rect.y = 1

        self.path.append((self.rect.x, self.rect.y))

    def drift_hypotheses(self):
        for root in self.generative_model.get_roots():
            root_index = self.generative_model.get_node_index(root.name)

            if random.choice([0, 1]):
                old_hypo = self.generative_model.bayesian_network.states[
                    root_index].distribution.items()

                moving = [old_hypo[0][1], old_hypo[1][1]]
                if np.argmax(moving):  # ~ [0.1, 0.9] -> [0.9, 0.1]
                    change = 0.05
                    if moving[1] - change < 0.1:
                        moving = [0.9, 0.1]
                    else:
                        moving = [moving[0] + change, moving[1] - change]
                else:  # ~ [0.9, 0.1] -> [0.1, 0.9]
                    change = 0.1
                    if moving[0] - change < 0.1:
                        moving = [0.1, 0.9]
                    else:
                        moving = [moving[0] - change, moving[1] + change]

                new_hypo = {0: moving[0], 1: moving[1]}

                self.generative_model.bayesian_network.states[
                    root_index].distribution = DiscreteDistribution(new_hypo)

    def draw(self, surface):
        surface.blit(self.image, self.rect)
        for step in self.path:
            surface.set_at(step, pg.Color("red"))

    def make_image(self):
        image = pg.Surface(self.rect.size).convert_alpha()
        image.fill(TRANSPARENT)
        image_rect = image.get_rect()
        pg.draw.rect(image, pg.Color("black"), image_rect)
        pg.draw.rect(image, pg.Color("green"), image_rect.inflate(-2, -2))
        return image
class WanderingPeepo(Peepo):
    RADIUS = 100

    WAN_LEFT = 'RON_wandering_left'
    WAN_RIGHT = 'RON_wandering_right'
    OBS_LEFT = 'RON_obstacle_left'
    OBS_RIGHT = 'RON_obstacle_right'
    MOT_LEFT = 'LEN_motor_left'
    MOT_RIGHT = 'LEN_motor_right'
    VIS_1 = 'LEN_vision_1'
    VIS_2 = 'LEN_vision_2'
    VIS_3 = 'LEN_vision_3'
    VIS_4 = 'LEN_vision_4'
    VIS_5 = 'LEN_vision_5'
    VIS_6 = 'LEN_vision_6'

    def __init__(self, peepo_actor, actors):
        super().__init__(self.create_model())

        self.peepo_actor = peepo_actor
        self.actors = actors

        self.motor_output = {pg.K_LEFT: False,
                             pg.K_RIGHT: False}
        self.obstacle_input = {'1': False,
                               '2': False,
                               '3': False,
                               '4': False,
                               '5': False,
                               '6': False}
        self.wander_left_chance = 0
        self.wander_right_chance = 0
        self.wandering_left = False
        self.wandering_right = False

        self.genmodel = GenerativeModel(self)

    def action(self, node, prediction):
        # prediction [0.9, 0.1] = STOP
        # prediction [0.1, 0.9] = START
        if np.argmax(prediction) == 0:
            if 'left' in node:
                self.motor_output[pg.K_LEFT] = False
            if 'right' in node:
                self.motor_output[pg.K_RIGHT] = False
        else:
            if 'left' in node:
                self.motor_output[pg.K_LEFT] = True
            if 'right' in node:
                self.motor_output[pg.K_RIGHT] = True

    def observation(self, name):
        if 'vision' in name:
            # prediction [0.9, 0.1] = NO OBSTACLE
            # prediction [0.1, 0.9] = OBSTACLE
            if '1' in name:
                return np.array([0.1, 0.9]) if self.obstacle_input['1'] else np.array([0.9, 0.1])
            if '2' in name:
                return np.array([0.1, 0.9]) if self.obstacle_input['2'] else np.array([0.9, 0.1])
            if '3' in name:
                return np.array([0.1, 0.9]) if self.obstacle_input['3'] else np.array([0.9, 0.1])
            if '4' in name:
                return np.array([0.1, 0.9]) if self.obstacle_input['4'] else np.array([0.9, 0.1])
            if '5' in name:
                return np.array([0.1, 0.9]) if self.obstacle_input['5'] else np.array([0.9, 0.1])
            if '6' in name:
                return np.array([0.1, 0.9]) if self.obstacle_input['6'] else np.array([0.9, 0.1])
        elif 'motor' in name:
            # prediction [0.9, 0.1] = STOPPED
            # prediction [0.1, 0.9] = MOVING
            if 'left' in name:
                return np.array([0.1, 0.9]) if self.motor_output[pg.K_LEFT] else np.array([0.9, 0.1])
            if 'right' in name:
                return np.array([0.1, 0.9]) if self.motor_output[pg.K_RIGHT] else np.array([0.9, 0.1])

    def update(self):
        network = self.genmodel.bayesian_network

        # [0.9, 0.1] = OFF
        # [0.1, 0.9] = ON
        if self.wandering_left:
            state = network.states[self.genmodel.get_node_index(self.WAN_LEFT)]
            state.distribution = DiscreteDistribution(change_distribution(state.distribution.items(), [0.9, 0.1]))
            self.wander_left_chance = 0
            self.wandering_left = False
        else:
            self.wander_left_chance += 0.1
            if random.randint(0, 100) <= self.wander_left_chance:
                state = network.states[self.genmodel.get_node_index(self.WAN_LEFT)]
                state.distribution = DiscreteDistribution(change_distribution(state.distribution.items(), [0.1, 0.9]))
                self.wandering_left = True

        if self.wandering_right:
            state = network.states[self.genmodel.get_node_index(self.WAN_RIGHT)]
            state.distribution = DiscreteDistribution(change_distribution(state.distribution.items(), [0.9, 0.1]))
            self.wander_right_chance = 0
            self.wandering_right = False
        else:
            self.wander_right_chance += 0.1
            if random.randint(0, 100) <= self.wander_right_chance:
                state = network.states[self.genmodel.get_node_index(self.WAN_RIGHT)]
                state.distribution = DiscreteDistribution(change_distribution(state.distribution.items(), [0.1, 0.9]))
                self.wandering_right = True

    def create_model(self):
        pp_network = PeepoNetwork(
            ron_nodes=[
                {'name': self.WAN_LEFT, 'card': 2},
                {'name': self.WAN_RIGHT, 'card': 2},
                {'name': self.OBS_LEFT, 'card': 2},
                {'name': self.OBS_RIGHT, 'card': 2}
            ],
            ext_nodes=[
                {'name': self.VIS_1, 'card': 2},
                {'name': self.VIS_2, 'card': 2},
                {'name': self.VIS_3, 'card': 2},
                {'name': self.VIS_4, 'card': 2},
                {'name': self.VIS_5, 'card': 2},
                {'name': self.VIS_6, 'card': 2}
            ],
            pro_nodes=[
                {'name': self.MOT_LEFT, 'card': 2},
                {'name': self.MOT_RIGHT, 'card': 2}
            ],
            edges=[
                (self.WAN_LEFT, self.MOT_LEFT),
                (self.WAN_RIGHT, self.MOT_RIGHT),
                (self.OBS_LEFT, self.MOT_RIGHT),
                (self.OBS_RIGHT, self.MOT_LEFT),
                (self.OBS_LEFT, self.VIS_1),
                (self.OBS_LEFT, self.VIS_2),
                (self.OBS_LEFT, self.VIS_3),
                (self.OBS_RIGHT, self.VIS_4),
                (self.OBS_RIGHT, self.VIS_5),
                (self.OBS_RIGHT, self.VIS_6),
            ],
            cpds={
                self.WAN_LEFT: [0.9, 0.1],
                self.WAN_RIGHT: [0.9, 0.1],
                self.OBS_LEFT: [0.9, 0.1],
                self.OBS_RIGHT: [0.9, 0.1],
                self.VIS_1: [[0.9, 0.1],
                             [0.1, 0.9]],
                self.VIS_2: [[0.9, 0.1],
                             [0.1, 0.9]],
                self.VIS_3: [[0.9, 0.1],
                             [0.1, 0.9]],
                self.VIS_4: [[0.9, 0.1],
                             [0.1, 0.9]],
                self.VIS_5: [[0.9, 0.1],
                             [0.1, 0.9]],
                self.VIS_6: [[0.9, 0.1],
                             [0.1, 0.9]],
                self.MOT_LEFT: [[0.9, 0.1, 0.1, 0.1],
                                [0.1, 0.9, 0.9, 0.9]],
                self.MOT_RIGHT: [[0.9, 0.1, 0.1, 0.1],
                                 [0.1, 0.9, 0.9, 0.9]],
            })
        pp_network.assemble()

        return pp_network

    def process(self):
        self.calculate_obstacles()
        self.genmodel.process()

    def calculate_obstacles(self):
        for key in self.obstacle_input:
            self.obstacle_input[key] = False

        for actor in self.actors:
            peepo_vec = vec(self.peepo_actor.rect.center)
            collided = collision(actor.rect, peepo_vec, self.peepo_actor.edge_left,
                                 self.peepo_actor.edge_right, WanderingPeepo.RADIUS)
            if collided:
                if 'wall' in actor.id:
                    edge = end_line(WanderingPeepo.RADIUS, self.peepo_actor.rotation, self.peepo_actor.rect.center)
                    if 'left' in actor.id:
                        wall_vec = vec((5, self.peepo_actor.rect.y))
                        deg = math.degrees(
                            math.atan2(wall_vec.y - edge.y, wall_vec.x - edge.x)) + self.peepo_actor.rotation
                        if deg < 0:
                            self.obstacle_input['6'] = True
                        else:
                            self.obstacle_input['1'] = True
                    elif 'right' in actor.id:
                        wall_vec = vec((1598, self.peepo_actor.rect.y))
                        deg = math.degrees(
                            math.atan2(wall_vec.y - edge.y, wall_vec.x - edge.x)) + self.peepo_actor.rotation
                        if deg < 0:
                            self.obstacle_input['1'] = True
                        else:
                            self.obstacle_input['6'] = True
                    elif 'up' in actor.id:
                        wall_vec = vec((5, self.peepo_actor.rect.y))
                        deg = math.degrees(
                            math.atan2(wall_vec.y - edge.y, wall_vec.x - edge.x)) + self.peepo_actor.rotation
                        if deg < 90:
                            self.obstacle_input['6'] = True
                        else:
                            self.obstacle_input['1'] = True
                    else:
                        wall_vec = vec((5, self.peepo_actor.rect.y))
                        deg = math.degrees(
                            math.atan2(wall_vec.y - edge.y, wall_vec.x - edge.x)) + self.peepo_actor.rotation
                        if deg < -90:
                            self.obstacle_input['6'] = True
                        else:
                            self.obstacle_input['1'] = True

                else:
                    edge1 = end_line(WanderingPeepo.RADIUS, self.peepo_actor.rotation - 30,
                                     self.peepo_actor.rect.center)
                    edge2 = end_line(WanderingPeepo.RADIUS, self.peepo_actor.rotation - 20,
                                     self.peepo_actor.rect.center)
                    edge3 = end_line(WanderingPeepo.RADIUS, self.peepo_actor.rotation - 10,
                                     self.peepo_actor.rect.center)
                    edge4 = end_line(WanderingPeepo.RADIUS, self.peepo_actor.rotation, self.peepo_actor.rect.center)
                    edge5 = end_line(WanderingPeepo.RADIUS, self.peepo_actor.rotation + 10,
                                     self.peepo_actor.rect.center)
                    edge6 = end_line(WanderingPeepo.RADIUS, self.peepo_actor.rotation + 20,
                                     self.peepo_actor.rect.center)
                    edge7 = end_line(WanderingPeepo.RADIUS, self.peepo_actor.rotation + 30,
                                     self.peepo_actor.rect.center)

                    self.obstacle_input['1'] = collision(actor.rect, peepo_vec, edge1, edge2, WanderingPeepo.RADIUS)
                    self.obstacle_input['2'] = collision(actor.rect, peepo_vec, edge2, edge3, WanderingPeepo.RADIUS)
                    self.obstacle_input['3'] = collision(actor.rect, peepo_vec, edge3, edge4, WanderingPeepo.RADIUS)
                    self.obstacle_input['4'] = collision(actor.rect, peepo_vec, edge4, edge5, WanderingPeepo.RADIUS)
                    self.obstacle_input['5'] = collision(actor.rect, peepo_vec, edge5, edge6, WanderingPeepo.RADIUS)
                    self.obstacle_input['6'] = collision(actor.rect, peepo_vec, edge6, edge7, WanderingPeepo.RADIUS)
예제 #18
0
파일: cointoss.py 프로젝트: hayoc/peepo
class CointossPeepo(Peepo):

    def __init__(self, coin_set, model_type):
        super().__init__(self.create_model(model_type))
        self.coin_set = coin_set
        self.index = 0
        self.generative_model = GenerativeModel(self, n_jobs=1)

    def update(self):
        return self.generative_model.process()

    def action(self, node, prediction):
        pass

    def observation(self, name):
        val = np.array([1, 0]) if self.coin_set[self.index] == 0 else np.array([0, 1])
        self.index += 1
        return val

    @staticmethod
    def create_model(model_type):
        a = 'A'
        b = 'B'
        c = 'C'
        d = 'D'

        if model_type == "paired":
            pp_network = PeepoNetwork(
                ron_nodes=[
                    {'name': a, 'card': 2},
                ],
                ext_nodes=[
                    {'name': d, 'card': 2},
                ],
                pro_nodes=[
                ],
                edges=[
                    (a, d),
                ],
                cpds={
                    a: [0.5, 0.5],
                    d: [[0.99, 0.01],
                        [0.01, 0.99]]
                })
        elif model_type == "sorted":
            pp_network = PeepoNetwork(
                ron_nodes=[
                    {'name': a, 'card': 2},
                ],
                ext_nodes=[
                    {'name': d, 'card': 2},
                ],
                pro_nodes=[
                ],
                edges=[
                    (a, d),
                ],
                cpds={
                    a: [0.9, 0.1],
                    d: [[0.01, 0.99],
                        [0.99, 0.01]]
                })
        elif model_type == "default":
            pp_network = PeepoNetwork(
                ron_nodes=[
                    {'name': a, 'card': 2},
                ],
                ext_nodes=[
                    {'name': d, 'card': 2},
                ],
                pro_nodes=[
                ],
                edges=[
                    (a, d),
                ],
                cpds={
                    a: [0.5, 0.5],
                    d: [[0.99, 0.01],
                        [0.01, 0.99]]
                })
        else:
            pp_network = PeepoNetwork(
                ron_nodes=[
                    {'name': a, 'card': 2},
                    {'name': b, 'card': 2},
                    {'name': c, 'card': 2}
                ],
                ext_nodes=[
                    {'name': d, 'card': 2},
                ],
                pro_nodes=[
                ],
                edges=[
                    (a, d),
                    (b, d),
                    (c, d),
                ],
                cpds={
                    a: [0.9, 0.1],
                    b: [0.1, 0.9],
                    c: [0.1, 0.9],
                    d: [[0.1, 0.9, 0.1, 0.9, 0.1, 0.9, 0.9, 0.9],
                        [0.9, 0.1, 0.9, 0.1, 0.9, 0.1, 0.1, 0.1]]
                })

        pp_network.assemble()

        return pp_network
예제 #19
0
파일: cointoss.py 프로젝트: hayoc/peepo
 def __init__(self, coin_set, model_type):
     super().__init__(self.create_model(model_type))
     self.coin_set = coin_set
     self.index = 0
     self.generative_model = GenerativeModel(self, n_jobs=1)
예제 #20
0
파일: peepo_v03.py 프로젝트: hayoc/peepo
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)

logging.info('logging initialized')
bot = PeepoBot()
logging.info('bot initialized')

network = BayesianModel([('hypo', 'infrared'), ('hypo', 'motor')])

cpd_a = TabularCPD(variable='hypo', variable_card=2, values=[[0.7, 0.3]])
cpd_b = TabularCPD(variable='infrared',
                   variable_card=2,
                   values=[[0.9, 0.1], [0.1, 0.9]],
                   evidence=['hypo'],
                   evidence_card=[2])
cpd_c = TabularCPD(variable='motor',
                   variable_card=2,
                   values=[[0.9, 0.1], [0.1, 0.9]],
                   evidence=['hypo'],
                   evidence_card=[2])
network.add_cpds(cpd_a, cpd_b, cpd_c)
network.check_model()

model = GenerativeModel(SensoryInput(bot), network)

logging.info('starting predictive processing')

while True:
    model.process()
예제 #21
0
파일: organism2.py 프로젝트: hayoc/peepo
class Peepo:
    """
    This organism represents peepo. Each peepo takes as parameters a name, an initial position and the list of
    obstacles present in its environment.
    """

    SIZE = (4, 4)
    RADIUS = 50
    SPEED = 2

    def __init__(self,
                 name,
                 network,
                 graphical,
                 pos=(0, 0),
                 ennemies=None,
                 food=None):
        self.graphical = graphical
        self.name = name
        self.network = network
        self.rect = pg.Rect(pos, Peepo.SIZE)
        self.rect.center = pos
        self.rotation = 0
        self.edge_right = end_line(Peepo.RADIUS, self.rotation + 30,
                                   self.rect.center)
        self.edge_left = end_line(Peepo.RADIUS, self.rotation - 30,
                                  self.rect.center)
        self.edge_middle = end_line(Peepo.RADIUS, self.rotation,
                                    self.rect.center)

        if self.graphical:
            self.image = self.make_image()
            self.image_original = self.image.copy()

        self.stomach = 0
        self.bang = 0

        self.ennemies = ennemies or []
        self.food = food or []
        self.obstacles = []
        self.assemble_obstacles()
        self.motor = {LEFT: False, RIGHT: False}
        self.view = {
            '1': False,
            '2': False,
            '3': False,
            '4': False,
        }
        self.is_an_enemy = False
        self.is_food = False
        self.generative_model = GenerativeModel(network,
                                                SensoryInputPeepo(self),
                                                n_jobs=1)

    def assemble_obstacles(self):
        self.obstacles = []
        for i, x in enumerate(self.food):
            self.obstacles.append([x, 0, i])
        for i, x in enumerate(self.ennemies):
            self.obstacles.append([x, 1, i])

    def update(self):

        self.generative_model.process()

        self.rect.x += Peepo.SPEED * math.cos(math.radians(self.rotation))
        self.rect.y += Peepo.SPEED * math.sin(math.radians(self.rotation))

        if self.motor[LEFT]:
            self.rotation -= 10
            if self.rotation < 0:
                self.rotation = 360
        if self.motor[RIGHT]:
            self.rotation += 10
            if self.rotation > 360:
                self.rotation = 0
        self.edge_middle = end_line(Peepo.RADIUS, self.rotation,
                                    self.rect.center)
        self.calculate_obstacles()

        if self.graphical:
            self.image = pg.transform.rotate(self.image_original,
                                             -self.rotation)
            self.rect = self.image.get_rect(center=self.rect.center)

        self.edge_right = end_line(Peepo.RADIUS, self.rotation + 30,
                                   self.rect.center)
        self.edge_left = end_line(Peepo.RADIUS, self.rotation - 30,
                                  self.rect.center)

        if self.rect.x < 0 or self.rect.y < 0 or self.rect.x > 800 or self.rect.y > 800:
            self.rect.x, self.rect.y = 400, 400

    def draw(self, surface):
        surface.blit(self.image, self.rect)
        pg.draw.line(surface, pg.Color("red"), self.rect.center,
                     self.edge_right, 2)
        pg.draw.line(surface, pg.Color("green"), self.rect.center,
                     self.edge_left, 2)
        pg.draw.line(surface, pg.Color("blue"), self.rect.center,
                     self.edge_middle, 4)
        pg.draw.circle(surface, pg.Color("grey"), self.rect.center,
                       Peepo.RADIUS, 2)

    def make_image(self):
        image = pg.Surface(self.rect.size).convert_alpha()
        image.fill(TRANSPARENT)
        image_rect = image.get_rect()
        pg.draw.rect(image, pg.Color("black"), image_rect)
        pg.draw.rect(image, pg.Color("green"), image_rect.inflate(-2, -2))
        return image

    def calculate_obstacles(self):
        self.view = {x: False for x in self.view}
        self.is_an_enemy = False
        self.is_food = False
        for obstacle in self.obstacles:
            if self.rect.colliderect(obstacle[0].rect):
                if obstacle[1] == 0:
                    self.stomach += 1
                    self.obstacles.remove(obstacle)
                else:
                    self.bang += 1
                    self.obstacles.remove(obstacle)
        self.food = []
        [self.food.append(x[0]) for x in self.obstacles if x[1] == 0]
        self.ennemies = []
        [self.ennemies.append(x[0]) for x in self.obstacles if x[1] == 1]
        self.assemble_obstacles()
        observations = []
        for obstacle in self.obstacles:
            distance = math.sqrt(
                (obstacle[0].rect.center[0] - self.rect.center[0])**2 +
                (obstacle[0].rect.center[1] - self.rect.center[1])**2)
            if distance <= Peepo.RADIUS:
                observations.append(obstacle)
        edge1 = end_line(Peepo.RADIUS, self.rotation - 30, self.rect.center)
        edge2 = end_line(Peepo.RADIUS, self.rotation - 15, self.rect.center)
        edge3 = end_line(Peepo.RADIUS, self.rotation, self.rect.center)
        edge4 = end_line(Peepo.RADIUS, self.rotation + 15, self.rect.center)
        edge5 = end_line(Peepo.RADIUS, self.rotation + 30, self.rect.center)
        sectors = [[edge1, edge2], [edge2, edge3], [edge3, edge4],
                   [edge4, edge5]]
        peepo_vec = pg.math.Vector2(self.rect.center)
        relevant_sector = ["0", self.rect.center, Peepo.RADIUS]
        closest_distance = 10000.
        for index, sector in enumerate(sectors):
            lower_edge = sector[0]
            upper_edge = sector[1]
            for obstacle in observations:
                is_collision = collision(obstacle[0].rect, peepo_vec,
                                         lower_edge, upper_edge, Peepo.RADIUS)
                if is_collision:
                    distance = math.sqrt(
                        (obstacle[0].rect.center[0] - peepo_vec[0])**2 +
                        (obstacle[0].rect.center[1] - peepo_vec[1])**2)
                    if distance <= closest_distance:
                        closest_distance = distance
                        relevant_sector[0] = str(index + 1)
                        relevant_sector[1] = obstacle[0].rect.center
                        relevant_sector[2] = closest_distance
                        if obstacle[1] == 1:
                            self.is_an_enemy = True
                            self.is_food = False
                        if obstacle[1] == 0:
                            self.is_food = True
                            self.is_an_enemy = False
        self.view = {x: False for x in self.view}
        self.view[relevant_sector[0]] = True
        sight_angle = 0
        only_true = relevant_sector[0]
        if only_true == '0':
            sight_angle = self.rotation
        if only_true == '1':
            sight_angle = self.rotation - 22.5
        if only_true == '2':
            sight_angle = self.rotation - 7.5
        if only_true == '3':
            sight_angle = self.rotation + 7.5
        if only_true == '4':
            sight_angle = self.rotation + 22.5

        self.edge_middle = end_line(relevant_sector[2] / 20, sight_angle,
                                    relevant_sector[1])