Kaynağa Gözat

molecules evaporation

Bastien Sevajol 9 yıl önce
ebeveyn
işleme
e595fc5914

+ 1 - 1
TODO Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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