Browse Source

Move move logic to brain parts

Bastien Sevajol 9 years ago
parent
commit
23d8656a43

+ 7 - 1
intelligine/core/exceptions.py View File

@@ -25,4 +25,10 @@ class BestPheromoneHere(PheromoneException):
25 25
         self._best_distance = best_distance
26 26
 
27 27
     def get_best_distance(self):
28
-        return self._best_distance
28
+        return self._best_distance
29
+
30
+class BrainException(Exception):
31
+    pass
32
+
33
+class BrainPartAlreadyExist(BrainException):
34
+    pass

+ 3 - 0
intelligine/cst.py View File

@@ -34,3 +34,6 @@ COL_FIGHTER = IncrementedNamedInt.get('intelligine.col.walker')
34 34
 COL_TRANSPORTER = IncrementedNamedInt.get('intelligine.col.transporter')
35 35
 COL_TRANSPORTER_CARRYING = IncrementedNamedInt.get('intelligine.col.transporter_carrying')
36 36
 COL_TRANSPORTER_NOT_CARRYING = IncrementedNamedInt.get('intelligine.col.transporter_not_carrying')
37
+
38
+BRAIN_SCHEMA = IncrementedNamedInt.get('intelligine.brain_schema')
39
+BRAIN_PART_MOVE = IncrementedNamedInt.get('intelligine.brain.part.move')

+ 8 - 0
intelligine/simulation/object/brain/AntBrain.py View File

@@ -1,16 +1,24 @@
1 1
 from intelligine.simulation.object.brain.Brain import Brain
2
+from intelligine.simulation.object.brain.part.AntMoveBrainPart import AntMoveBrainPart
2 3
 from intelligine.cst import MOVE_MODE, MOVE_MODE_EXPLO, MOVE_MODE_GOHOME, PHEROMON_DIR_HOME, PHEROMON_DIR_EXPLO
3 4
 from intelligine.cst import PHEROMONE_SEARCHING
5
+from intelligine.cst import BRAIN_PART_MOVE
4 6
 
5 7
 
6 8
 class AntBrain(Brain):
7 9
 
10
+    _brain_part_move_class = AntMoveBrainPart
11
+
8 12
     def __init__(self, context, host):
9 13
         super().__init__(context, host)
14
+        self._set_brain_part(BRAIN_PART_MOVE, self._get_move_brain_part_instance())
10 15
         self._movement_mode = MOVE_MODE_EXPLO
11 16
         self._distance_from_objective = 0  # TODO rename: distance_since_objective
12 17
         self._pheromone_searching = PHEROMON_DIR_EXPLO
13 18
 
19
+    def _get_move_brain_part_instance(self):
20
+        return self._brain_part_move_class()
21
+
14 22
     def switch_to_mode(self, mode):
15 23
         self._movement_mode = mode
16 24
         self._update_pheromone_gland(mode)

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

@@ -1,5 +1,28 @@
1
+from intelligine.core.exceptions import BrainPartAlreadyExist
2
+from intelligine.cst import BRAIN_SCHEMA
3
+
4
+
1 5
 class Brain():
2 6
 
7
+    _brain_part_class = {}
8
+
3 9
     def __init__(self, context, host):
4 10
         self._context = context
5
-        self._host = host
11
+        self._host = host
12
+        self._schema = {}
13
+        self._parts = {}
14
+
15
+    def _set_brain_part(self, name, brain_part, replace=False):
16
+        if name in self._parts and not replace:
17
+            raise BrainPartAlreadyExist()
18
+        self._parts[name] = brain_part
19
+        self._update_schema()
20
+
21
+    def get_part(self, name):
22
+        return self._parts[name]
23
+
24
+    def _update_schema(self):
25
+        self._schema = {}
26
+        for part_name in self._parts:
27
+            self._schema[part_name] = self._parts[part_name].__class__
28
+        self._context.metas.value.set(BRAIN_SCHEMA, self._host.get_id(), self._schema)

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

@@ -1,25 +1,28 @@
1
-from intelligine.synergy.event.move.MoveAction import MoveAction
2
-from intelligine.cst import PHEROMONE_SEARCHING, MOVE_MODE_EXPLO
3
-from intelligine.cst import COL_TRANSPORTER_NOT_CARRYING, COL_TRANSPORTER_CARRYING
1
+from intelligine.simulation.object.brain.part.MoveBrainPart import MoveBrainPart
2
+from xyzworld.cst import POSITION
4 3
 from intelligine.core.exceptions import NoPheromone, BestPheromoneHere
4
+from intelligine.cst import PHEROMONE_SEARCHING, MOVE_MODE_EXPLO, COL_TRANSPORTER_NOT_CARRYING, COL_TRANSPORTER_CARRYING
5 5
 from intelligine.simulation.pheromone.DirectionPheromone import DirectionPheromone
6 6
 
7 7
 
8
-class PheromoneMoveAction(MoveAction):
8
+class AntMoveBrainPart(MoveBrainPart):
9 9
 
10
-    def _get_prepared_direction(self, context, object_point):
10
+    @classmethod
11
+    def get_direction(cls, context, object_id):
11 12
         try:
12
-            return self._get_direction_with_pheromones(context, object_point)
13
+            return cls._get_direction_with_pheromones(context, object_id)
13 14
         except NoPheromone:
14
-            return super()._get_prepared_direction(context, object_point)
15
+            return super().get_direction(context, object_id)
15 16
 
16
-    def _get_direction_with_pheromones(self, context, object_point):
17
-        pheromone_type = context.metas.value.get(PHEROMONE_SEARCHING, self._object_id)
17
+    @classmethod
18
+    def _get_direction_with_pheromones(cls, context, object_id):
19
+        object_point = context.metas.value.get(POSITION, object_id)
20
+        pheromone_type = context.metas.value.get(PHEROMONE_SEARCHING, object_id)
18 21
         try:
19
-            direction = self._get_pheromone_direction_for_point(context, object_point, pheromone_type)
22
+            direction = cls._get_pheromone_direction_for_point(context, object_point, pheromone_type)
20 23
         except NoPheromone:
21 24
             try:
22
-                direction = self._get_direction_of_pheromone(context, object_point, pheromone_type)
25
+                direction = cls._get_direction_of_pheromone(context, object_point, pheromone_type)
23 26
             except NoPheromone:
24 27
                 raise
25 28
         return direction
@@ -40,12 +43,12 @@ class PheromoneMoveAction(MoveAction):
40 43
         except NoPheromone as err:
41 44
             raise err
42 45
 
43
-    def _apply_move(self, obj, context):
44
-        super()._apply_move(obj, context)
46
+    def done(self, obj, context):
47
+        super().done(obj, context)
45 48
         self._appose_pheromone(obj, context)
46 49
 
47 50
         # TEST: le temps de tout tester
48
-        if self._move_to_point == obj.get_colony().get_start_position() and obj.is_carrying():
51
+        if obj.get_position() == obj.get_colony().get_start_position() and obj.is_carrying():
49 52
             obj_transported = obj.get_carried()
50 53
             obj_transported.set_carried_by(None)
51 54
             obj.put_carry(obj_transported, (-1, 0, 0))
@@ -64,4 +67,3 @@ class PheromoneMoveAction(MoveAction):
64 67
         except BestPheromoneHere as best_pheromone_here:
65 68
             obj.get_brain().set_distance_from_objective(best_pheromone_here.get_best_distance())
66 69
 
67
-

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

@@ -0,0 +1,4 @@
1
+class BrainPart():
2
+
3
+    def done(self, obj, context):
4
+        pass

+ 38 - 0
intelligine/simulation/object/brain/part/MoveBrainPart.py View File

@@ -0,0 +1,38 @@
1
+from intelligine.simulation.object.brain.part.BrainPart import BrainPart
2
+from intelligine.synergy.event.move.direction import directions_same_level, directions_slighty
3
+from random import randint, choice, randrange
4
+from intelligine.cst import BLOCKED_SINCE, PREVIOUS_DIRECTION
5
+
6
+
7
+class MoveBrainPart(BrainPart):
8
+
9
+    @classmethod
10
+    def get_direction(cls, context, object_id):
11
+        return cls._get_random_direction(context, object_id)
12
+
13
+    @classmethod
14
+    def _get_random_direction(cls, context, object_id):
15
+        try:
16
+            blocked_since = context.metas.value.get(BLOCKED_SINCE, object_id)
17
+        except KeyError:
18
+            blocked_since = 0
19
+        direction_name = None
20
+        if blocked_since <= 3:  #TODO: config
21
+            try:
22
+                previous_direction = context.metas.value.get(PREVIOUS_DIRECTION, object_id)
23
+                # TODO: Faut mettre ca en plus propre (proba d'aller tou droit, config, etc)
24
+                if randrange(100) < 75:  # 75% de change d'aller tout droit
25
+                    # Dans le futur: les fourmis vont moins tout droit quand elle se croient et se touche
26
+                    return previous_direction
27
+
28
+                directions_list = directions_slighty[previous_direction]
29
+                # TODO: TMP tant que 1 niveau (z)
30
+                directions_list = [direction for direction in directions_list if direction > 9 and direction < 19]
31
+                direction_name = choice(directions_list)
32
+            except KeyError:
33
+                pass
34
+
35
+        if not direction_name:
36
+            direction_name = randint(directions_same_level[0], directions_same_level[1])
37
+
38
+        return direction_name

+ 2 - 2
intelligine/synergy/Colony.py View File

@@ -1,5 +1,5 @@
1 1
 from synergine.synergy.collection.SynergyCollection import SynergyCollection
2
-from intelligine.synergy.event.move.PheromoneMoveAction import PheromoneMoveAction
2
+from intelligine.synergy.event.move.MoveAction import MoveAction
3 3
 from intelligine.synergy.event.attack.NearAttackableAction import NearAttackableAction
4 4
 from intelligine.synergy.event.transport.TakeableAction import TakeableAction
5 5
 from intelligine.synergy.event.transport.PutableAction import PutableAction
@@ -10,7 +10,7 @@ class Colony(SynergyCollection):
10 10
 
11 11
     def __init__(self, configuration):
12 12
         super().__init__(configuration)
13
-        self._actions = [PheromoneMoveAction, NearAttackableAction, TakeableAction, PutableAction,
13
+        self._actions = [MoveAction, NearAttackableAction, TakeableAction, PutableAction,
14 14
                          CycleAction]
15 15
         self._start_position = configuration.get_start_position()
16 16
 

+ 10 - 33
intelligine/synergy/event/move/MoveAction.py View File

@@ -1,10 +1,8 @@
1 1
 from synergine.synergy.event.Action import Action
2 2
 from intelligine.synergy.event.move.MoveEvent import MoveEvent
3
-from random import randint, choice, randrange
4 3
 from synergine.synergy.event.exception.ActionAborted import ActionAborted
5 4
 from xyzworld.cst import POSITION
6
-from intelligine.cst import PREVIOUS_DIRECTION, BLOCKED_SINCE
7
-from intelligine.synergy.event.move.direction import directions_same_level, directions_slighty
5
+from intelligine.cst import PREVIOUS_DIRECTION, BLOCKED_SINCE, BRAIN_PART_MOVE, BRAIN_SCHEMA
8 6
 from intelligine.synergy.event.move.direction import get_position_with_direction_decal
9 7
 
10 8
 
@@ -19,11 +17,13 @@ class MoveAction(Action):
19 17
 
20 18
     def prepare(self, context):
21 19
         object_point = context.metas.value.get(POSITION, self._object_id)
22
-        direction = self._get_prepared_direction(context, object_point)
20
+        direction = self._get_prepared_direction(context)
23 21
         self._set_prepared_direction(context, object_point, direction)
24 22
 
25
-    def _get_prepared_direction(self, context, object_point):
26
-        return self._get_random_direction(context)
23
+    def _get_prepared_direction(self, context):
24
+        object_brain_schema = context.metas.value.get(BRAIN_SCHEMA, self._object_id)
25
+        object_move_brain_part = object_brain_schema[BRAIN_PART_MOVE]
26
+        return object_move_brain_part.get_direction(context, self._object_id)
27 27
 
28 28
     def _set_prepared_direction(self, context, object_point, direction):
29 29
         move_to_point = get_position_with_direction_decal(direction, object_point)
@@ -34,32 +34,6 @@ class MoveAction(Action):
34 34
             # TODO: mettre self._dont_move = True ?
35 35
             pass
36 36
 
37
-    def _get_random_direction(self, context):
38
-        try:
39
-            blocked_since = context.metas.value.get(BLOCKED_SINCE, self._object_id)
40
-        except KeyError:
41
-            blocked_since = 0
42
-        direction_name = None
43
-        if blocked_since <= 3:  #TODO: config
44
-            try:
45
-                previous_direction = context.metas.value.get(PREVIOUS_DIRECTION, self._object_id)
46
-                # TODO: Faut mettre ca en plus propre (proba d'aller tou droit, config, etc)
47
-                if randrange(100) < 75:  # 75% de change d'aller tout droit
48
-                    # Dans le futur: les fourmis vont moins tout droit quand elle se croient et se touche
49
-                    return previous_direction
50
-
51
-                directions_list = directions_slighty[previous_direction]
52
-                # TODO: TMP tant que 1 niveau (z)
53
-                directions_list = [direction for direction in directions_list if direction > 9 and direction < 19]
54
-                direction_name = choice(directions_list)
55
-            except KeyError:
56
-                pass
57
-
58
-        if not direction_name:
59
-            direction_name = randint(directions_same_level[0], directions_same_level[1])
60
-
61
-        return direction_name
62
-
63 37
     @staticmethod
64 38
     def _direction_point_is_possible(context, direction_point):
65 39
         return context.position_is_penetrable(direction_point)
@@ -77,5 +51,8 @@ class MoveAction(Action):
77 51
             raise ActionAborted()
78 52
 
79 53
         obj.set_position(self._move_to_point)
54
+        obj.get_brain().get_part(BRAIN_PART_MOVE).done(obj, context)
55
+
56
+        # TODO: Ces metas update dans ant ?
80 57
         context.metas.value.set(PREVIOUS_DIRECTION, self._object_id, self._move_to_direction)
81
-        context.metas.value.set(BLOCKED_SINCE, self._object_id, 0)
58
+        context.metas.value.set(BLOCKED_SINCE, self._object_id, 0)

+ 2 - 2
intelligine/tests/simulation/mode/TestChangeMode.py View File

@@ -10,7 +10,7 @@ from intelligine.tests.simulation.mode.Base import Base
10 10
 from intelligine.synergy.Colony import Colony
11 11
 from intelligine.synergy.Simulation import Simulation
12 12
 from intelligine.synergy.ColonyConfiguration import ColonyConfiguration
13
-from intelligine.synergy.event.move.PheromoneMoveAction import PheromoneMoveAction
13
+from intelligine.synergy.event.move.MoveAction import MoveAction
14 14
 from intelligine.synergy.event.move.direction import NORTH, SOUTH
15 15
 from intelligine.tests.src.event.MoveAction import MoveAction as TestMoveAction
16 16
 from synergine.synergy.collection.SynergyCollection import SynergyCollection
@@ -43,7 +43,7 @@ class TestChangeMode(Base):
43 43
         class TestColony(Colony):
44 44
             def __init__(self, configuration):
45 45
                 super().__init__(configuration)
46
-                self._actions.remove(PheromoneMoveAction)
46
+                self._actions.remove(MoveAction)
47 47
                 TestMoveAction.force_direction = test_case._force_move
48 48
                 self._actions.append(TestMoveAction)
49 49
         return TestColony(self._get_colony_configuration())

+ 4 - 7
intelligine/tests/src/event/MoveAction.py View File

@@ -1,13 +1,10 @@
1
-from intelligine.synergy.event.move.PheromoneMoveAction import PheromoneMoveAction as BaseMoveAction
1
+from intelligine.synergy.event.move.MoveAction import MoveAction as BaseMoveAction
2 2
 from intelligine.synergy.event.move.direction import NORTH
3 3
 
4 4
 
5 5
 class MoveAction(BaseMoveAction):
6 6
 
7
-    force_direction = lambda self, context, object_point: NORTH
7
+    force_direction = lambda self, context, object_id: NORTH
8 8
 
9
-    def _get_direction_with_pheromones(self, context, object_point):
10
-        return self.force_direction(context, object_point)
11
-
12
-    # def _get_random_direction(self, context):
13
-    #     return self.force_direction
9
+    def _get_prepared_direction(self, context):
10
+        return self.force_direction(context, self._object_id)