Browse Source

Merge branch 'dev/refact'

Bastien Sevajol 9 years ago
parent
commit
924841b190

+ 2 - 0
TODO View File

@@ -8,6 +8,8 @@ TODO:
8 8
 
9 9
  * Mechanisme qui donne les pheromones around ?
10 10
  * Appliquer la disparition des pheromones
11
+ * Les move mode sont arbitraire. On sais (cf. livre Ameisen) qu'elles se spécialisent avec l'expérience de reussite/echec. Voir coment implémenter ça !
12
+ * Display: la maj de ce qui est envoye aux terminaux: penser aux donnees comme les pheromones
11 13
 
12 14
 Future:
13 15
  * Chambres

+ 0 - 14
config.py View File

@@ -6,20 +6,6 @@ from intelligine.display.pygame.visualisation import visualisation as pygame_vis
6 6
 # TODO: influencer avec argument python
7 7
 from intelligine.sandbox.exploration.collections import collections
8 8
 
9
-"""
10
- TODO:
11
- * AttackAction :: comment choisir entre les actions ?
12
-
13
- * pheromones:
14
-   cf. doc papier
15
-   + Pour le "pt de ressource": Poser un objet qui, lorsque on applique la position:
16
-     L'objet doit pouvoir occuper plusieurs positions (gros objet)
17
-     Il a donc * une position de reference
18
-               * une liste de positions occupe
19
-               * dans les metas cette liste de position contient la reference de l'objet
20
-               *
21
-
22
-"""
23 9
 
24 10
 config = {
25 11
     'app': {

+ 11 - 0
intelligine/core/exceptions.py View File

@@ -42,6 +42,9 @@ class BestPheromoneHere(PheromoneException):
42 42
     def get_best_distance(self):
43 43
         return self._best_distance
44 44
 
45
+class PheromoneGlandDisabled(PheromoneException):
46
+    pass
47
+
45 48
 
46 49
 class BrainException(Exception):
47 50
     pass
@@ -51,6 +54,14 @@ class BrainPartAlreadyExist(BrainException):
51 54
     pass
52 55
 
53 56
 
57
+class BodyException(Exception):
58
+    pass
59
+
60
+
61
+class BodyPartAlreadyExist(BodyException):
62
+    pass
63
+
64
+
54 65
 class DirectionException(Exception):
55 66
     pass
56 67
 

+ 9 - 3
intelligine/cst.py View File

@@ -15,18 +15,20 @@ CANT_PUT_STILL = IncrementedNamedInt.get('intelligine.cantput.still')
15 15
 ACTION_DIE = IncrementedNamedInt.get('intelligine.basebug.action.die')
16 16
 PHEROMONE_SEARCHING = IncrementedNamedInt.get('intelligine.pheromone_searching')
17 17
 
18
+# TODO: Renommer "move_mode" en "mode"
18 19
 MOVE_MODE = IncrementedNamedInt.get('intelligine.basebug.move.mode')
19 20
 MOVE_MODE_EXPLO = IncrementedNamedInt.get('intelligine.basebug.move.mode.explo')
20 21
 MOVE_MODE_GOHOME = IncrementedNamedInt.get('intelligine.basebug.move.mode.gohome')
22
+MOVE_MODE_NURSE = IncrementedNamedInt.get('intelligine.basebug.move.mode.nurse')
21 23
 
22 24
 TYPE = IncrementedNamedInt.get('intelligine.object.type')
23 25
 TYPE_RESOURCE_TRANSFORMABLE = IncrementedNamedInt.get('intelligine.object.type.resource.transformable')
24
-
25
-LAST_PHERMONES_POINTS = IncrementedNamedInt.get('intelligine.last_pheromones_points')
26
+TYPE_NURSERY = IncrementedNamedInt.get('intelligine.object.type.nursery')
26 27
 
27 28
 PHEROMON_POSITIONS = IncrementedNamedInt.get('intelligine.phero.positions')
28 29
 PHEROMON_INFOS = IncrementedNamedInt.get('intelligine.phero.infos')
29 30
 PHEROMON_DIRECTION = IncrementedNamedInt.get('intelligine.phero.direction')
31
+PHEROMON_DIR_NONE = IncrementedNamedInt.get('intelligine.phero.direction.none')
30 32
 PHEROMON_DIR_EXPLO = IncrementedNamedInt.get('intelligine.phero.direction.explo')
31 33
 PHEROMON_DIR_HOME = IncrementedNamedInt.get('intelligine.phero.direction.home')
32 34
 
@@ -40,4 +42,8 @@ COL_TRANSPORTER_NOT_CARRYING = IncrementedNamedInt.get('intelligine.col.transpor
40 42
 BRAIN_SCHEMA = IncrementedNamedInt.get('intelligine.brain_schema')
41 43
 BRAIN_PART_MOVE = IncrementedNamedInt.get('intelligine.brain.part.move')
42 44
 BRAIN_PART_TAKE = IncrementedNamedInt.get('intelligine.brain.part.take')
43
-BRAIN_PART_PUT = IncrementedNamedInt.get('intelligine.brain.part.put')
45
+BRAIN_PART_PUT = IncrementedNamedInt.get('intelligine.brain.part.put')
46
+BRAIN_PART_ATTACK = IncrementedNamedInt.get('intelligine.brain.part.attack')
47
+
48
+BODY_SCHEMA = IncrementedNamedInt.get('intelligine.body_schema')
49
+BODY_PART_PHEROMONE_GLAND = IncrementedNamedInt.get('intelligine.body.part.pheromone_gland')

+ 5 - 1
intelligine/sandbox/colored/RedColonyConfiguration.py View File

@@ -1,17 +1,21 @@
1 1
 from intelligine.synergy.ColonyConfiguration import ColonyConfiguration
2 2
 from intelligine.sandbox.colored.RedAnt import RedAnt
3 3
 from intelligine.synergy.object.ant.Egg import Egg
4
-from intelligine.cst import COLONY
4
+from intelligine.cst import COLONY, MOVE_MODE_NURSE
5 5
 
6 6
 
7 7
 class RedColonyConfiguration(ColonyConfiguration):
8 8
 
9 9
     _start_position = (0, 20, 70)
10 10
     _ant_class = RedAnt
11
+    _ant_count = 50
11 12
 
12 13
     def get_start_objects(self, collection, context):
13 14
         objects = super().get_start_objects(collection, context)
14 15
 
16
+        for ant in objects:
17
+            ant._brain.switch_to_mode(MOVE_MODE_NURSE)
18
+
15 19
         for x in range(50):
16 20
           for y in range(1, 50):
17 21
             if x % 3 == 0 and y % 3 == 0:

+ 17 - 18
intelligine/simulation/object/brain/AntBrain.py View File

@@ -1,7 +1,7 @@
1 1
 from intelligine.simulation.object.brain.Brain import Brain
2 2
 from intelligine.simulation.object.brain.part.move.AntMoveBrainPart import AntMoveBrainPart
3 3
 from intelligine.cst import MOVE_MODE, MOVE_MODE_EXPLO, MOVE_MODE_GOHOME, PHEROMON_DIR_HOME, PHEROMON_DIR_EXPLO, \
4
-    BRAIN_PART_TAKE, BRAIN_PART_PUT
4
+    BRAIN_PART_TAKE, BRAIN_PART_PUT, MOVE_MODE_NURSE, PHEROMON_DIR_NONE
5 5
 from intelligine.cst import PHEROMONE_SEARCHING
6 6
 from intelligine.cst import BRAIN_PART_MOVE
7 7
 from intelligine.simulation.object.brain.part.transport.AntPutBrainPart import AntPutBrainPart
@@ -10,29 +10,19 @@ from intelligine.simulation.object.brain.part.transport.AntTakeBrainPart import
10 10
 
11 11
 class AntBrain(Brain):
12 12
 
13
-    _brain_part_move_class = AntMoveBrainPart
14
-    _brain_part_take_class = AntTakeBrainPart
15
-    _brain_part_put_class = AntPutBrainPart
13
+    # TODO: methode __init_ pour la classe ? Pour surcharger ici.
14
+    _brain_parts = {
15
+        BRAIN_PART_MOVE: AntMoveBrainPart,
16
+        BRAIN_PART_TAKE: AntTakeBrainPart,
17
+        BRAIN_PART_PUT: AntPutBrainPart
18
+    }
16 19
 
17 20
     def __init__(self, context, host):
18 21
         super().__init__(context, host)
19
-        # TODO: Gerer les BrainPart avec un dictionnaire ?
20
-        self._set_brain_part(BRAIN_PART_MOVE, self._get_move_brain_part_instance())
21
-        self._set_brain_part(BRAIN_PART_TAKE, self._get_take_brain_part_instance())
22
-        self._set_brain_part(BRAIN_PART_PUT, self._get_put_brain_part_instance())
23 22
         self._movement_mode = MOVE_MODE_EXPLO
24 23
         self._distance_from_objective = 0  # TODO rename: distance_since_objective
25 24
         self._pheromone_searching = PHEROMON_DIR_EXPLO
26 25
 
27
-    def _get_move_brain_part_instance(self):
28
-        return self._brain_part_move_class()
29
-
30
-    def _get_take_brain_part_instance(self):
31
-        return self._brain_part_take_class()
32
-
33
-    def _get_put_brain_part_instance(self):
34
-        return self._brain_part_put_class()
35
-
36 26
     def switch_to_mode(self, mode):
37 27
         self._movement_mode = mode
38 28
         self._update_pheromone_gland(mode)
@@ -45,15 +35,24 @@ class AntBrain(Brain):
45 35
             pheromone_direction_type = PHEROMON_DIR_HOME
46 36
         elif mode == MOVE_MODE_GOHOME:
47 37
             pheromone_direction_type = PHEROMON_DIR_EXPLO
38
+        elif mode == MOVE_MODE_NURSE:
39
+            pheromone_direction_type = None
48 40
         else:
49 41
             raise NotImplementedError()
50
-        self._host.get_movement_pheromone_gland().set_pheromone_type(pheromone_direction_type)
42
+
43
+        if pheromone_direction_type:
44
+            self._host.get_movement_pheromone_gland().set_pheromone_type(pheromone_direction_type)
45
+            self._host.get_movement_pheromone_gland().enable()
46
+        else:
47
+            self._host.get_movement_pheromone_gland().disable()
51 48
 
52 49
     def _update_pheromone_searching(self, mode):
53 50
         if mode == MOVE_MODE_EXPLO:
54 51
             pheromone_searching = PHEROMON_DIR_EXPLO
55 52
         elif mode == MOVE_MODE_GOHOME:
56 53
             pheromone_searching = PHEROMON_DIR_HOME
54
+        elif mode == MOVE_MODE_NURSE:
55
+            pheromone_searching = PHEROMON_DIR_NONE
57 56
         else:
58 57
             raise NotImplementedError()
59 58
         self._pheromone_searching = pheromone_searching

+ 8 - 1
intelligine/simulation/object/brain/Brain.py View File

@@ -4,13 +4,18 @@ from intelligine.cst import BRAIN_SCHEMA
4 4
 
5 5
 class Brain():
6 6
 
7
-    _brain_part_class = {}
7
+    _brain_parts = {}
8 8
 
9 9
     def __init__(self, context, host):
10 10
         self._context = context
11 11
         self._host = host
12 12
         self._schema = {}
13 13
         self._parts = {}
14
+        self._init_parts()
15
+
16
+    def _init_parts(self):
17
+        for brain_part_name in self._brain_parts:
18
+            self._set_brain_part(brain_part_name, self._brain_parts[brain_part_name](self))
14 19
 
15 20
     def _set_brain_part(self, name, brain_part, replace=False):
16 21
         if name in self._parts and not replace:
@@ -25,4 +30,6 @@ class Brain():
25 30
         self._schema = {}
26 31
         for part_name in self._parts:
27 32
             self._schema[part_name] = self._parts[part_name].__class__
33
+        # TODO: N'est-ce pas un schema appartenant a la classe ? Ne suffirai t-il pas de stocker ce schema par classe
34
+        # plutôt que par objet ?
28 35
         self._context.metas.value.set(BRAIN_SCHEMA, self._host.get_id(), self._schema)

+ 3 - 0
intelligine/simulation/object/brain/part/BrainPart.py View File

@@ -1,4 +1,7 @@
1 1
 class BrainPart():
2 2
 
3
+    def __init__(self, host_brain):
4
+        self._host_brain = host_brain
5
+
3 6
     def done(self, obj, context):
4 7
         pass

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

@@ -49,5 +49,6 @@ class AntMoveBrainPart(MoveBrainPart):
49 49
 
50 50
     @staticmethod
51 51
     def _appose_pheromone(obj):
52
-        obj.get_movement_pheromone_gland().appose()
52
+        if obj.get_movement_pheromone_gland().is_enabled():
53
+            obj.get_movement_pheromone_gland().appose()
53 54
 

+ 10 - 7
intelligine/simulation/object/brain/part/transport/AntPutBrainPart.py View File

@@ -1,11 +1,11 @@
1 1
 from intelligine.core.exceptions import CantFindWhereToPut
2
-from intelligine.simulation.object.brain.part.transport.TakeBrainPart import TakeBrainPart
3
-from intelligine.cst import MOVE_MODE_EXPLO, MOVE_MODE, TYPE_RESOURCE_TRANSFORMABLE, TYPE, CARRIED, \
4
-    COL_TRANSPORTER_NOT_CARRYING, COL_TRANSPORTER_CARRYING
2
+from intelligine.cst import MOVE_MODE_EXPLO, TYPE_RESOURCE_TRANSFORMABLE, CARRIED
3
+from intelligine.simulation.object.brain.part.transport.TransportBrainPart import TransportBrainPart
4
+from intelligine.synergy.object.Food import Food
5 5
 from xyzworld.cst import POSITION, POSITIONS
6 6
 
7 7
 
8
-class AntPutBrainPart(TakeBrainPart):
8
+class AntPutBrainPart(TransportBrainPart):
9 9
 
10 10
     # TODO: methode __nit_ pour la classe ?
11 11
     _mode_matches = {
@@ -52,6 +52,9 @@ class AntPutBrainPart(TakeBrainPart):
52 52
         return False
53 53
 
54 54
     def done(self, obj, puted_object, context):
55
-        # TODO: Depose au -1 pour des raisons de test. Plus tard ce sera des tas comme un autre !
56
-        puted_object.set_position((-1, 0, 0))
57
-        obj.get_brain().switch_to_mode(MOVE_MODE_EXPLO)
55
+        # TODO: Il faut refact/logique qqpart pour ca !! Genre Brain.done(PUT, ??)
56
+        if isinstance(puted_object, Food):
57
+            obj.get_brain().switch_to_mode(MOVE_MODE_EXPLO)
58
+            # TODO: TEST Depose au -1 pour des raisons de test. Plus tard ce sera des tas comme un autre !
59
+            puted_object.set_position((-1, 0, 0))
60
+

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

@@ -1,14 +1,15 @@
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 MOVE_MODE_EXPLO, MOVE_MODE, TYPE_RESOURCE_TRANSFORMABLE, \
4
-    TYPE, MOVE_MODE_GOHOME, PHEROMON_DIR_EXPLO
4
+    TYPE, MOVE_MODE_GOHOME, PHEROMON_DIR_EXPLO, MOVE_MODE_NURSE, TYPE_NURSERY
5 5
 
6 6
 
7 7
 class AntTakeBrainPart(TakeBrainPart):
8 8
 
9
-    # TODO: methode __nit_ pour la classe ? vt mieux surcharger !
9
+    # TODO: methode __init_ pour la classe ? Pour surcharger ici.
10 10
     _mode_matches = {
11 11
         MOVE_MODE_EXPLO: [TYPE_RESOURCE_TRANSFORMABLE],
12
+        MOVE_MODE_NURSE: [TYPE_NURSERY]
12 13
     }
13 14
 
14 15
     @classmethod
@@ -20,6 +21,4 @@ class AntTakeBrainPart(TakeBrainPart):
20 21
         # TODO: Ranger ca ? Truc plus dynamique/configurable ?
21 22
         if isinstance(take_object, Resource):
22 23
             obj.get_brain().switch_to_mode(MOVE_MODE_GOHOME)
23
-            # TODO: set_last_pheromone_point ca devrait pas etre dans get_movement_pheromone_gland().appose() ?
24
-            obj.set_last_pheromone_point(PHEROMON_DIR_EXPLO, obj.get_position())
25 24
             obj.get_movement_pheromone_gland().appose()

+ 0 - 3
intelligine/simulation/object/brain/part/transport/TransportBrainPart.py View File

@@ -16,9 +16,6 @@ class TransportBrainPart(BrainPart):
16 16
 
17 17
     @classmethod
18 18
     def _objects_have_same_type(cls, context, object_carried_id, object_to_put_id):
19
-        # BUG: On considere ici que c une liste de type pour obj. J'ai fait l'inverse.
20
-        # Une listde de objid pour un type.
21
-        # TODO: Il faut inverser !
22 19
         object_carried_types = context.metas.list.get(TYPE, object_carried_id)
23 20
         for object_carried_type in object_carried_types:
24 21
             if context.metas.list.have(TYPE, object_to_put_id, object_carried_type):

+ 15 - 2
intelligine/simulation/object/pheromone/PheromoneGland.py View File

@@ -1,4 +1,4 @@
1
-from intelligine.core.exceptions import BestPheromoneHere
1
+from intelligine.core.exceptions import BestPheromoneHere, PheromoneGlandDisabled
2 2
 from intelligine.simulation.pheromone.DirectionPheromone import DirectionPheromone
3 3
 
4 4
 class PheromoneGland():
@@ -7,6 +7,7 @@ class PheromoneGland():
7 7
         self._pheromone_type = None
8 8
         self._host = host
9 9
         self._context = context
10
+        self._enabled = False
10 11
 
11 12
     def set_pheromone_type(self, pheromone_type):
12 13
         self._pheromone_type = pheromone_type
@@ -20,9 +21,21 @@ class PheromoneGland():
20 21
         raise NotImplementedError()
21 22
 
22 23
     def appose(self):
24
+        if not self._enabled:
25
+            raise PheromoneGlandDisabled()
26
+
23 27
         try:
24 28
             DirectionPheromone.appose(self._context,
25 29
                                       self._host.get_position(),
26 30
                                       self.get_pheromone())
27 31
         except BestPheromoneHere as best_pheromone_here:
28
-            self._host.get_brain().set_distance_from_objective(best_pheromone_here.get_best_distance())
32
+            self._host.get_brain().set_distance_from_objective(best_pheromone_here.get_best_distance())
33
+
34
+    def disable(self):
35
+        self._enabled = False
36
+
37
+    def enable(self):
38
+        self._enabled = True
39
+
40
+    def is_enabled(self):
41
+        return self._enabled

+ 21 - 13
intelligine/simulation/pheromone/DirectionPheromone.py View File

@@ -12,23 +12,15 @@ class DirectionPheromone():
12 12
         context.pheromones().increment_with_pheromone(point, pheromone)
13 13
         context.metas.list.add(PHEROMON_POSITIONS, PHEROMON_POSITIONS, point, assert_not_in=False)
14 14
 
15
-    @staticmethod
16
-    def get_direction_for_point(context, point, pheromone_type):
15
+    @classmethod
16
+    def get_direction_for_point(cls, context, point, pheromone_type):
17 17
         flavour = context.pheromones().get_flavour(point)
18 18
         pheromone = flavour.get_pheromone(category=PHEROMON_DIRECTION, type=pheromone_type)
19 19
 
20 20
         distance = pheromone.get_distance()
21
-        around_points = context.get_around_points_of(point)
22
-        # TODO: Cet algo around a mettre ailleurs
23
-        around_pheromones_points = []
24
-        for around_point in around_points:
25
-            flavour = context.pheromones().get_flavour(around_point)
26
-            try:
27
-                around_pheromone = flavour.get_pheromone(category=PHEROMON_DIRECTION, type=pheromone_type)
28
-                if around_pheromone.get_distance() < distance:
29
-                    around_pheromones_points.append((around_point, around_pheromone))
30
-            except NoPheromone:
31
-                pass  # No pheromone, ok continue to sniff around
21
+        around_pheromone_filter = lambda around_pheromone: around_pheromone.get_distance() < distance
22
+        around_pheromones_points = cls._get_around_pheromones(context, point, pheromone_type,
23
+                                                              pheromone_filter=around_pheromone_filter)
32 24
 
33 25
         if not around_pheromones_points:
34 26
             raise NoPheromone()
@@ -54,6 +46,22 @@ class DirectionPheromone():
54 46
         return direction
55 47
 
56 48
     @staticmethod
49
+    def _get_around_pheromones(context, reference_point, pheromone_type,
50
+                               pheromone_filter=lambda around_pheromone: True):
51
+        around_points = context.get_around_points_of(reference_point)
52
+        around_pheromones_points = []
53
+        for around_point in around_points:
54
+            flavour = context.pheromones().get_flavour(around_point)
55
+            try:
56
+                around_pheromone = flavour.get_pheromone(category=PHEROMON_DIRECTION, type=pheromone_type)
57
+                if pheromone_filter(around_pheromone):
58
+                    around_pheromones_points.append((around_point, around_pheromone))
59
+            except NoPheromone:
60
+                pass  # No pheromone, ok continue to sniff around
61
+
62
+        return around_pheromones_points
63
+
64
+    @staticmethod
57 65
     def get_best_pheromone_direction_in(context, reference_point, points, pheromone_type):
58 66
         around_pheromones_points = []
59 67
         for around_point in points:

+ 5 - 1
intelligine/synergy/event/attack/NearAttackableEvent.py View File

@@ -2,7 +2,7 @@ from intelligine.core.exceptions import NearNothingFound
2 2
 from synergine.core.exceptions import NotConcernedEvent
3 3
 from intelligine.synergy.event.src.NearEvent import NearEvent
4 4
 from xyzworld.mechanism.ArroundMechanism import ArroundMechanism
5
-from intelligine.cst import ATTACKABLE, COLONY, COL_FIGHTER
5
+from intelligine.cst import ATTACKABLE, COLONY, COL_FIGHTER, BRAIN_PART_ATTACK
6 6
 
7 7
 
8 8
 class NearAttackableEvent(NearEvent):
@@ -24,4 +24,8 @@ class NearAttackableEvent(NearEvent):
24 24
         except NearNothingFound:
25 25
             raise NotConcernedEvent()
26 26
 
27
+        brain_part = self._get_brain_part(context, object_id, BRAIN_PART_ATTACK)
28
+        if not brain_part.can_attack(context, object_id, parameters[self._near_name][0]):
29
+            raise NotConcernedEvent()
30
+
27 31
         return parameters

+ 4 - 11
intelligine/synergy/event/transport/PutableEvent.py View File

@@ -30,7 +30,7 @@ class PutableEvent(NearEvent):
30 30
             raise NotConcernedEvent()
31 31
 
32 32
         object_near_id = parameters[self._near_name][0]
33
-        brain_part = self._get_brain_part(object_id, context)
33
+        brain_part = self._get_brain_part(context, object_id, BRAIN_PART_PUT)
34 34
 
35 35
         if not brain_part.can_put(context, object_id, object_near_id):
36 36
             raise NotConcernedEvent()
@@ -48,14 +48,7 @@ class PutableEvent(NearEvent):
48 48
     def _can_put(object_id, context):
49 49
         return not context.metas.value.get(CANT_PUT_STILL, object_id, allow_empty=True)
50 50
 
51
-    @staticmethod
52
-    def _get_brain_part(object_id, context):
53
-        # TODO: refatc au dessus ?
54
-        object_brain_schema = context.metas.value.get(BRAIN_SCHEMA, object_id)
55
-        return object_brain_schema[BRAIN_PART_PUT]
56
-
57
-    @staticmethod
58
-    def _object_can_put(object_id, context, object_to_put_id):
59
-        object_brain_schema = context.metas.value.get(BRAIN_SCHEMA, object_id)
60
-        object_take_brain_part = object_brain_schema[BRAIN_PART_PUT]
51
+    @classmethod
52
+    def _object_can_put(cls, object_id, context, object_to_put_id):
53
+        object_take_brain_part = cls._get_brain_part(context, object_id, BRAIN_PART_PUT)
61 54
         return object_take_brain_part.can_put(context, object_id, object_to_put_id)

+ 3 - 4
intelligine/synergy/event/transport/TakeableEvent.py View File

@@ -35,8 +35,7 @@ class TakeableEvent(NearEvent):
35 35
     def _can_carry(object_id, context):
36 36
         return not context.metas.value.get(CANT_CARRY_STILL, object_id, allow_empty=True)
37 37
 
38
-    @staticmethod
39
-    def _object_can_take(object_id, context, object_to_take_id):
40
-        object_brain_schema = context.metas.value.get(BRAIN_SCHEMA, object_id)
41
-        object_take_brain_part = object_brain_schema[BRAIN_PART_TAKE]
38
+    @classmethod
39
+    def _object_can_take(cls, object_id, context, object_to_take_id):
40
+        object_take_brain_part = cls._get_brain_part(context, object_id, BRAIN_PART_TAKE)
42 41
         return object_take_brain_part.can_take(context, object_id, object_to_take_id)

+ 17 - 0
intelligine/synergy/object/BaseBug.py View File

@@ -1,3 +1,4 @@
1
+from intelligine.core.exceptions import BodyPartAlreadyExist
1 2
 from intelligine.synergy.object.Transportable import Transportable
2 3
 from intelligine.cst import ALIVE, ATTACKABLE, COL_ALIVE
3 4
 from intelligine.simulation.object.brain.Brain import Brain
@@ -5,6 +6,8 @@ from intelligine.simulation.object.brain.Brain import Brain
5 6
 
6 7
 class BaseBug(Transportable):
7 8
 
9
+    _body_parts = {}
10
+
8 11
     def __init__(self, collection, context):
9 12
         super().__init__(collection, context)
10 13
         context.metas.states.add_list(self.get_id(), [ALIVE, ATTACKABLE])
@@ -12,6 +15,20 @@ class BaseBug(Transportable):
12 15
         self._life_points = 10
13 16
         self._movements_count = -1
14 17
         self._brain = self._get_brain_instance()
18
+        self._parts = {}
19
+        self._init_parts()
20
+
21
+    def _init_parts(self):
22
+        for body_part_name in self._body_parts:
23
+            self._set_body_part(body_part_name, self._body_parts[body_part_name](self, self._context))
24
+
25
+    def _set_body_part(self, name, body_part, replace=False):
26
+        if name in self._parts and not replace:
27
+            raise BodyPartAlreadyExist()
28
+        self._parts[name] = body_part
29
+
30
+    def get_body_part(self, name):
31
+        return self._parts[name]
15 32
 
16 33
     def hurted(self, points):
17 34
         self._life_points -= points

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

@@ -1,10 +1,12 @@
1 1
 from intelligine.synergy.object.BaseBug import BaseBug
2
-from intelligine.cst import TRANSPORTABLE
2
+from intelligine.cst import TRANSPORTABLE, TYPE_NURSERY, TYPE
3 3
 
4 4
 
5 5
 class Egg(BaseBug):
6 6
 
7 7
     def __init__(self, collection, context):
8 8
         super().__init__(collection, context)
9
+        context.metas.list.add(TYPE, self.get_id(), TYPE_NURSERY)
10
+        # TODO: ?? TRANSPORTABLE ne devrait pas ette du cote de Transportable ?
9 11
         context.metas.states.add(self.get_id(), TRANSPORTABLE)
10 12
         self._life_points = 1

+ 20 - 36
intelligine/synergy/object/ant/Ant.py View File

@@ -1,10 +1,7 @@
1
-from intelligine.core.exceptions import BestPheromoneHere
2
-from intelligine.simulation.pheromone.DirectionPheromone import DirectionPheromone
1
+from intelligine.core.exceptions import PheromoneException
3 2
 from intelligine.synergy.object.Bug import Bug
4
-from intelligine.cst import CARRYING, TRANSPORTER, ATTACKER, \
5
-                            COL_TRANSPORTER, COL_TRANSPORTER_NOT_CARRYING, \
6
-                            COL_FIGHTER, MOVE_MODE_EXPLO, MOVE_MODE_GOHOME, \
7
-                            PHEROMON_DIR_EXPLO, LAST_PHERMONES_POINTS, CARRIED
3
+from intelligine.cst import CARRYING, TRANSPORTER, ATTACKER, COL_TRANSPORTER, COL_TRANSPORTER_NOT_CARRYING, \
4
+    COL_FIGHTER, MOVE_MODE_EXPLO, MOVE_MODE_GOHOME, CARRIED, BODY_PART_PHEROMONE_GLAND
8 5
 from intelligine.synergy.object.Food import Food
9 6
 from intelligine.simulation.object.pheromone.MovementPheromoneGland import MovementPheromoneGland
10 7
 from intelligine.simulation.object.brain.AntBrain import AntBrain
@@ -12,76 +9,63 @@ from intelligine.simulation.object.brain.AntBrain import AntBrain
12 9
 
13 10
 class Ant(Bug):
14 11
 
12
+    _body_parts = {
13
+        BODY_PART_PHEROMONE_GLAND: MovementPheromoneGland
14
+    }
15
+
15 16
     def __init__(self, collection, context):
16 17
         super().__init__(collection, context)
17 18
         context.metas.states.add_list(self.get_id(), [TRANSPORTER, ATTACKER])
18 19
         context.metas.collections.add_list(self.get_id(), [COL_TRANSPORTER,
19 20
                                                            COL_TRANSPORTER_NOT_CARRYING,
20 21
                                                            COL_FIGHTER])
21
-        self._carried = []
22
-        self._last_pheromones_points = {}
23
-        # TODO: Faire un body_part schema pour ces trucs la
24
-        self._movement_pheromone_gland = MovementPheromoneGland(self, self._context)
22
+        self._carried = None
25 23
         self._brain.switch_to_mode(MOVE_MODE_EXPLO)
26 24
 
27 25
     def _get_brain_instance(self):
28 26
         return AntBrain(self._context, self)
29 27
 
30 28
     def get_movement_pheromone_gland(self):
31
-        return self._movement_pheromone_gland
29
+        return self.get_body_part(BODY_PART_PHEROMONE_GLAND)
32 30
 
33 31
     def put_carry(self, obj, position=None):
34 32
         if position is None:
35 33
             position = self._get_position()
36
-        self._carried.remove(obj)
34
+        self._carried = None
37 35
         obj.set_position(position)
38 36
         self._context.metas.states.remove(self.get_id(), CARRYING)
39 37
 
40 38
     def get_carried(self):
41
-        # TODO: cas ou plusieurs ?
42
-        return self._carried[0]
39
+        return self._carried
43 40
 
44 41
     def carry(self, obj):
45
-        self._carried.append(obj)
42
+        self._carried = obj
46 43
         self._context.metas.states.add(self.get_id(), CARRYING)
47
-        #  TODO: On gere une liste de carried (mais pas juste la dessous). Ne gerer qu'un objet carried ?
48 44
         self._context.metas.value.set(CARRIED, self.get_id(), obj.get_id())
49
-        # TODO: pour le moment hardcode
45
+        # TODO: pour le moment hardcode, a gerer dans AntTakeBrainPart (callback en fct de ce qui est depose)
50 46
         if isinstance(obj, Food):
51 47
             self.get_brain().switch_to_mode(MOVE_MODE_GOHOME)
52
-            self.set_last_pheromone_point(PHEROMON_DIR_EXPLO, obj.get_position())
53 48
             self.get_movement_pheromone_gland().appose()
54 49
 
55 50
     def is_carrying(self):
56
-        if len(self._carried):
51
+        if self._carried:
57 52
             return True
58 53
         return False
59 54
 
60
-    # TODO: Est-ce ici que doit etre ce code ?
61 55
     def set_position(self, position):
62 56
         if self._position is not None and position != self._position:
63 57
             self._brain.host_moved()
64 58
         super().set_position(position)
65 59
         if self.is_carrying():
66
-            for obj_carried in self._carried:
67
-                obj_carried.set_position(position)
68
-
69
-    # TODO: N'est plus utiliser ! delete it !
70
-    def get_last_pheromone_point(self, pheromone_name):
71
-        if pheromone_name in self._last_pheromones_points:
72
-            return self._last_pheromones_points[pheromone_name]
73
-        return self._start_position
74
-
75
-    def set_last_pheromone_point(self, pheromone_name, position):
76
-        self._last_pheromones_points[pheromone_name] = position
77
-        self._context.metas.value.set(LAST_PHERMONES_POINTS, self.get_id(), self._last_pheromones_points)
60
+            self._carried.set_position(position)
78 61
 
79 62
     def initialize(self):
80 63
         super().initialize()
81
-        try:
82
-            self.get_movement_pheromone_gland().appose()
83
-        except BestPheromoneHere as best_pheromone_here:
84
-            pass
64
+        if self.get_movement_pheromone_gland().is_enabled():
65
+            try:
66
+                self.get_movement_pheromone_gland().appose()
67
+            except PheromoneException:
68
+                pass
85 69
 
86 70
     def get_colony(self):
87 71
         return self.get_collection()

+ 1 - 1
intelligine/synergy/object/ant/Pheromon.py View File

@@ -1,13 +1,13 @@
1 1
 from xyzworld.SynergyObject import SynergyObject as XyzSynergyObject
2 2
 
3 3
 
4
+# TODO: ne doit plus exister. Il est la pour le display uniquement. (pheromones ne sont pas des entites)
4 5
 class Pheromon(XyzSynergyObject):
5 6
 
6 7
     def __init__(self, collection, context):
7 8
         super().__init__(collection, context)
8 9
         self._direction = None
9 10
 
10
-    # TODO: direction ailleurs non ?
11 11
     def set_direction(self, direction):
12 12
         self._direction = direction
13 13
 

+ 1 - 0
intelligine/synergy/object/ant/PheromonExploration.py View File

@@ -1,5 +1,6 @@
1 1
 from intelligine.synergy.object.ant.Pheromon import Pheromon
2 2
 
3 3
 
4
+# TODO: ne doit plus exister. Il est la pour le display uniquement. (pheromones ne sont pas des entites)
4 5
 class PheromonExploration(Pheromon):
5 6
     pass

+ 1 - 0
intelligine/synergy/object/ant/PheromonHome.py View File

@@ -1,5 +1,6 @@
1 1
 from intelligine.synergy.object.ant.Pheromon import Pheromon
2 2
 
3 3
 
4
+# TODO: ne doit plus exister. Il est la pour le display uniquement. (pheromones ne sont pas des entites)
4 5
 class PheromonHome(Pheromon):
5 6
     pass

+ 0 - 9
run.py View File

@@ -2,15 +2,6 @@ from os import getcwd
2 2
 from sys import path as ppath
3 3
 ppath.insert(1,getcwd()+'/modules') # TODO: win32 compatibilite (python path)
4 4
 
5
-
6
-"""
7
-TODO:
8
- * Objects "dur" (terre); ne pas les avoir dans les objet a calculer sans cesse (INERTE)
9
- * SlightyTurn
10
-"""
11
-
12
-
13
-
14 5
 from synergine.core.Core import Core
15 6
 from config import config
16 7