Browse Source

refactorise event/action

Bastien Sevajol 9 years ago
parent
commit
13788b8fd9

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

@@ -50,3 +50,14 @@ class BrainPartAlreadyExist(BrainException):
50 50
 
51 51
 class DirectionException(Exception):
52 52
     pass
53
+
54
+
55
+class NearException(Exception):
56
+    pass
57
+
58
+
59
+class NearFound(NearException):
60
+    pass
61
+
62
+class NearNothingFound(NearException):
63
+    pass

+ 6 - 1
intelligine/cst.py View File

@@ -18,6 +18,9 @@ MOVE_MODE = IncrementedNamedInt.get('intelligine.basebug.move.mode')
18 18
 MOVE_MODE_EXPLO = IncrementedNamedInt.get('intelligine.basebug.move.mode.explo')
19 19
 MOVE_MODE_GOHOME = IncrementedNamedInt.get('intelligine.basebug.move.mode.gohome')
20 20
 
21
+TYPE = IncrementedNamedInt.get('intelligine.object.type')
22
+TYPE_RESOURCE_TRANSFORMABLE = IncrementedNamedInt.get('intelligine.object.type.resource.transformable')
23
+
21 24
 LAST_PHERMONES_POINTS = IncrementedNamedInt.get('intelligine.last_pheromones_points')
22 25
 
23 26
 PHEROMON_POSITIONS = IncrementedNamedInt.get('intelligine.phero.positions')
@@ -34,4 +37,6 @@ COL_TRANSPORTER_CARRYING = IncrementedNamedInt.get('intelligine.col.transporter_
34 37
 COL_TRANSPORTER_NOT_CARRYING = IncrementedNamedInt.get('intelligine.col.transporter_not_carrying')
35 38
 
36 39
 BRAIN_SCHEMA = IncrementedNamedInt.get('intelligine.brain_schema')
37
-BRAIN_PART_MOVE = IncrementedNamedInt.get('intelligine.brain.part.move')
40
+BRAIN_PART_MOVE = IncrementedNamedInt.get('intelligine.brain.part.move')
41
+BRAIN_PART_TAKE = IncrementedNamedInt.get('intelligine.brain.part.take')
42
+BRAIN_PART_PUT = IncrementedNamedInt.get('intelligine.brain.part.put')

+ 10 - 2
intelligine/simulation/object/brain/AntBrain.py View File

@@ -1,17 +1,22 @@
1 1
 from intelligine.simulation.object.brain.Brain import Brain
2
-from intelligine.simulation.object.brain.part.AntMoveBrainPart import AntMoveBrainPart
3
-from intelligine.cst import MOVE_MODE, MOVE_MODE_EXPLO, MOVE_MODE_GOHOME, PHEROMON_DIR_HOME, PHEROMON_DIR_EXPLO
2
+from intelligine.simulation.object.brain.part.move.AntMoveBrainPart import AntMoveBrainPart
3
+from intelligine.cst import MOVE_MODE, MOVE_MODE_EXPLO, MOVE_MODE_GOHOME, PHEROMON_DIR_HOME, PHEROMON_DIR_EXPLO, \
4
+    BRAIN_PART_TAKE
4 5
 from intelligine.cst import PHEROMONE_SEARCHING
5 6
 from intelligine.cst import BRAIN_PART_MOVE
7
+from intelligine.simulation.object.brain.part.take.AntTakeBrainPart import AntTakeBrainPart
6 8
 
7 9
 
8 10
 class AntBrain(Brain):
9 11
 
10 12
     _brain_part_move_class = AntMoveBrainPart
13
+    _brain_part_take_class = AntTakeBrainPart
11 14
 
12 15
     def __init__(self, context, host):
13 16
         super().__init__(context, host)
17
+        # TODO: Gerer les BrainPart avec un dictionnaire ?
14 18
         self._set_brain_part(BRAIN_PART_MOVE, self._get_move_brain_part_instance())
19
+        self._set_brain_part(BRAIN_PART_TAKE, self._get_take_brain_part_instance())
15 20
         self._movement_mode = MOVE_MODE_EXPLO
16 21
         self._distance_from_objective = 0  # TODO rename: distance_since_objective
17 22
         self._pheromone_searching = PHEROMON_DIR_EXPLO
@@ -19,6 +24,9 @@ class AntBrain(Brain):
19 24
     def _get_move_brain_part_instance(self):
20 25
         return self._brain_part_move_class()
21 26
 
27
+    def _get_take_brain_part_instance(self):
28
+        return self._brain_part_take_class()
29
+
22 30
     def switch_to_mode(self, mode):
23 31
         self._movement_mode = mode
24 32
         self._update_pheromone_gland(mode)

intelligine/simulation/object/brain/part/AntMoveBrainPart.py → intelligine/simulation/object/brain/part/move/AntMoveBrainPart.py View File

@@ -1,4 +1,4 @@
1
-from intelligine.simulation.object.brain.part.MoveBrainPart import MoveBrainPart
1
+from intelligine.simulation.object.brain.part.move.MoveBrainPart import MoveBrainPart
2 2
 from xyzworld.cst import POSITION
3 3
 from intelligine.core.exceptions import NoPheromone
4 4
 from intelligine.cst import PHEROMONE_SEARCHING, MOVE_MODE_EXPLO, COL_TRANSPORTER_NOT_CARRYING, COL_TRANSPORTER_CARRYING

intelligine/simulation/object/brain/part/MoveBrainPart.py → intelligine/simulation/object/brain/part/move/MoveBrainPart.py View File


+ 34 - 0
intelligine/simulation/object/brain/part/take/AntTakeBrainPart.py View File

@@ -0,0 +1,34 @@
1
+from intelligine.simulation.object.brain.part.take.TakeBrainPart import TakeBrainPart
2
+from intelligine.synergy.object.ressource.Ressource import Resource
3
+from intelligine.cst import MOVE_MODE_EXPLO, MOVE_MODE, TYPE_RESOURCE_TRANSFORMABLE, \
4
+    TYPE, MOVE_MODE_GOHOME, PHEROMON_DIR_EXPLO
5
+
6
+
7
+class AntTakeBrainPart(TakeBrainPart):
8
+
9
+    # TODO: methode __nit_ pour la classe ?
10
+    _take = {
11
+        MOVE_MODE_EXPLO: [TYPE_RESOURCE_TRANSFORMABLE],
12
+    }
13
+
14
+    @classmethod
15
+    def can_take(cls, context, object_id, object_to_take_id):
16
+        if not cls._object_is_takable_type(context, object_id, object_to_take_id):
17
+            return False
18
+        return True
19
+
20
+    @classmethod
21
+    def _object_is_takable_type(cls, context, object_id, object_to_take_id):
22
+        move_mode = context.metas.value.get(MOVE_MODE, object_id)
23
+        for takable_type in cls._take[move_mode]:
24
+            if context.metas.list.have(TYPE, takable_type, object_to_take_id, allow_empty=True):
25
+                return True
26
+        return False
27
+
28
+    def done(self, obj, take_object, context):
29
+        # TODO: Ranger ca ? Truc plus dynamique/configurable ?
30
+        if isinstance(take_object, Resource):
31
+            obj.get_brain().switch_to_mode(MOVE_MODE_GOHOME)
32
+            # TODO: set_last_pheromone_point ca devrait pas etre dans get_movement_pheromone_gland().appose() ?
33
+            obj.set_last_pheromone_point(PHEROMON_DIR_EXPLO, obj.get_position())
34
+            obj.get_movement_pheromone_gland().appose()

+ 10 - 0
intelligine/simulation/object/brain/part/take/TakeBrainPart.py View File

@@ -0,0 +1,10 @@
1
+from intelligine.simulation.object.brain.part.BrainPart import BrainPart
2
+
3
+
4
+class TakeBrainPart(BrainPart):
5
+
6
+    _take = {}
7
+
8
+    @classmethod
9
+    def can_take(cls, context, object_to_take_id):
10
+        return False

+ 6 - 2
intelligine/synergy/event/attack/NearAttackableEvent.py View File

@@ -1,3 +1,4 @@
1
+from intelligine.core.exceptions import NearNothingFound
1 2
 from synergine.core.exceptions import NotConcernedEvent
2 3
 from intelligine.synergy.event.src.NearEvent import NearEvent
3 4
 from xyzworld.mechanism.ArroundMechanism import ArroundMechanism
@@ -17,7 +18,10 @@ class NearAttackableEvent(NearEvent):
17 18
     def _prepare(self, object_id, context, parameters={}):
18 19
         obj_colony_id = context.metas.value.get(COLONY, object_id)
19 20
         filter = lambda near_object_id, context: obj_colony_id != context.metas.value.get(COLONY, near_object_id)
20
-        self.map(context, parameters, stop_at_first=True, filter=filter)
21
-        if self._near_name not in parameters:
21
+
22
+        try:
23
+            self.map(context, parameters, stop_at_first=True, filter=filter)
24
+        except NearNothingFound:
22 25
             raise NotConcernedEvent()
26
+
23 27
         return parameters

+ 5 - 2
intelligine/synergy/event/src/NearEvent.py View File

@@ -1,3 +1,4 @@
1
+from intelligine.core.exceptions import NearFound, NearNothingFound
1 2
 from synergine.synergy.event.Event import Event
2 3
 from xyzworld.mechanism.ArroundMechanism import ArroundMechanism
3 4
 
@@ -11,11 +12,13 @@ class NearEvent(Event):
11 12
         super().__init__(actions)
12 13
         self._mechanism = ArroundMechanism
13 14
 
14
-    def map(self, context, parameters, stop_at_first = False, filter = lambda near_object_id, context: True):
15
+    # TODO: parameters en entre/sortie c pas bon ca
16
+    def map(self, context, parameters, stop_at_first=False, filter=lambda near_object_id, context: True):
15 17
         for near_object_id in parameters['objects_ids_near']:
16 18
             if self._near_map(near_object_id, context) and filter(near_object_id, context):
17 19
                 if self._near_name not in parameters:
18 20
                     parameters[self._near_name] = []
19 21
                 parameters[self._near_name].append(near_object_id)
20 22
                 if stop_at_first:
21
-                    return
23
+                    return
24
+        raise NearNothingFound()

+ 2 - 0
intelligine/synergy/event/transport/PutableAction.py View File

@@ -1,3 +1,4 @@
1
+from intelligine.synergy.event.move.MoveAction import MoveAction
1 2
 from synergine.synergy.event.Action import Action
2 3
 from intelligine.synergy.event.transport.PutableEvent import PutableEvent
3 4
 from intelligine.cst import CANT_CARRY_STILL
@@ -8,6 +9,7 @@ from synergine.synergy.event.exception.ActionAborted import ActionAborted
8 9
 class PutableAction(Action):
9 10
 
10 11
     _listen = PutableEvent
12
+    _depend = [MoveAction]
11 13
 
12 14
     def __init__(self, object_id, parameters):
13 15
         super().__init__(object_id, parameters)

+ 9 - 7
intelligine/synergy/event/transport/TakeableAction.py View File

@@ -1,12 +1,15 @@
1 1
 from intelligine.synergy.event.move.MoveAction import MoveAction
2 2
 from synergine.synergy.event.Action import Action
3 3
 from intelligine.synergy.event.transport.TakeableEvent import TakeableEvent
4
-from intelligine.cst import CANT_PUT_STILL
4
+from intelligine.cst import CANT_PUT_STILL, BRAIN_SCHEMA, BRAIN_PART_TAKE
5 5
 from synergine.synergy.event.exception.ActionAborted import ActionAborted
6 6
 
7 7
 
8 8
 class TakeableAction(Action):
9
-
9
+    """
10
+    TODO: Prendre le premier prenable, interrompre la recherche si trouve
11
+          si au run de l'action objet non prenable, tant pis. ActionAborted.
12
+    """
10 13
     _listen = TakeableEvent
11 14
     _depend = [MoveAction]
12 15
 
@@ -14,21 +17,20 @@ class TakeableAction(Action):
14 17
         super().__init__(object_id, parameters)
15 18
 
16 19
     def prepare(self, context):
20
+        # TODO: C l'event qui doit preparer les donnees
17 21
         pass
18 22
 
19 23
     def run(self, obj, context, synergy_manager):
20
-        # TODO: TEST
21
-        # TODO: Enlever le state de transportable a ce qui est transporte
22
-        # ?! Comment gerer lorsque deux obj vont vouloir transporter le meme objet ? process !
23
-        obj_id_transportable = self._parameters['objects_ids_transportable'][0]
24
+        obj_id_transportable = self._parameters[TakeableEvent.PARAM_TAKE]
24 25
         obj_transportable = synergy_manager.get_map().get_object(obj_id_transportable)
25
-        if obj_transportable.is_carried():
26
+        if obj_transportable.is_carried():  # TODO: is_takable
26 27
             raise ActionAborted()
27 28
         try:
28 29
             obj_carried = obj_transportable.get_what_carry()
29 30
             obj_carried.set_carried_by(obj)
30 31
             obj.carry(obj_carried)
31 32
             context.metas.value.set(CANT_PUT_STILL, obj.get_id(), 5)
33
+            obj.get_brain().get_part(BRAIN_PART_TAKE).done(obj, obj_carried, context)
32 34
         except ValueError: # Une NotCarriableError serais pus approprie
33 35
             # TODO: tmp? Si on as pas pu le porter c'est qu'il vient d'etre porte par une autre.
34 36
             pass

+ 24 - 5
intelligine/synergy/event/transport/TakeableEvent.py View File

@@ -1,11 +1,13 @@
1
+from intelligine.core.exceptions import NearNothingFound
1 2
 from synergine.core.exceptions import NotConcernedEvent
2 3
 from intelligine.synergy.event.src.NearEvent import NearEvent
3 4
 from xyzworld.mechanism.ArroundMechanism import ArroundMechanism
4
-from intelligine.cst import TRANSPORTABLE, CANT_CARRY_STILL, COL_TRANSPORTER_NOT_CARRYING
5
+from intelligine.cst import TRANSPORTABLE, CANT_CARRY_STILL, COL_TRANSPORTER_NOT_CARRYING, BRAIN_SCHEMA, BRAIN_PART_TAKE
5 6
 
6 7
 
7 8
 class TakeableEvent(NearEvent):
8 9
 
10
+    PARAM_TAKE = 'take'
9 11
     concern = COL_TRANSPORTER_NOT_CARRYING
10 12
     _near_name = 'objects_ids_transportable'
11 13
     _near_map = lambda self, near_object_id, context: context.metas.states.have(near_object_id, TRANSPORTABLE)
@@ -15,9 +17,26 @@ class TakeableEvent(NearEvent):
15 17
         self._mechanism = ArroundMechanism
16 18
 
17 19
     def _prepare(self, object_id, context, parameters={}):
18
-        if context.metas.value.get(CANT_CARRY_STILL, object_id, allow_empty=True):
20
+        if not self._can_carry(object_id, context):
19 21
             raise NotConcernedEvent()
20
-        self.map(context, parameters, stop_at_first=True)
21
-        if self._near_name not in parameters:
22
+
23
+        try:
24
+            self.map(context, parameters, stop_at_first=True)
25
+        except NearNothingFound:
26
+            raise NotConcernedEvent()
27
+
28
+        if not self._object_can_take(object_id, context, parameters[self._near_name][0]):
22 29
             raise NotConcernedEvent()
23
-        return parameters
30
+
31
+        parameters[self.PARAM_TAKE] = parameters[self._near_name][0]
32
+        return parameters
33
+
34
+    @staticmethod
35
+    def _can_carry(object_id, context):
36
+        return not context.metas.value.get(CANT_CARRY_STILL, object_id, allow_empty=True)
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]
42
+        return object_take_brain_part.can_take(context, object_id, object_to_take_id)

+ 5 - 3
intelligine/synergy/object/Food.py View File

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

+ 5 - 0
intelligine/synergy/object/ressource/Ressource.py View File

@@ -0,0 +1,5 @@
1
+from intelligine.synergy.object.Transportable import Transportable
2
+
3
+
4
+class Resource(Transportable):
5
+    pass

+ 10 - 0
intelligine/tests/src/event/MoveEvent.py View File

@@ -0,0 +1,10 @@
1
+from intelligine.synergy.event.move.MoveEvent import MoveEvent as BaseMoveEvent
2
+from intelligine.synergy.event.move.direction import NORTH
3
+
4
+
5
+class MoveEvent(BaseMoveEvent):
6
+
7
+    force_direction = lambda self, object_id, context: NORTH
8
+
9
+    def _get_direction(self, object_id, context):
10
+        return self.force_direction(object_id, context)