Browse Source

refactorise event/action

Bastien Sevajol 9 years ago
parent
commit
13788b8fd9

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

50
 
50
 
51
 class DirectionException(Exception):
51
 class DirectionException(Exception):
52
     pass
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
 MOVE_MODE_EXPLO = IncrementedNamedInt.get('intelligine.basebug.move.mode.explo')
18
 MOVE_MODE_EXPLO = IncrementedNamedInt.get('intelligine.basebug.move.mode.explo')
19
 MOVE_MODE_GOHOME = IncrementedNamedInt.get('intelligine.basebug.move.mode.gohome')
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
 LAST_PHERMONES_POINTS = IncrementedNamedInt.get('intelligine.last_pheromones_points')
24
 LAST_PHERMONES_POINTS = IncrementedNamedInt.get('intelligine.last_pheromones_points')
22
 
25
 
23
 PHEROMON_POSITIONS = IncrementedNamedInt.get('intelligine.phero.positions')
26
 PHEROMON_POSITIONS = IncrementedNamedInt.get('intelligine.phero.positions')
34
 COL_TRANSPORTER_NOT_CARRYING = IncrementedNamedInt.get('intelligine.col.transporter_not_carrying')
37
 COL_TRANSPORTER_NOT_CARRYING = IncrementedNamedInt.get('intelligine.col.transporter_not_carrying')
35
 
38
 
36
 BRAIN_SCHEMA = IncrementedNamedInt.get('intelligine.brain_schema')
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
 from intelligine.simulation.object.brain.Brain import Brain
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
 from intelligine.cst import PHEROMONE_SEARCHING
5
 from intelligine.cst import PHEROMONE_SEARCHING
5
 from intelligine.cst import BRAIN_PART_MOVE
6
 from intelligine.cst import BRAIN_PART_MOVE
7
+from intelligine.simulation.object.brain.part.take.AntTakeBrainPart import AntTakeBrainPart
6
 
8
 
7
 
9
 
8
 class AntBrain(Brain):
10
 class AntBrain(Brain):
9
 
11
 
10
     _brain_part_move_class = AntMoveBrainPart
12
     _brain_part_move_class = AntMoveBrainPart
13
+    _brain_part_take_class = AntTakeBrainPart
11
 
14
 
12
     def __init__(self, context, host):
15
     def __init__(self, context, host):
13
         super().__init__(context, host)
16
         super().__init__(context, host)
17
+        # TODO: Gerer les BrainPart avec un dictionnaire ?
14
         self._set_brain_part(BRAIN_PART_MOVE, self._get_move_brain_part_instance())
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
         self._movement_mode = MOVE_MODE_EXPLO
20
         self._movement_mode = MOVE_MODE_EXPLO
16
         self._distance_from_objective = 0  # TODO rename: distance_since_objective
21
         self._distance_from_objective = 0  # TODO rename: distance_since_objective
17
         self._pheromone_searching = PHEROMON_DIR_EXPLO
22
         self._pheromone_searching = PHEROMON_DIR_EXPLO
19
     def _get_move_brain_part_instance(self):
24
     def _get_move_brain_part_instance(self):
20
         return self._brain_part_move_class()
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
     def switch_to_mode(self, mode):
30
     def switch_to_mode(self, mode):
23
         self._movement_mode = mode
31
         self._movement_mode = mode
24
         self._update_pheromone_gland(mode)
32
         self._update_pheromone_gland(mode)

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

1
-from intelligine.simulation.object.brain.part.MoveBrainPart import MoveBrainPart
1
+from intelligine.simulation.object.brain.part.move.MoveBrainPart import MoveBrainPart
2
 from xyzworld.cst import POSITION
2
 from xyzworld.cst import POSITION
3
 from intelligine.core.exceptions import NoPheromone
3
 from intelligine.core.exceptions import NoPheromone
4
 from intelligine.cst import PHEROMONE_SEARCHING, MOVE_MODE_EXPLO, COL_TRANSPORTER_NOT_CARRYING, COL_TRANSPORTER_CARRYING
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

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

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
+from intelligine.core.exceptions import NearNothingFound
1
 from synergine.core.exceptions import NotConcernedEvent
2
 from synergine.core.exceptions import NotConcernedEvent
2
 from intelligine.synergy.event.src.NearEvent import NearEvent
3
 from intelligine.synergy.event.src.NearEvent import NearEvent
3
 from xyzworld.mechanism.ArroundMechanism import ArroundMechanism
4
 from xyzworld.mechanism.ArroundMechanism import ArroundMechanism
17
     def _prepare(self, object_id, context, parameters={}):
18
     def _prepare(self, object_id, context, parameters={}):
18
         obj_colony_id = context.metas.value.get(COLONY, object_id)
19
         obj_colony_id = context.metas.value.get(COLONY, object_id)
19
         filter = lambda near_object_id, context: obj_colony_id != context.metas.value.get(COLONY, near_object_id)
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
             raise NotConcernedEvent()
25
             raise NotConcernedEvent()
26
+
23
         return parameters
27
         return parameters

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

1
+from intelligine.core.exceptions import NearFound, NearNothingFound
1
 from synergine.synergy.event.Event import Event
2
 from synergine.synergy.event.Event import Event
2
 from xyzworld.mechanism.ArroundMechanism import ArroundMechanism
3
 from xyzworld.mechanism.ArroundMechanism import ArroundMechanism
3
 
4
 
11
         super().__init__(actions)
12
         super().__init__(actions)
12
         self._mechanism = ArroundMechanism
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
         for near_object_id in parameters['objects_ids_near']:
17
         for near_object_id in parameters['objects_ids_near']:
16
             if self._near_map(near_object_id, context) and filter(near_object_id, context):
18
             if self._near_map(near_object_id, context) and filter(near_object_id, context):
17
                 if self._near_name not in parameters:
19
                 if self._near_name not in parameters:
18
                     parameters[self._near_name] = []
20
                     parameters[self._near_name] = []
19
                 parameters[self._near_name].append(near_object_id)
21
                 parameters[self._near_name].append(near_object_id)
20
                 if stop_at_first:
22
                 if stop_at_first:
21
-                    return
23
+                    return
24
+        raise NearNothingFound()

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

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

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

1
 from intelligine.synergy.event.move.MoveAction import MoveAction
1
 from intelligine.synergy.event.move.MoveAction import MoveAction
2
 from synergine.synergy.event.Action import Action
2
 from synergine.synergy.event.Action import Action
3
 from intelligine.synergy.event.transport.TakeableEvent import TakeableEvent
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
 from synergine.synergy.event.exception.ActionAborted import ActionAborted
5
 from synergine.synergy.event.exception.ActionAborted import ActionAborted
6
 
6
 
7
 
7
 
8
 class TakeableAction(Action):
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
     _listen = TakeableEvent
13
     _listen = TakeableEvent
11
     _depend = [MoveAction]
14
     _depend = [MoveAction]
12
 
15
 
14
         super().__init__(object_id, parameters)
17
         super().__init__(object_id, parameters)
15
 
18
 
16
     def prepare(self, context):
19
     def prepare(self, context):
20
+        # TODO: C l'event qui doit preparer les donnees
17
         pass
21
         pass
18
 
22
 
19
     def run(self, obj, context, synergy_manager):
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
         obj_transportable = synergy_manager.get_map().get_object(obj_id_transportable)
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
             raise ActionAborted()
27
             raise ActionAborted()
27
         try:
28
         try:
28
             obj_carried = obj_transportable.get_what_carry()
29
             obj_carried = obj_transportable.get_what_carry()
29
             obj_carried.set_carried_by(obj)
30
             obj_carried.set_carried_by(obj)
30
             obj.carry(obj_carried)
31
             obj.carry(obj_carried)
31
             context.metas.value.set(CANT_PUT_STILL, obj.get_id(), 5)
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
         except ValueError: # Une NotCarriableError serais pus approprie
34
         except ValueError: # Une NotCarriableError serais pus approprie
33
             # TODO: tmp? Si on as pas pu le porter c'est qu'il vient d'etre porte par une autre.
35
             # TODO: tmp? Si on as pas pu le porter c'est qu'il vient d'etre porte par une autre.
34
             pass
36
             pass

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

1
+from intelligine.core.exceptions import NearNothingFound
1
 from synergine.core.exceptions import NotConcernedEvent
2
 from synergine.core.exceptions import NotConcernedEvent
2
 from intelligine.synergy.event.src.NearEvent import NearEvent
3
 from intelligine.synergy.event.src.NearEvent import NearEvent
3
 from xyzworld.mechanism.ArroundMechanism import ArroundMechanism
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
 class TakeableEvent(NearEvent):
8
 class TakeableEvent(NearEvent):
8
 
9
 
10
+    PARAM_TAKE = 'take'
9
     concern = COL_TRANSPORTER_NOT_CARRYING
11
     concern = COL_TRANSPORTER_NOT_CARRYING
10
     _near_name = 'objects_ids_transportable'
12
     _near_name = 'objects_ids_transportable'
11
     _near_map = lambda self, near_object_id, context: context.metas.states.have(near_object_id, TRANSPORTABLE)
13
     _near_map = lambda self, near_object_id, context: context.metas.states.have(near_object_id, TRANSPORTABLE)
15
         self._mechanism = ArroundMechanism
17
         self._mechanism = ArroundMechanism
16
 
18
 
17
     def _prepare(self, object_id, context, parameters={}):
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
             raise NotConcernedEvent()
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
             raise NotConcernedEvent()
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
-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
     def __init__(self, collection, context):
7
     def __init__(self, collection, context):
8
         super().__init__(collection, context)
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
         context.metas.states.add(self.get_id(), TRANSPORTABLE)
11
         context.metas.states.add(self.get_id(), TRANSPORTABLE)
10
 
12
 
11
     def get_what_carry(self):
13
     def get_what_carry(self):

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

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

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)