Browse Source

molecules evaporation

Bastien Sevajol 8 years ago
parent
commit
e595fc5914

+ 1 - 1
TODO View File

@@ -1,4 +1,4 @@
1 1
 * Fourmis (map.tmx) pas en mode nurse (-> algo de choix d'activité plus tard)
2 2
 * Ant: MOVE_MODE_HOME && rien à faire (pas de truc à stocker, switch to mode EXPLO)
3 3
 * Nourriture posé: Comme oeufs, plus de debug. Implique algo pour pas remplir couloirs. Implique ne plus travailler a xplo de nourriture si plus de place ? etc ...
4
-* ! Les molecules d'odeur (oeuf et bouffe) ne disparaissent pas. Ce que l'on peut faire: Ces odeurs ont tjrs une intensité de 1. En même temps que l'on lance la SmellAction on lance (juste avant) l'Action d'évaporation. Les odeurs seront ainsi nettoyé.
4
+* ! Les molecules d'odeur (oeuf et bouffe) ne disparaissent pas. Ce que l'on peut faire: Ces odeurs ont tjrs une intensité de 1. En même temps que l'on lance la SmellAction on lance (juste avant) l'Action d'évaporation. Les odeurs seront ainsi nettoyé. EDIT c'est censcé être dans le cycle_pre_run de l'action !

+ 9 - 1
config.py View File

@@ -28,7 +28,8 @@ config = {
28 28
             'mainprocess': True,
29 29
             'cycles': -1,
30 30
             'seed': 42
31
-        }
31
+        },
32
+        'clean_each_cycle': 100
32 33
     },
33 34
     'simulations': simulations,
34 35
     'connections': [Pygame],
@@ -60,5 +61,12 @@ config = {
60 61
         'put': {
61 62
             'max_objects_at_same_position': 5
62 63
         }
64
+    },
65
+    'stigmergy': {
66
+        'molecule': {
67
+            'evaporate_decrement': 5,
68
+            'evaporate_min_age': 100,
69
+            'evaporate_each_cycle': 100
70
+        }
63 71
     }
64 72
 }

+ 2 - 2
intelligine/cst.py View File

@@ -35,8 +35,8 @@ TYPE_NURSERY = IncrementedNamedInt.get('intelligine.object.type.nursery')
35 35
 TYPE_ANT = IncrementedNamedInt.get('intelligine.object.type.ant')
36 36
 
37 37
 PHEROMON_POSITIONS = IncrementedNamedInt.get('intelligine.phero.positions')
38
-MOLECULES_INFOS = IncrementedNamedInt.get('intelligine.phero.infos')
39
-MOLECULES_DIRECTION = IncrementedNamedInt.get('intelligine.phero.direction')
38
+MOLECULES_INFOS = IncrementedNamedInt.get('intelligine.mol.infos')
39
+MOLECULES_DIRECTION = IncrementedNamedInt.get('intelligine.mol.direction')
40 40
 PHEROMON_DIR_NONE = IncrementedNamedInt.get('intelligine.phero.direction.none')
41 41
 PHEROMON_DIR_EXPLO = IncrementedNamedInt.get('intelligine.phero.direction.explo')
42 42
 EXPLORATION_VECTOR = IncrementedNamedInt.get('intelligine.exploration_vector')

+ 1 - 1
intelligine/display/pygame/config.py View File

@@ -1,7 +1,7 @@
1 1
 from intelligine.synergy.Colony import Colony
2 2
 from intelligine.synergy.Environment import Environment
3
+from intelligine.synergy.Simulation import Simulation
3 4
 from intelligine.synergy.object.StockedFood import StockedFood
4
-from synergine.synergy.Simulation import Simulation
5 5
 from intelligine.synergy.object.Food import Food
6 6
 from intelligine.synergy.object.Rock import Rock
7 7
 from intelligine.synergy.object.ant.Ant import Ant

+ 1 - 1
intelligine/simulation/molecule/DirectionMolecule.py View File

@@ -11,7 +11,7 @@ class DirectionMolecule():
11 11
 
12 12
     @classmethod
13 13
     def appose(cls, context, point, molecule):
14
-        context.molecules().increment_with_molecule(point, molecule)
14
+        context.molecules().increment_with_molecule(point, molecule, context.get_cycle())
15 15
         context.metas.list.add(MOLECULES, MOLECULES, point, assert_not_in=False)
16 16
 
17 17
     @classmethod

+ 35 - 0
intelligine/simulation/molecule/Evaporation.py View File

@@ -0,0 +1,35 @@
1
+from intelligine.cst import MOLECULES, MOLECULES_DIRECTION
2
+from intelligine.synergy.stigmergy.MoleculesManager import MoleculesManager
3
+
4
+
5
+class Evaporation:
6
+
7
+    def __init__(self, context, intensity_decrement, molecules_exclude_types, molecule_minimum_age):
8
+        self._context = context
9
+        self._intensity_decrement = intensity_decrement
10
+        self._molecules_manager = MoleculesManager(context)
11
+        self._molecules_exclude_types = molecules_exclude_types
12
+        self._molecule_minimum_age = molecule_minimum_age
13
+
14
+    def evaporate(self):
15
+        for position, flavour in self._get_flavours():
16
+            self._decrease_flavour(flavour)
17
+            self._molecules_manager.set_flavour(position, flavour)
18
+
19
+    def _get_flavours(self):
20
+        molecules_points = self._context.metas.list.get(MOLECULES, MOLECULES)
21
+        for molecule_point in molecules_points:
22
+            yield molecule_point, self._molecules_manager.get_flavour(molecule_point)
23
+
24
+    def _decrease_flavour(self, flavour):
25
+        for direction_molecule in flavour.get_molecules(MOLECULES_DIRECTION):
26
+            if not self._is_recent_molecule(direction_molecule) \
27
+               and not self._is_excluded_molecule_type(direction_molecule):
28
+                direction_molecule.increment_intensity(-self._intensity_decrement)
29
+                flavour.set_molecule(direction_molecule)
30
+
31
+    def _is_recent_molecule(self, molecule):
32
+        return (self._context.get_cycle() - molecule.get_cycle_age()) < self._molecule_minimum_age
33
+
34
+    def _is_excluded_molecule_type(self, molecule):
35
+        return molecule.get_type() in self._molecules_exclude_types

+ 5 - 1
intelligine/simulation/molecule/Molecule.py View File

@@ -1,10 +1,11 @@
1 1
 class Molecule():
2 2
 
3
-    def __init__(self, category, type, distance=None, intensity=0):
3
+    def __init__(self, category, type, distance=None, intensity=0, cycle_age=None):
4 4
         self._category = category
5 5
         self._type = type
6 6
         self._distance = distance
7 7
         self._intensity = intensity
8
+        self._cycle_age = cycle_age
8 9
 
9 10
     def get_category(self):
10 11
         return self._category
@@ -21,5 +22,8 @@ class Molecule():
21 22
     def get_intensity(self):
22 23
         return self._intensity
23 24
 
25
+    def get_cycle_age(self):
26
+        return self._cycle_age
27
+
24 28
     def increment_intensity(self, increment_value):
25 29
         self._intensity += increment_value

+ 13 - 4
intelligine/simulation/molecule/MoleculeFlavour.py View File

@@ -10,10 +10,10 @@ class MoleculeFlavour():
10 10
         for category in raw_data:
11 11
             molecules_by_category = raw_data[category]
12 12
             for type in molecules_by_category:
13
-                distance, intensity = molecules_by_category[type]
13
+                distance, intensity, cycle_age = molecules_by_category[type]
14 14
                 if category not in flavour:
15 15
                     flavour[category] = {}
16
-                flavour[category][type] = Molecule(category, type, distance, intensity)
16
+                flavour[category][type] = Molecule(category, type, distance, intensity, cycle_age)
17 17
         return cls(flavour)
18 18
 
19 19
     def get_raw_data(self):
@@ -24,7 +24,10 @@ class MoleculeFlavour():
24 24
                 molecule = molecules_by_category[type]
25 25
                 if category not in raw_data:
26 26
                     raw_data[category] = {}
27
-                raw_data[category][type] = (molecule.get_distance(), molecule.get_intensity())
27
+                if molecule.get_intensity() >= 0:
28
+                    raw_data[category][type] = (molecule.get_distance(),
29
+                                                molecule.get_intensity(),
30
+                                                molecule.get_cycle_age())
28 31
         return raw_data
29 32
 
30 33
     def __init__(self, flavour):
@@ -43,7 +46,13 @@ class MoleculeFlavour():
43 46
         :return: Molecules dict or empty dict of no molecules
44 47
         """
45 48
         try:
46
-            return self.get_types(category)
49
+            return self.get_types(category).values()
50
+        except NoCategoryInMolecule:
51
+            return {}
52
+
53
+    def get_molecules_types(self, category):
54
+        try:
55
+            return self.get_types(category).keys()
47 56
         except NoCategoryInMolecule:
48 57
             return {}
49 58
 

+ 2 - 2
intelligine/simulation/object/brain/part/move/AntMoveBrainPart.py View File

@@ -117,7 +117,7 @@ class AntMoveBrainPart(MoveBrainPart):
117 117
     def _on_home_smell(cls, context, object_id):
118 118
         current_position = context.metas.value.get(POSITION, object_id)
119 119
         flavour = context.molecules().get_flavour(current_position)
120
-        molecules = flavour.get_molecules(MOLECULES_DIRECTION)
120
+        molecules = flavour.get_molecules_types(MOLECULES_DIRECTION)
121 121
 
122 122
         if not molecules:
123 123
             return False
@@ -140,7 +140,7 @@ class AntMoveBrainPart(MoveBrainPart):
140 140
             self._update_exploration_vector()
141 141
 
142 142
     def _start_new_exploration(self):
143
-        self._reinit_exploration_vector()
143
+        self._init_exploration_vector()
144 144
         self._host_brain.switch_to_mode(MODE_EXPLO)
145 145
 
146 146
     def _init_exploration_vector(self):

+ 1 - 1
intelligine/simulation/object/brain/part/transport/AntTakeBrainPart.py View File

@@ -1,7 +1,7 @@
1 1
 from intelligine.simulation.object.brain.part.transport.TakeBrainPart import TakeBrainPart
2 2
 from intelligine.synergy.object.ressource.Ressource import Resource
3 3
 from intelligine.cst import MODE_EXPLO, TYPE_RESOURCE_EXPLOITABLE, \
4
-    MODE_GOHOME, MODE_NURSE, TYPE_NURSERY
4
+    MODE_GOHOME, MODE_NURSE, TYPE_NURSERY, MODE_HOME
5 5
 
6 6
 
7 7
 class AntTakeBrainPart(TakeBrainPart):

+ 29 - 1
intelligine/synergy/Simulation.py View File

@@ -1,9 +1,37 @@
1
+from intelligine.simulation.molecule.Evaporation import Evaporation
2
+from synergine.core.Core import Core
1 3
 from synergine.synergy.Simulation import Simulation as BaseSimulation
2 4
 from synergine_xyz.cst import POSITIONS
3 5
 
4 6
 
5 7
 class Simulation(BaseSimulation):
6 8
 
9
+    _smells = []
10
+
11
+    @classmethod
12
+    def add_smell(cls, smell):
13
+        if smell not in cls._smells:
14
+            cls._smells.append(smell)
15
+
16
+    @classmethod
17
+    def get_smells(cls):
18
+        return cls._smells
19
+
7 20
     def end_cycle(self, context):
8
-        if context.get_cycle() % 100 is 0:
21
+        clean_each_cycle = Core.get_configuration_manager().get('engine.clean_each_cycle', 100)
22
+        evaporate_each_cycle = Core.get_configuration_manager().get('stigmergy.molecule.evaporate_each_cycle', 100)
23
+
24
+        if context.get_cycle() % clean_each_cycle is 0:
9 25
             context.metas.list.clean(POSITIONS)
26
+
27
+        if context.get_cycle() % evaporate_each_cycle is 0:
28
+            self._evaporate(context)
29
+
30
+    def _evaporate(self, context):
31
+        evaporation_increment = Core.get_configuration_manager().get('stigmergy.molecule.evaporate_decrement', 5)
32
+        evaporation_min_age = Core.get_configuration_manager().get('stigmergy.molecule.evaporate_min_age', 100)
33
+        evaporation = Evaporation(context,
34
+                                  evaporation_increment,
35
+                                  molecules_exclude_types=self.get_smells(),
36
+                                  molecule_minimum_age=evaporation_min_age)
37
+        evaporation.evaporate()

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

@@ -35,7 +35,7 @@ class SmellAction(Action):
35 35
             try:
36 36
                 DirectionMolecule.appose(context, smell_point, molecule)
37 37
             except BestMoleculeHere:
38
-                pass  #
38
+                pass  # TODO: Pas l'inverse ? A voir apres avoir fix la disparition.
39 39
 
40 40
             #
41 41
             # current_point_smell = points_distances[smell_point]

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

@@ -1,4 +1,5 @@
1 1
 from intelligine.cst import OBJ_SMELL, INSTANCE_CLASS
2
+from intelligine.synergy.Simulation import Simulation
2 3
 from synergine_xyz.SynergyObject import SynergyObject as XyzSynergyObject
3 4
 
4 5
 
@@ -12,6 +13,7 @@ class SynergyObject(XyzSynergyObject):
12 13
     def _set_smell(self, smell_type):
13 14
         self._smell = smell_type
14 15
         self._context.metas.value.set(OBJ_SMELL, self.get_id(), smell_type)
16
+        Simulation.add_smell(smell_type)
15 17
 
16 18
     def get_smell(self):
17 19
         if not self._smell:

+ 3 - 2
intelligine/synergy/stigmergy/MoleculesManager.py View File

@@ -28,14 +28,15 @@ class MoleculesManager():
28 28
                 return Molecule()
29 29
             raise
30 30
 
31
-    def increment_with_molecule(self, position, apposed_molecule):
31
+    def increment_with_molecule(self, position, apposed_molecule, cycle_age):
32 32
         flavour = self.get_flavour(position)
33 33
         try:
34 34
             position_molecule = flavour.get_molecule(apposed_molecule.get_category(), apposed_molecule.get_type())
35 35
         except NoMolecule:
36 36
             position_molecule = Molecule(apposed_molecule.get_category(),
37 37
                                          apposed_molecule.get_type(),
38
-                                         distance=apposed_molecule.get_distance())
38
+                                         distance=apposed_molecule.get_distance(),
39
+                                         cycle_age=cycle_age)
39 40
 
40 41
         position_molecule.increment_intensity(apposed_molecule.get_intensity())
41 42