Browse Source

Smell code

Bastien Sevajol 8 years ago
parent
commit
32d4aa8394

+ 18 - 1
intelligine/core/Context.py View File

@@ -14,8 +14,25 @@ class Context(XyzContext):
14 14
         return self._pheromones
15 15
 
16 16
     def position_is_penetrable(self, position):
17
+        """
18
+
19
+        Return True if position is empty or occuped by non physical impenetrable object.
20
+
21
+        :param position:
22
+        :return:
23
+        """
17 24
         objects_ids_on_this_point = self.metas.list.get(POSITIONS, position, allow_empty=True)
18 25
         for object_id_on_this_point in objects_ids_on_this_point:
19 26
           if self.metas.states.have(object_id_on_this_point, IMPENETRABLE):
20 27
             return False
21
-        return True
28
+        return True
29
+
30
+    def position_can_be_odorus(self, position):
31
+        """
32
+
33
+        Return True if position can smell
34
+
35
+        :param position:
36
+        :return:
37
+        """
38
+        return self.position_is_penetrable(position)

+ 7 - 0
intelligine/cst.py View File

@@ -33,6 +33,12 @@ PHEROMON_DIR_NONE = IncrementedNamedInt.get('intelligine.phero.direction.none')
33 33
 PHEROMON_DIR_EXPLO = IncrementedNamedInt.get('intelligine.phero.direction.explo')
34 34
 PHEROMON_DIR_HOME = IncrementedNamedInt.get('intelligine.phero.direction.home')
35 35
 
36
+OBJ_SMELL = IncrementedNamedInt.get('intelligine.obj_smell')
37
+SMELL_FOOD = IncrementedNamedInt.get('intelligine.smell.food')
38
+SMELL_EGG = IncrementedNamedInt.get('intelligine.smell.egg')
39
+POINT_SMELL = IncrementedNamedInt.get('intelligine.point_smell')
40
+POINTS_SMELL = IncrementedNamedInt.get('intelligine.points_smell')
41
+
36 42
 COL_ALIVE = IncrementedNamedInt.get('intelligine.col.alive')
37 43
 COL_WALKER = IncrementedNamedInt.get('intelligine.col.walker')
38 44
 COL_FIGHTER = IncrementedNamedInt.get('intelligine.col.walker')
@@ -40,6 +46,7 @@ COL_TRANSPORTER = IncrementedNamedInt.get('intelligine.col.transporter')
40 46
 COL_TRANSPORTER_CARRYING = IncrementedNamedInt.get('intelligine.col.transporter_carrying')
41 47
 COL_TRANSPORTER_NOT_CARRYING = IncrementedNamedInt.get('intelligine.col.transporter_not_carrying')
42 48
 COL_EATABLE = IncrementedNamedInt.get('intelligine.col.eatable')
49
+COL_SMELL = IncrementedNamedInt.get('intelligine.col.smell')
43 50
 
44 51
 BRAIN_SCHEMA = IncrementedNamedInt.get('intelligine.brain_schema')
45 52
 BRAIN_PART_MOVE = IncrementedNamedInt.get('intelligine.brain.part.move')

+ 25 - 7
intelligine/display/Pygame.py View File

@@ -1,8 +1,10 @@
1 1
 from intelligine.core.exceptions import NoPheromone
2 2
 from synergine_xyz.display.Pygame import Pygame as XyzPygame
3 3
 import pygame
4
-from intelligine.cst import PHEROMON_DIRECTION, PHEROMON_DIR_HOME, PHEROMON_DIR_EXPLO, PHEROMON_POSITIONS
5
-from intelligine.display.pygame.visualisation import SURFACE_PHEROMONE_EXPLORATION, SURFACE_PHEROMONE_HOME
4
+from intelligine.cst import PHEROMON_DIRECTION, PHEROMON_DIR_HOME, PHEROMON_DIR_EXPLO, PHEROMON_POSITIONS, POINTS_SMELL, \
5
+    POINT_SMELL, SMELL_EGG, SMELL_FOOD
6
+from intelligine.display.pygame.visualisation import SURFACE_PHEROMONE_EXPLORATION, SURFACE_PHEROMONE_HOME, \
7
+    SURFACE_SMELL_EGG, SURFACE_SMELL_FOOD
6 8
 
7 9
 
8 10
 class Pygame(XyzPygame):
@@ -10,15 +12,23 @@ class Pygame(XyzPygame):
10 12
     def __init__(self, config, context, synergy_manager):
11 13
         super().__init__(config, context, synergy_manager)
12 14
         self._is_display_pheromones = False
15
+        self._is_display_smells = False
13 16
 
14 17
     def receive(self, actions_done):
15 18
         super().receive(actions_done)
19
+
16 20
         if self._is_display_pheromones:
17 21
             pheromones_positions = self._context.metas.list.get(PHEROMON_POSITIONS,
18 22
                                                                 PHEROMON_POSITIONS,
19 23
                                                                 allow_empty=True)
20 24
             self._display_pheromones(pheromones_positions, self._context)
21 25
 
26
+        if self._is_display_smells:
27
+            smell_positions = self._context.metas.list.get(POINTS_SMELL,
28
+                                                           POINTS_SMELL,
29
+                                                           allow_empty=True)
30
+            self._display_smells(smell_positions, self._context)
31
+
22 32
     def _display_pheromones(self, pheromones_positions, context):
23 33
         pheromone_exploration_surface = self._object_visualizer.get_surface(SURFACE_PHEROMONE_EXPLORATION)
24 34
         pheromone_home_surface = self._object_visualizer.get_surface(SURFACE_PHEROMONE_HOME)
@@ -37,9 +47,17 @@ class Pygame(XyzPygame):
37 47
             except NoPheromone:
38 48
                 pass # No pheromone here
39 49
 
50
+    def _display_smells(self, smell_positions, context):
51
+        smell_egg_surface = self._object_visualizer.get_surface(SURFACE_SMELL_EGG)
52
+        smell_food_surface = self._object_visualizer.get_surface(SURFACE_SMELL_FOOD)
53
+
54
+        for point in smell_positions:
55
+            point_flavour = context.metas.value.get(POINT_SMELL, point, allow_empty=True, empty_value={})
56
+            if SMELL_EGG in point_flavour:
57
+                self.draw_surface(point, smell_egg_surface)
58
+            if SMELL_FOOD in point_flavour:
59
+                self.draw_surface(point, smell_food_surface)
60
+
40 61
     def _key_pressed(self, key):
41
-        if key == pygame.K_p:
42
-            if self._is_display_pheromones:
43
-                self._is_display_pheromones = False
44
-            else:
45
-                self._is_display_pheromones = True
62
+        self._is_display_pheromones = key == pygame.K_p
63
+        self._is_display_smells = key == pygame.K_s

BIN
intelligine/display/pygame/image/smell.png View File


+ 13 - 0
intelligine/display/pygame/visualisation.py View File

@@ -17,6 +17,9 @@ from synergine_xyz.tmx.TileMapConnector import TileMapConnector
17 17
 SURFACE_PHEROMONE_HOME = 'pheromone_home'
18 18
 SURFACE_PHEROMONE_EXPLORATION = 'pheromone_exploration'
19 19
 
20
+SURFACE_SMELL_EGG = 'smell_egg'
21
+SURFACE_SMELL_FOOD = 'smell_food'
22
+
20 23
 # TODO: Analyser les procedes ici pour proposer des outils dans le framework
21 24
 
22 25
 # ant = PygameImage.from_filepath(getcwd()+'/intelligine/display/pygame/image/ant.png')
@@ -39,6 +42,8 @@ eggc5 = PygameImage.from_filepath(getcwd()+'/intelligine/display/pygame/image/eg
39 42
 eggc7 = PygameImage.from_filepath(getcwd()+'/intelligine/display/pygame/image/egg_c7.png')
40 43
 phee = PygameImage.from_filepath(getcwd()+'/intelligine/display/pygame/image/phee.png')
41 44
 pheh = PygameImage.from_filepath(getcwd()+'/intelligine/display/pygame/image/pheh.png')
45
+
46
+smell = PygameImage.from_filepath(getcwd()+'/intelligine/display/pygame/image/smell.png')
42 47
 #
43 48
 # directions_ant = DirectionnedImage(ant)
44 49
 # directions_red_ant = DirectionnedImage(red_ant)
@@ -226,6 +231,14 @@ def get_standard_extract_from_map(map_file_path, map_config):
226 231
                 'default': pheh,
227 232
                 'callbacks': []
228 233
             },
234
+            SURFACE_SMELL_EGG: {
235
+                'default': smell,
236
+                'callbacks': []
237
+            },
238
+            SURFACE_SMELL_FOOD: {
239
+                'default': smell,
240
+                'callbacks': []
241
+            },
229 242
         }
230 243
     })
231 244
 

+ 17 - 0
intelligine/mechanism/TraversableDistanceFromMechanism.py View File

@@ -0,0 +1,17 @@
1
+from synergine_xyz.mechanism.DistanceFromMechanism import DistanceFromMechanism
2
+
3
+
4
+class TraversableDistanceFromMechanism(DistanceFromMechanism):
5
+    """
6
+    Prepare list of traversable points around synergy object position. These point are associated with distance
7
+    of synergy object position.
8
+    """
9
+
10
+    def _get_maximum_distance(self, object_id, context):
11
+        # TODO (ds surcharge) Maintenir un rayon (calculé en fonction de la taille de la colonie + ratio en
12
+        #  fonction de ce qui est smelling)
13
+        # pour le moment ...valeur hardcode
14
+        return 6
15
+
16
+    def _point_is_computable(self, context, point):
17
+        return context.position_can_be_odorus(point)

+ 8 - 1
intelligine/synergy/Rocks.py View File

@@ -1,5 +1,12 @@
1
+from intelligine.synergy.event.smell.SmellAction import SmellAction
1 2
 from synergine.synergy.collection.SynergyCollection import SynergyCollection
2 3
 
3 4
 
4 5
 class Rocks(SynergyCollection):
5
-    pass
6
+    """
7
+    TODO: Rename in Environment
8
+    """
9
+
10
+    def __init__(self, configuration):
11
+        super().__init__(configuration)
12
+        self._actions = [SmellAction]

+ 28 - 0
intelligine/synergy/event/smell/SmellAction.py View File

@@ -0,0 +1,28 @@
1
+from intelligine.cst import POINT_SMELL, POINTS_SMELL
2
+from intelligine.synergy.event.smell.SmellEvent import SmellEvent
3
+from synergine.synergy.event.Action import Action
4
+
5
+
6
+class SmellAction(Action):
7
+
8
+    _listen = SmellEvent
9
+
10
+    def run(self, obj, context, synergy_manager):
11
+
12
+        points_distances = self._parameters['points_distances']
13
+        smell_type = obj.get_smell()
14
+
15
+        for smell_point in points_distances:
16
+
17
+            where_to_put_smells = context.metas.value.get(POINT_SMELL, smell_point, allow_empty=True, empty_value={})
18
+            current_point_smell = points_distances[smell_point]
19
+
20
+            if smell_type not in where_to_put_smells:
21
+                where_to_put_smells[smell_type] = current_point_smell
22
+            else:
23
+                where_to_put_smell = where_to_put_smells[smell_type]
24
+                if current_point_smell < where_to_put_smell:
25
+                    where_to_put_smells[smell_type] = where_to_put_smell
26
+
27
+            context.metas.value.set(POINT_SMELL, smell_point, where_to_put_smells)
28
+            context.metas.list.add(POINTS_SMELL, POINTS_SMELL, smell_point, assert_not_in=False)

+ 26 - 0
intelligine/synergy/event/smell/SmellEvent.py View File

@@ -0,0 +1,26 @@
1
+from intelligine.cst import COL_SMELL
2
+from intelligine.mechanism.TraversableDistanceFromMechanism import TraversableDistanceFromMechanism
3
+from intelligine.synergy.event.Event import Event
4
+from intelligine.cst import SMELL_FOOD, SMELL_EGG
5
+from intelligine.synergy.object.StockedFood import StockedFood
6
+from intelligine.synergy.object.ant.Egg import Egg
7
+from synergine.core.exceptions import NotConcernedEvent
8
+
9
+
10
+class SmellEvent(Event):
11
+
12
+    _mechanism = TraversableDistanceFromMechanism
13
+    _concern = COL_SMELL
14
+    _each_cycle = 100
15
+    _first_cycle_force = True
16
+    _smell = {
17
+        StockedFood: SMELL_FOOD,
18
+        Egg: SMELL_EGG
19
+    }
20
+    """ Match between synergy class and smell type """
21
+
22
+    def _prepare(self, object_id, context, parameters={}):
23
+        if not parameters['points_distances']:
24
+            raise NotConcernedEvent()
25
+
26
+        return parameters

+ 2 - 1
intelligine/synergy/object/Egg.py View File

@@ -1,5 +1,5 @@
1 1
 from intelligine.synergy.object.BaseBug import BaseBug
2
-from intelligine.cst import TRANSPORTABLE, TYPE_NURSERY, TYPE
2
+from intelligine.cst import TYPE_NURSERY, TYPE, SMELL_EGG
3 3
 
4 4
 
5 5
 class Egg(BaseBug):
@@ -8,3 +8,4 @@ class Egg(BaseBug):
8 8
         super().__init__(collection, context)
9 9
         context.metas.list.add(TYPE, self.get_id(), TYPE_NURSERY)
10 10
         self._life_points = 1
11
+        self._set_smell(SMELL_EGG)

+ 3 - 1
intelligine/synergy/object/StockedFood.py View File

@@ -1,4 +1,4 @@
1
-from intelligine.cst import TYPE, TYPE_RESOURCE_EXPLOITABLE, COL_EATABLE
1
+from intelligine.cst import TYPE, TYPE_RESOURCE_EXPLOITABLE, COL_EATABLE, COL_SMELL, SMELL_FOOD
2 2
 from intelligine.synergy.object.Food import Food
3 3
 
4 4
 
@@ -8,3 +8,5 @@ class StockedFood(Food):
8 8
         super().__init__(collection, context)
9 9
         context.metas.list.remove(TYPE, self.get_id(), TYPE_RESOURCE_EXPLOITABLE)
10 10
         self._add_col(COL_EATABLE)
11
+        self._add_col(COL_SMELL)
12
+        self._set_smell(SMELL_FOOD)

+ 18 - 0
intelligine/synergy/object/SynergyObject.py View File

@@ -0,0 +1,18 @@
1
+from intelligine.cst import OBJ_SMELL
2
+from synergine_xyz.SynergyObject import SynergyObject as XyzSynergyObject
3
+
4
+
5
+class SynergyObject(XyzSynergyObject):
6
+
7
+    def __init__(self, collection, context):
8
+        super().__init__(collection, context)
9
+        self._smell = None
10
+
11
+    def _set_smell(self, smell_type):
12
+        self._smell = smell_type
13
+        self._context.metas.value.set(OBJ_SMELL, self.get_id(), smell_type)
14
+
15
+    def get_smell(self):
16
+        if not self._smell:
17
+            raise Exception('Smell type not defined')
18
+        return self._smell

+ 2 - 2
intelligine/synergy/object/Transportable.py View File

@@ -1,8 +1,8 @@
1
-from synergine_xyz.SynergyObject import SynergyObject as XyzSynergyObject
2 1
 from intelligine.cst import TRANSPORTABLE, CARRIED
2
+from intelligine.synergy.object.SynergyObject import SynergyObject
3 3
 
4 4
 
5
-class Transportable(XyzSynergyObject):
5
+class Transportable(SynergyObject):
6 6
 
7 7
     def __init__(self, collection, context):
8 8
         super().__init__(collection, context)