Browse Source

Merge branch 'dev/mol'

Bastien Sevajol 8 years ago
parent
commit
7d42d10e40
68 changed files with 23678 additions and 2717 deletions
  1. 1 1
      .travis.yml
  2. 1 54
      INSTALL.md
  3. 1 0
      README.md
  4. 2 2
      TODO
  5. 13 2
      config.py
  6. BIN
      doc/images/explo_antstar_glue.gif
  7. 4 4
      intelligine/core/Context.py
  8. 7 11
      intelligine/core/exceptions.py
  9. 24 11
      intelligine/cst.py
  10. 91 44
      intelligine/display/Pygame.py
  11. 5 0
      intelligine/display/map.py
  12. 26 0
      intelligine/display/pygame/config.py
  13. 4 26
      intelligine/display/pygame/visualisation.py
  14. 2 1
      intelligine/sandbox/all/all.py
  15. 2 1
      intelligine/sandbox/exploration/exploration.py
  16. 1858 1858
      intelligine/sandbox/exploration/map.tmx
  17. 10215 0
      intelligine/sandbox/exploration/map.tmx.bak
  18. 12 0
      intelligine/shorcut/brain.py
  19. 87 0
      intelligine/simulation/molecule/DirectionMolecule.py
  20. 62 0
      intelligine/simulation/molecule/Evaporation.py
  21. 7 3
      intelligine/simulation/molecule/Molecule.py
  22. 76 0
      intelligine/simulation/molecule/MoleculeFlavour.py
  23. 66 36
      intelligine/simulation/object/brain/AntBrain.py
  24. 7 16
      intelligine/simulation/object/brain/Brain.py
  25. 9 1
      intelligine/simulation/object/brain/part/BrainPart.py
  26. 131 30
      intelligine/simulation/object/brain/part/move/AntMoveBrainPart.py
  27. 64 0
      intelligine/simulation/object/brain/part/move/AntStar/ByPass.py
  28. 26 0
      intelligine/simulation/object/brain/part/move/AntStar/Host.py
  29. 24 0
      intelligine/simulation/object/brain/part/move/AntStar/HostFeeler.py
  30. 27 17
      intelligine/simulation/object/brain/part/transport/AntPutBrainPart.py
  31. 19 8
      intelligine/simulation/object/brain/part/transport/AntTakeBrainPart.py
  32. 25 8
      intelligine/simulation/object/brain/part/transport/TransportBrainPart.py
  33. 42 0
      intelligine/simulation/object/molecule/MoleculeGland.py
  34. 15 0
      intelligine/simulation/object/molecule/MovementMoleculeGland.py
  35. 0 12
      intelligine/simulation/object/pheromone/MovementPheromoneGland.py
  36. 0 41
      intelligine/simulation/object/pheromone/PheromoneGland.py
  37. 0 85
      intelligine/simulation/pheromone/DirectionPheromone.py
  38. 0 51
      intelligine/simulation/pheromone/PheromoneFlavour.py
  39. 29 1
      intelligine/synergy/Simulation.py
  40. 1 5
      intelligine/synergy/event/Event.py
  41. 2 1
      intelligine/synergy/event/attack/NearAttackableEvent.py
  42. 1 1
      intelligine/synergy/event/move/MoveAction.py
  43. 2 2
      intelligine/synergy/event/move/MoveEvent.py
  44. 5 1
      intelligine/synergy/event/move/direction.py
  45. 30 18
      intelligine/synergy/event/smell/SmellAction.py
  46. 6 2
      intelligine/synergy/event/smell/SmellEvent.py
  47. 10 2
      intelligine/synergy/event/transport/PutableAction.py
  48. 3 2
      intelligine/synergy/event/transport/PutableEvent.py
  49. 1 1
      intelligine/synergy/event/transport/TakeableAction.py
  50. 3 2
      intelligine/synergy/event/transport/TakeableEvent.py
  51. 4 5
      intelligine/synergy/object/BaseBug.py
  52. 2 1
      intelligine/synergy/object/Egg.py
  53. 2 1
      intelligine/synergy/object/StockedFood.py
  54. 4 1
      intelligine/synergy/object/SynergyObject.py
  55. 3 3
      intelligine/synergy/object/Transportable.py
  56. 16 15
      intelligine/synergy/object/ant/Ant.py
  57. 50 0
      intelligine/synergy/stigmergy/MoleculesManager.py
  58. 0 49
      intelligine/synergy/stigmergy/PheromonesManager.py
  59. 26 0
      intelligine/tests/simulation/bypass/TestByPass.py
  60. 51 36
      intelligine/tests/simulation/mode/TestChangeMode.py
  61. 0 0
      intelligine/tests/simulation/molecule/Base.py
  62. 227 0
      intelligine/tests/simulation/molecule/TestDirection.py
  63. 0 241
      intelligine/tests/simulation/pheromone/TestDirection.py
  64. 10215 0
      intelligine/tests/src/simulation/SimpleTestWorld1.tmx
  65. 19 0
      intelligine/tests/src/simulation/SimpleTestWorld1Simulation.py
  66. 5 2
      requirements.txt
  67. 3 2
      tests.py
  68. 3 0
      tests_requirements.txt

+ 1 - 1
.travis.yml View File

@@ -7,4 +7,4 @@ install:
7 7
 script:
8 8
   - coverage run tests.py --rcfile=.coveragerc -v && coverage report -m && python3.4 tests.py
9 9
 after_success:
10
-  - coveralls
10
+  - coveralls

+ 1 - 54
INSTALL.md View File

@@ -1,54 +1 @@
1
-INSTALL
2
-=====================
3
-
4
-Windows
5
---------------------
6
-
7
-(dirty tmp howto)
8
-
9
-Install python 3.4+: https://www.python.org/downloads/
10
-Install Git: http://git-scm.com/download/win
11
-
12
-Execute command 
13
-````
14
-C:\Python34\python -m pip install pytmx
15
-````
16
-Install pygame for python3.4: Download pygame‑1.9.2a0‑cp34‑none‑win32.whl on http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame
17
-
18
-Execute command 
19
-````
20
-C:\Python34\python -m pip install "Downloads\pygame-1.9.2a0-cp34-none-win32.whl"
21
-````
22
-Launch Git Bash program and execute command
23
-````
24
-git clone https://github.com/buxx/intelligine.git ant/intelligine
25
-````
26
-
27
-Open Cmd and execute commands 
28
-````
29
-cd intelligine
30
-git clone https://github.com/buxx/synergine.git
31
-git clone https://github.com/buxx/synergine_xyz.git
32
-````
33
-
34
-Open new Cmd:
35
-````
36
-cd intelligine
37
-C:\Python34\python run.py multi
38
-````
39
-
40
-Linux
41
--------------------
42
-
43
-You need python3.4+ and git. Clone the project:
44
-````
45
-git clone https://github.com/buxx/intelligine.git ant/intelligine
46
-````
47
-Install requirements:
48
-````
49
-pip install -r requirements.txt
50
-````
51
-It's ready
52
-````
53
-python run.py multi
54
-````
1
+Soon ...

+ 1 - 0
README.md View File

@@ -18,3 +18,4 @@ Social intelligence (/Ant colony) simulation.
18 18
 ### Ressource exploration
19 19
 
20 20
 [![Intelligine: ressource exploration](https://raw.githubusercontent.com/buxx/intelligine/master/doc/images/intelligine_ressource_20150421_r.gif)](https://raw.githubusercontent.com/buxx/intelligine/master/doc/images/intelligine_ressource_20150421_r.gif) 
21
+[![Intelligine: ressource exploration with AntStar algo for bypass](https://raw.githubusercontent.com/buxx/intelligine/dev/mol/doc/images/explo_antstar_glue.gif)](https://raw.githubusercontent.com/buxx/intelligine/dev/mol/doc/images/explo_antstar_glue.gif)

+ 2 - 2
TODO View File

@@ -1,3 +1,3 @@
1 1
 * Fourmis (map.tmx) pas en mode nurse (-> algo de choix d'activité plus tard)
2
-* Pygame: smell, pheromons: rendre + generique
3
-* Smell: Calcul de la distance max
2
+* Ant: MOVE_MODE_HOME && rien à faire (pas de truc à stocker, switch to mode EXPLO)
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 ...

+ 13 - 2
config.py View File

@@ -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],
@@ -56,6 +57,16 @@ config = {
56 57
     'ant': {
57 58
         'take': {
58 59
             'cant_put_still': 5
60
+        },
61
+        'put': {
62
+            'max_objects_at_same_position': 5
63
+        }
64
+    },
65
+    'stigmergy': {
66
+        'molecule': {
67
+            'evaporate_decrement': 5,
68
+            'evaporate_min_age': 100,
69
+            'evaporate_each_cycle': 100
59 70
         }
60 71
     }
61
-}
72
+}

BIN
doc/images/explo_antstar_glue.gif View File


+ 4 - 4
intelligine/core/Context.py View File

@@ -1,17 +1,17 @@
1 1
 from synergine_xyz.Context import Context as XyzContext
2 2
 from intelligine.cst import IMPENETRABLE
3 3
 from synergine_xyz.cst import POSITIONS
4
-from intelligine.synergy.stigmergy.PheromonesManager import PheromonesManager
4
+from intelligine.synergy.stigmergy.MoleculesManager import MoleculesManager
5 5
 
6 6
 
7 7
 class Context(XyzContext):
8 8
 
9 9
     def __init__(self):
10 10
         super().__init__()
11
-        self._pheromones = PheromonesManager(self)
11
+        self._molecules = MoleculesManager(self)
12 12
 
13
-    def pheromones(self):
14
-        return self._pheromones
13
+    def molecules(self):
14
+        return self._molecules
15 15
 
16 16
     def position_is_penetrable(self, position):
17 17
         """

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

@@ -13,27 +13,27 @@ class UnableToFoundMovement(MovementException):
13 13
     pass
14 14
 
15 15
 
16
-class PheromoneException(Exception):
16
+class MoleculeException(Exception):
17 17
     pass
18 18
 
19 19
 
20
-class NoPheromone(PheromoneException):
20
+class NoMolecule(MoleculeException):
21 21
     pass
22 22
 
23 23
 
24
-class NoPheromoneMove(PheromoneException, MovementException):
24
+class NoMoleculeMove(MoleculeException, MovementException):
25 25
     pass
26 26
 
27 27
 
28
-class NoTypeInPheromone(NoPheromone):
28
+class NoTypeInMolecule(NoMolecule):
29 29
     pass
30 30
 
31 31
 
32
-class NoCategoryInPheromone(NoPheromone):
32
+class NoCategoryInMolecule(NoMolecule):
33 33
     pass
34 34
 
35 35
 
36
-class BestPheromoneHere(PheromoneException):
36
+class BestMoleculeHere(MoleculeException):
37 37
 
38 38
     def __init__(self, best_distance,  *args, **kwargs):
39 39
         super().__init__(*args, **kwargs)
@@ -42,7 +42,7 @@ class BestPheromoneHere(PheromoneException):
42 42
     def get_best_distance(self):
43 43
         return self._best_distance
44 44
 
45
-class PheromoneGlandDisabled(PheromoneException):
45
+class MoleculeGlandDisabled(MoleculeException):
46 46
     pass
47 47
 
48 48
 
@@ -50,10 +50,6 @@ class BrainException(Exception):
50 50
     pass
51 51
 
52 52
 
53
-class BrainPartAlreadyExist(BrainException):
54
-    pass
55
-
56
-
57 53
 class BodyException(Exception):
58 54
     pass
59 55
 

+ 24 - 11
intelligine/cst.py View File

@@ -9,30 +9,40 @@ COLONY = IncrementedNamedInt.get('intelligine.colony')
9 9
 TRANSPORTABLE = IncrementedNamedInt.get('intelligine.transportable')
10 10
 TRANSPORTER = IncrementedNamedInt.get('intelligine.transporter')
11 11
 CARRYING = IncrementedNamedInt.get('intelligine.carrying')
12
-CARRIED = IncrementedNamedInt.get('intelligine.carried')
12
+CARRIED_BY = IncrementedNamedInt.get('intelligine.carried_by')
13
+CARRY = IncrementedNamedInt.get('intelligine.carry')
13 14
 CANT_CARRY_STILL = IncrementedNamedInt.get('intelligine.cantcarry.still')
14 15
 CANT_PUT_STILL = IncrementedNamedInt.get('intelligine.cantput.still')
15 16
 ACTION_DIE = IncrementedNamedInt.get('intelligine.basebug.action.die')
16
-PHEROMONE_SEARCHING = IncrementedNamedInt.get('intelligine.pheromone_searching')
17
+MOLECULE_SEARCHING = IncrementedNamedInt.get('intelligine.molecule_searching')
18
+MOLECULES = IncrementedNamedInt.get('intelligine.molecules')
17 19
 
18
-# TODO: Renommer "move_mode" en "mode"
19
-MOVE_MODE = IncrementedNamedInt.get('intelligine.basebug.move.mode')
20
-MOVE_MODE_EXPLO = IncrementedNamedInt.get('intelligine.basebug.move.mode.explo')
21
-MOVE_MODE_GOHOME = IncrementedNamedInt.get('intelligine.basebug.move.mode.gohome')
22
-MOVE_MODE_NURSE = IncrementedNamedInt.get('intelligine.basebug.move.mode.nurse')
20
+MODE = IncrementedNamedInt.get('intelligine.basebug.move')
21
+MODE_EXPLO = IncrementedNamedInt.get('intelligine.basebug.move.explo')
22
+MODE_GOHOME = IncrementedNamedInt.get('intelligine.basebug.move.gohome')
23
+MODE_NURSE = IncrementedNamedInt.get('intelligine.basebug.move.nurse')
24
+MODE_HOME = IncrementedNamedInt.get('intelligine.basebug.move.home')
25
+
26
+MOVE_BYBASS = IncrementedNamedInt.get('intelligine.basebug.move.bypass')
27
+MOVE_BYBASS_DISTANCE = IncrementedNamedInt.get('intelligine.basebug.move.bypass.distance')
28
+MOVE_BYBASS_MEMORY = IncrementedNamedInt.get('intelligine.basebug.move.bypass.memory')
29
+MOVE_BYBASS_WALL = IncrementedNamedInt.get('intelligine.basebug.move.bypass.wall')
30
+MOVE_BYBASS_RE_WALKING = IncrementedNamedInt.get('intelligine.basebug.move.bypass.re_walking')
23 31
 
24 32
 TYPE = IncrementedNamedInt.get('intelligine.object.type')
25 33
 TYPE_RESOURCE_EXPLOITABLE = IncrementedNamedInt.get('intelligine.object.type.resource.transformable')
34
+TYPE_RESOURCE_EATABLE = IncrementedNamedInt.get('intelligine.object.type.resource.eatable')
26 35
 TYPE_NURSERY = IncrementedNamedInt.get('intelligine.object.type.nursery')
27 36
 TYPE_ANT = IncrementedNamedInt.get('intelligine.object.type.ant')
28 37
 
29 38
 PHEROMON_POSITIONS = IncrementedNamedInt.get('intelligine.phero.positions')
30
-PHEROMON_INFOS = IncrementedNamedInt.get('intelligine.phero.infos')
31
-PHEROMON_DIRECTION = IncrementedNamedInt.get('intelligine.phero.direction')
39
+MOLECULES_INFOS = IncrementedNamedInt.get('intelligine.mol.infos')
40
+MOLECULES_DIRECTION = IncrementedNamedInt.get('intelligine.mol.direction')
32 41
 PHEROMON_DIR_NONE = IncrementedNamedInt.get('intelligine.phero.direction.none')
33 42
 PHEROMON_DIR_EXPLO = IncrementedNamedInt.get('intelligine.phero.direction.explo')
34
-PHEROMON_DIR_HOME = IncrementedNamedInt.get('intelligine.phero.direction.home')
43
+EXPLORATION_VECTOR = IncrementedNamedInt.get('intelligine.exploration_vector')
35 44
 
45
+#SMELL = IncrementedNamedInt.get('intelligine.smell')
36 46
 OBJ_SMELL = IncrementedNamedInt.get('intelligine.obj_smell')
37 47
 SMELL_FOOD = IncrementedNamedInt.get('intelligine.smell.food')
38 48
 SMELL_EGG = IncrementedNamedInt.get('intelligine.smell.egg')
@@ -48,6 +58,9 @@ COL_TRANSPORTER_NOT_CARRYING = IncrementedNamedInt.get('intelligine.col.transpor
48 58
 COL_EATABLE = IncrementedNamedInt.get('intelligine.col.eatable')
49 59
 COL_SMELL = IncrementedNamedInt.get('intelligine.col.smell')
50 60
 
61
+INSTANCE_CLASS = IncrementedNamedInt.get('intelligine.instance_class')
62
+
63
+BRAIN = IncrementedNamedInt.get('intelligine.brain')
51 64
 BRAIN_SCHEMA = IncrementedNamedInt.get('intelligine.brain_schema')
52 65
 BRAIN_PART_MOVE = IncrementedNamedInt.get('intelligine.brain.part.move')
53 66
 BRAIN_PART_TAKE = IncrementedNamedInt.get('intelligine.brain.part.take')
@@ -55,4 +68,4 @@ BRAIN_PART_PUT = IncrementedNamedInt.get('intelligine.brain.part.put')
55 68
 BRAIN_PART_ATTACK = IncrementedNamedInt.get('intelligine.brain.part.attack')
56 69
 
57 70
 BODY_SCHEMA = IncrementedNamedInt.get('intelligine.body_schema')
58
-BODY_PART_PHEROMONE_GLAND = IncrementedNamedInt.get('intelligine.body.part.pheromone_gland')
71
+BODY_PART_PHEROMONE_GLAND = IncrementedNamedInt.get('intelligine.body.part.molecule_gland')

+ 91 - 44
intelligine/display/Pygame.py View File

@@ -1,8 +1,10 @@
1
-from intelligine.core.exceptions import NoPheromone
1
+from intelligine.core.exceptions import NoMolecule
2
+from intelligine.synergy.object.ant.Ant import Ant
3
+from intelligine.synergy.object.ant.Egg import Egg
2 4
 from synergine_xyz.display.Pygame import Pygame as XyzPygame
3 5
 import pygame
4
-from intelligine.cst import PHEROMON_DIRECTION, PHEROMON_DIR_HOME, PHEROMON_DIR_EXPLO, PHEROMON_POSITIONS, POINTS_SMELL, \
5
-    POINT_SMELL, SMELL_EGG, SMELL_FOOD
6
+from intelligine.cst import PHEROMON_DIR_EXPLO, MOLECULES, SMELL_EGG, SMELL_FOOD, MOLECULES_DIRECTION, \
7
+    MOVE_BYBASS_MEMORY
6 8
 from intelligine.display.pygame.visualisation import SURFACE_PHEROMONE_EXPLORATION, SURFACE_PHEROMONE_HOME, \
7 9
     SURFACE_SMELL_EGG, SURFACE_SMELL_FOOD
8 10
 
@@ -11,63 +13,108 @@ class Pygame(XyzPygame):
11 13
 
12 14
     def __init__(self, config, context, synergy_manager):
13 15
         super().__init__(config, context, synergy_manager)
14
-        self._is_display_pheromones = False
16
+        self._is_display_molecules = False
15 17
         self._is_display_smells = False
18
+        self._draw_callbacks = []
16 19
 
17 20
     def receive(self, actions_done):
18 21
         super().receive(actions_done)
19 22
 
20
-        if self._is_display_pheromones:
21
-            pheromones_positions = self._context.metas.list.get(PHEROMON_POSITIONS,
22
-                                                                PHEROMON_POSITIONS,
23
-                                                                allow_empty=True)
24
-            self._display_pheromones(pheromones_positions, self._context)
23
+        if self._is_display_molecules:
24
+            molecules_positions = self._context.metas.list.get(MOLECULES,
25
+                                                               MOLECULES,
26
+                                                               allow_empty=True)
27
+            self._display_molecules(molecules_positions, self._context)
25 28
 
26
-        if self._is_display_smells:
27
-            smell_positions = self._context.metas.list.get(POINTS_SMELL,
28
-                                                           POINTS_SMELL,
29
-                                                           allow_empty=True)
30
-            self._display_smells(smell_positions, self._context)
29
+    def _display_molecules(self, molecules_positions, context):
30
+        molecule_exploration_surface = self._object_visualizer.get_surface(SURFACE_PHEROMONE_EXPLORATION)
31
+        molecule_home_surface = self._object_visualizer.get_surface(SURFACE_PHEROMONE_HOME)
32
+        smell_egg_surface = self._object_visualizer.get_surface(SURFACE_SMELL_EGG)
33
+        smell_food_surface = self._object_visualizer.get_surface(SURFACE_SMELL_FOOD)
34
+
35
+        for point in molecules_positions:
36
+            point_flavour = context.molecules().get_flavour(point)
37
+            try:
38
+                molecule = point_flavour.get_molecule(category=MOLECULES_DIRECTION, type=PHEROMON_DIR_EXPLO)
39
+                self.draw_surface(point, molecule_exploration_surface)
40
+
41
+                adapted_point = self._get_real_pixel_position_of_position(point)
42
+                myfont = pygame.font.SysFont("monospace", 15)
43
+                label = myfont.render(str(molecule.get_distance()), 1, (128,255,128))
44
+                self._screen.blit(label, adapted_point)
31 45
 
32
-    def _display_pheromones(self, pheromones_positions, context):
33
-        pheromone_exploration_surface = self._object_visualizer.get_surface(SURFACE_PHEROMONE_EXPLORATION)
34
-        pheromone_home_surface = self._object_visualizer.get_surface(SURFACE_PHEROMONE_HOME)
46
+            except NoMolecule:
47
+                pass # No molecule here
35 48
 
36
-        for point in pheromones_positions:
37
-            point_flavour = context.pheromones().get_flavour(point)
38 49
             try:
39
-                point_flavour.get_pheromone(category=PHEROMON_DIRECTION, type=PHEROMON_DIR_HOME)
40
-                self.draw_surface(point, pheromone_home_surface)
41
-            except NoPheromone:
42
-                pass # No pheromone here
50
+                molecule = point_flavour.get_molecule(category=MOLECULES_DIRECTION, type=SMELL_FOOD)
51
+                self.draw_surface(point, smell_food_surface)
52
+
53
+                adapted_point = self._get_real_pixel_position_of_position(point)
54
+                adapted_point = (adapted_point[0]+10, adapted_point[1]+10)
55
+                myfont = pygame.font.SysFont("monospace", 15)
56
+                label = myfont.render(str(molecule.get_distance()), 1, (255,255,0))
57
+                self._screen.blit(label, adapted_point)
58
+
59
+            except NoMolecule:
60
+                pass # No molecule here
43 61
 
44 62
             try:
45
-                point_flavour.get_pheromone(category=PHEROMON_DIRECTION, type=PHEROMON_DIR_EXPLO)
46
-                self.draw_surface(point, pheromone_exploration_surface)
47
-            except NoPheromone:
48
-                pass # No pheromone here
63
+                molecule = point_flavour.get_molecule(category=MOLECULES_DIRECTION, type=SMELL_EGG)
64
+                self.draw_surface(point, smell_food_surface)
49 65
 
50
-    def _display_smells(self, smell_positions, context):
51
-        smell_egg_surface = self._object_visualizer.get_surface(SURFACE_SMELL_EGG)
52
-        smell_food_surface = self._object_visualizer.get_surface(SURFACE_SMELL_FOOD)
66
+                adapted_point = self._get_real_pixel_position_of_position(point)
67
+                adapted_point = (adapted_point[0]+10, adapted_point[1]+10)
68
+                myfont = pygame.font.SysFont("monospace", 15)
69
+                label = myfont.render(str(molecule.get_distance()), 1, (255,255,0))
70
+                self._screen.blit(label, adapted_point)
71
+
72
+            except NoMolecule:
73
+                pass # No molecule here
53 74
 
54
-        for point in smell_positions:
55
-            point_flavour = context.metas.value.get(POINT_SMELL, point, allow_empty=True, empty_value={})
56
-            if SMELL_EGG in point_flavour:
75
+            try:
76
+                point_flavour.get_molecule(category=MOLECULES_DIRECTION, type=SMELL_EGG)
57 77
                 self.draw_surface(point, smell_egg_surface)
58
-            if SMELL_FOOD in point_flavour:
59
-                self.draw_surface(point, smell_food_surface)
78
+            except NoMolecule:
79
+                pass # No molecule here
60 80
 
61 81
     def _key_pressed(self, key):
62 82
 
63
-        if key == pygame.K_p:
64
-            if self._is_display_pheromones:
65
-                self._is_display_pheromones = False
83
+        if key == pygame.K_m:
84
+            if self._is_display_molecules:
85
+                self._is_display_molecules = False
66 86
             else:
67
-                self._is_display_pheromones = True
87
+                self._is_display_molecules = True
68 88
 
69
-        if key == pygame.K_s:
70
-            if self._is_display_smells:
71
-                self._is_display_smells = False
72
-            else:
73
-                self._is_display_smells = True
89
+    def draw_object(self, obj, point):
90
+        super().draw_object(obj, point)
91
+        # TODO: DEBUG
92
+        if isinstance(obj, Ant):
93
+            myfont = pygame.font.SysFont("monospace", 15)
94
+            label = myfont.render(str(obj.get_id()), 1, (255,255,0))
95
+            self._draw_callbacks.append(lambda: self._screen.blit(label, point))
96
+            label2 = myfont.render(',', 1, (0,0,0))
97
+
98
+            ant_mem = self._context.metas.value.get(MOVE_BYBASS_MEMORY, obj.get_id(), allow_empty=True,
99
+                                                             empty_value=[])
100
+
101
+            def print_mem(points):
102
+                for m in points:
103
+                    real_point = self._get_real_pixel_position_of_position((0, m[0], m[1]))
104
+                    self._screen.blit(label2, real_point)
105
+
106
+            self._draw_callbacks.append(lambda: print_mem(ant_mem) )
107
+        # TODO: DEBUG
108
+        if isinstance(obj, Egg):
109
+            myfont = pygame.font.SysFont("monospace", 15)
110
+            label = myfont.render(str(obj.get_id()), 1, (125,255,25))
111
+            self._draw_callbacks.append(lambda: self._screen.blit(label, point))
112
+
113
+    def start_of_cycle(self):
114
+        super().start_of_cycle()
115
+        self._draw_callbacks = []
116
+
117
+    def end_of_cycle(self):
118
+        for draw_callback in self._draw_callbacks:
119
+            draw_callback()
120
+        super().end_of_cycle()

+ 5 - 0
intelligine/display/map.py View File

@@ -0,0 +1,5 @@
1
+from synergine_xyz.tmx.TileMapConnector import TileMapConnector
2
+
3
+
4
+def get_map_connector(map_file_path, map_config):
5
+    return TileMapConnector.from_file(map_file_path, dict(map_config))

+ 26 - 0
intelligine/display/pygame/config.py View File

@@ -0,0 +1,26 @@
1
+from intelligine.synergy.Colony import Colony
2
+from intelligine.synergy.Environment import Environment
3
+from intelligine.synergy.Simulation import Simulation
4
+from intelligine.synergy.object.StockedFood import StockedFood
5
+from intelligine.synergy.object.Food import Food
6
+from intelligine.synergy.object.Rock import Rock
7
+from intelligine.synergy.object.ant.Ant import Ant
8
+from intelligine.synergy.object.ant.Egg import Egg
9
+
10
+
11
+map_config = {
12
+    'simulation': {
13
+        'base': Simulation
14
+    },
15
+    'collection': {
16
+        'ant': Colony,
17
+        'env': Environment
18
+    },
19
+    'object': {
20
+        'ant': Ant,
21
+        'egg': Egg,
22
+        'rock': Rock,
23
+        'food': Food,
24
+        'stocked_food': StockedFood
25
+    }
26
+}

+ 4 - 26
intelligine/display/pygame/visualisation.py View File

@@ -1,21 +1,15 @@
1 1
 import pygame
2
-from intelligine.synergy.Colony import Colony
3
-from intelligine.synergy.Environment import Environment
4
-from intelligine.synergy.object.StockedFood import StockedFood
5
-from synergine.synergy.Simulation import Simulation
2
+from intelligine.display.map import get_map_connector
6 3
 from synergine_xyz.display.PygameImageRotate import PygameImageRotate
7 4
 from synergine_xyz.display.PygameVisualisation import PygameVisualisation
8 5
 from synergine_xyz.display.object.pygame.PygameImage import PygameImage
9
-from intelligine.synergy.object.Food import Food
10 6
 from intelligine.synergy.object.ant.Ant import Ant
11
-from intelligine.synergy.object.Rock import Rock
12 7
 from intelligine.synergy.object.ant.Egg import Egg
13 8
 from os import getcwd
14 9
 from synergine_xyz.cst import PREVIOUS_DIRECTION
15
-from synergine_xyz.tmx.TileMapConnector import TileMapConnector
16 10
 
17
-SURFACE_PHEROMONE_HOME = 'pheromone_home'
18
-SURFACE_PHEROMONE_EXPLORATION = 'pheromone_exploration'
11
+SURFACE_PHEROMONE_HOME = 'molecule_home'
12
+SURFACE_PHEROMONE_EXPLORATION = 'molecule_exploration'
19 13
 
20 14
 SURFACE_SMELL_EGG = 'smell_egg'
21 15
 SURFACE_SMELL_FOOD = 'smell_food'
@@ -158,22 +152,6 @@ def for_position(position, objects, context):
158 152
 # Behind, new
159 153
 #############################
160 154
 
161
-map_config = {
162
-    'simulation': {
163
-        'base': Simulation
164
-    },
165
-    'collection': {
166
-        'ant': Colony,
167
-        'env': Environment
168
-    },
169
-    'object': {
170
-        'ant': Ant,
171
-        'egg': Egg,
172
-        'rock': Rock,
173
-        'food': Food,
174
-        'stocked_food': StockedFood
175
-    }
176
-}
177 155
 image_rotate = PygameImageRotate()
178 156
 
179 157
 
@@ -203,7 +181,7 @@ def ant_direction_modifier(obj, context, visual):
203 181
 
204 182
 
205 183
 def get_standard_extract_from_map(map_file_path, map_config):
206
-    map_connector = TileMapConnector.from_file(map_file_path, dict(map_config))
184
+    map_connector = get_map_connector(map_file_path, map_config)
207 185
     visualisation = PygameVisualisation.get_default_visualisation()
208 186
 
209 187
     simulations = map_connector.create_simulations()

+ 2 - 1
intelligine/sandbox/all/all.py View File

@@ -1,5 +1,6 @@
1 1
 from os import getcwd
2
-from intelligine.display.pygame.visualisation import get_standard_extract_from_map, map_config
2
+from intelligine.display.pygame.config import map_config
3
+from intelligine.display.pygame.visualisation import get_standard_extract_from_map
3 4
 
4 5
 
5 6
 simulations, visualisation = get_standard_extract_from_map(getcwd()+"/intelligine/sandbox/all/map.tmx",

+ 2 - 1
intelligine/sandbox/exploration/exploration.py View File

@@ -1,5 +1,6 @@
1 1
 from os import getcwd
2
-from intelligine.display.pygame.visualisation import get_standard_extract_from_map, map_config
2
+from intelligine.display.pygame.config import map_config
3
+from intelligine.display.pygame.visualisation import get_standard_extract_from_map
3 4
 
4 5
 
5 6
 simulations, visualisation = get_standard_extract_from_map(getcwd()+"/intelligine/sandbox/exploration/map.tmx",

File diff suppressed because it is too large
+ 1858 - 1858
intelligine/sandbox/exploration/map.tmx


File diff suppressed because it is too large
+ 10215 - 0
intelligine/sandbox/exploration/map.tmx.bak


+ 12 - 0
intelligine/shorcut/brain.py View File

@@ -0,0 +1,12 @@
1
+from intelligine.cst import BRAIN, BRAIN_SCHEMA, INSTANCE_CLASS
2
+
3
+
4
+def get_brain_class(context, object_id):
5
+    object_class = context.metas.value.get(INSTANCE_CLASS, object_id)
6
+    return context.metas.value.get(BRAIN, object_class)
7
+
8
+
9
+def get_brain_part(context, object_id, brain_part_name):
10
+    object_class = context.metas.value.get(INSTANCE_CLASS, object_id)
11
+    object_brain_schema = context.metas.value.get(BRAIN_SCHEMA, object_class)
12
+    return object_brain_schema[brain_part_name]

+ 87 - 0
intelligine/simulation/molecule/DirectionMolecule.py View File

@@ -0,0 +1,87 @@
1
+from intelligine.cst import POINTS_SMELL, MOLECULES, MOLECULES_DIRECTION
2
+from intelligine.core.exceptions import NoMolecule
3
+from random import shuffle
4
+from synergine_xyz.geometry import get_degree_from_north
5
+from intelligine.synergy.event.move.direction import get_direction_for_degrees
6
+
7
+
8
+class DirectionMolecule():
9
+
10
+    _positions_key = None
11
+
12
+    @classmethod
13
+    def appose(cls, context, point, molecule):
14
+        context.molecules().increment_with_molecule(point, molecule, context.get_cycle())
15
+        context.metas.list.add(MOLECULES, MOLECULES, point, assert_not_in=False)
16
+
17
+    @classmethod
18
+    def get_direction_for_point(cls, context, point, molecule_type):
19
+        flavour = context.molecules().get_flavour(point)
20
+        molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
21
+
22
+        distance = molecule.get_distance()
23
+        around_molecule_filter = lambda around_molecule: around_molecule.get_distance() < distance
24
+        around_molecules_points = cls._get_around_molecules(context, point, molecule_type,
25
+                                                            molecule_filter=around_molecule_filter)
26
+
27
+        if not around_molecules_points:
28
+            raise NoMolecule()
29
+
30
+        shuffle(around_molecules_points)
31
+        around_molecules_sorted = sorted(around_molecules_points, key=lambda x: x[1].get_intensity(), reverse=True)
32
+        max_intensity = around_molecules_sorted[0][1].get_intensity()
33
+
34
+        around_molecules_max = []
35
+        for around_molecule_sorted in around_molecules_sorted:
36
+            if around_molecule_sorted[1].get_intensity() == max_intensity:
37
+                around_molecules_max.append(around_molecule_sorted)
38
+
39
+        around_molecules_sorted_by_distance = sorted(around_molecules_max,
40
+                                                      key=lambda x: x[1].get_distance(),
41
+                                                      reverse=False)
42
+
43
+        go_to_point = around_molecules_sorted_by_distance[0][0]
44
+
45
+        direction_degrees = get_degree_from_north(point, go_to_point)
46
+        direction = get_direction_for_degrees(direction_degrees)
47
+
48
+        return direction
49
+
50
+    @classmethod
51
+    def _get_around_molecules(cls, context, reference_point, molecule_type,
52
+                              molecule_filter=lambda around_molecule: True):
53
+        around_points = context.get_around_points_of_point(reference_point)
54
+        around_molecules_points = []
55
+        for around_point in around_points:
56
+            flavour = context.molecules().get_flavour(around_point)
57
+            try:
58
+                around_molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
59
+                if molecule_filter(around_molecule):
60
+                    around_molecules_points.append((around_point, around_molecule))
61
+            except NoMolecule:
62
+                pass  # No molecule, ok continue to sniff around
63
+
64
+        return around_molecules_points
65
+
66
+    @classmethod
67
+    def get_best_molecule_direction_in(cls, context, reference_point, points, molecule_type):
68
+        around_molecules_points = []
69
+        for around_point in points:
70
+            flavour = context.molecules().get_flavour(around_point)
71
+            try:
72
+                around_molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
73
+                around_molecules_points.append((around_point, around_molecule))
74
+            except NoMolecule:
75
+                pass  # Ok, no molecule, continue to sniff around
76
+
77
+        if not around_molecules_points:
78
+            raise NoMolecule()
79
+
80
+        shuffle(around_molecules_points)
81
+        around_molecules_sorted = sorted(around_molecules_points, key=lambda x: x[1].get_intensity(), reverse=True)
82
+        go_to_point = around_molecules_sorted[0][0]
83
+
84
+        direction_degrees = get_degree_from_north(reference_point, go_to_point)
85
+        direction = get_direction_for_degrees(direction_degrees)
86
+
87
+        return direction

+ 62 - 0
intelligine/simulation/molecule/Evaporation.py View File

@@ -0,0 +1,62 @@
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,
8
+                 intensity_decrement=1,
9
+                 molecule_minimum_age=0,
10
+                 molecules_exclude_types=None,
11
+                 molecules_include_types=None):
12
+        self._context = context
13
+        self._intensity_decrement = intensity_decrement
14
+        self._molecules_manager = MoleculesManager(context)
15
+        self._molecule_minimum_age = molecule_minimum_age
16
+        self._molecules_exclude_types = molecules_exclude_types
17
+        self._molecules_include_types = molecules_include_types
18
+
19
+    def evaporate(self):
20
+        for position, flavour in self._get_flavours():
21
+            self._decrease_flavour(flavour)
22
+            self._molecules_manager.set_flavour(position, flavour)
23
+
24
+    def remove(self):
25
+        for position, flavour in self._get_flavours():
26
+            self._remove_molecule(flavour)
27
+            self._molecules_manager.set_flavour(position, flavour)
28
+
29
+    def _get_flavours(self):
30
+        molecules_points = self._context.metas.list.get(MOLECULES, MOLECULES, allow_empty=True)
31
+        for molecule_point in molecules_points:
32
+            yield molecule_point, self._molecules_manager.get_flavour(molecule_point)
33
+
34
+    def _decrease_flavour(self, flavour):
35
+        for direction_molecule in self._get_molecules_from_flavour(flavour):
36
+            direction_molecule.increment_intensity(-self._intensity_decrement)
37
+            flavour.set_molecule(direction_molecule)
38
+
39
+    def _get_molecules_from_flavour(self, flavour):
40
+        molecules = []
41
+        for direction_molecule in flavour.get_molecules(MOLECULES_DIRECTION):
42
+            if not self._is_recent_molecule(direction_molecule) \
43
+               and not self._is_excluded_molecule_type(direction_molecule):
44
+                molecules.append(direction_molecule)
45
+        return molecules
46
+
47
+    def _remove_molecule(self, flavour):
48
+        for direction_molecule in self._get_molecules_from_flavour(flavour):
49
+            flavour.remove_molecule(direction_molecule)
50
+
51
+    def _is_recent_molecule(self, molecule):
52
+        return (self._context.get_cycle() - molecule.get_cycle_age()) < self._molecule_minimum_age
53
+
54
+    def _is_excluded_molecule_type(self, molecule):
55
+        if not self._molecules_exclude_types and not self._molecules_include_types:
56
+            return False
57
+
58
+        if self._molecules_exclude_types and not self._molecules_include_types:
59
+            return molecule.get_type() in self._molecules_exclude_types
60
+
61
+        if not self._molecules_exclude_types and self._molecules_include_types:
62
+            return molecule.get_type() not in self._molecules_include_types

intelligine/simulation/pheromone/Pheromone.py → intelligine/simulation/molecule/Molecule.py View File

@@ -1,10 +1,11 @@
1
-class Pheromone():
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 Pheromone():
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
-        self._intensity += increment_value
29
+        self._intensity += increment_value

+ 76 - 0
intelligine/simulation/molecule/MoleculeFlavour.py View File

@@ -0,0 +1,76 @@
1
+from intelligine.core.exceptions import NoTypeInMolecule, NoCategoryInMolecule
2
+from intelligine.simulation.molecule.Molecule import Molecule
3
+
4
+
5
+class MoleculeFlavour():
6
+
7
+    @classmethod
8
+    def new_from_raw_data(cls, raw_data):
9
+        flavour = {}
10
+        for category in raw_data:
11
+            molecules_by_category = raw_data[category]
12
+            for type in molecules_by_category:
13
+                distance, intensity, cycle_age = molecules_by_category[type]
14
+                if category not in flavour:
15
+                    flavour[category] = {}
16
+                flavour[category][type] = Molecule(category, type, distance, intensity, cycle_age)
17
+        return cls(flavour)
18
+
19
+    def get_raw_data(self):
20
+        raw_data = {}
21
+        for category in self._flavour:
22
+            molecules_by_category = self._flavour[category]
23
+            for type in molecules_by_category:
24
+                molecule = molecules_by_category[type]
25
+                if category not in raw_data:
26
+                    raw_data[category] = {}
27
+                if molecule.get_intensity() >= 0:
28
+                    raw_data[category][type] = (molecule.get_distance(),
29
+                                                molecule.get_intensity(),
30
+                                                molecule.get_cycle_age())
31
+        return raw_data
32
+
33
+    def __init__(self, flavour):
34
+        self._flavour = flavour
35
+
36
+    def get_molecule(self, category, type):
37
+        types = self.get_types(category)
38
+        if type not in types:
39
+            raise NoTypeInMolecule()
40
+        return types[type]
41
+
42
+    def get_molecules(self, category):
43
+        """
44
+
45
+        :param category:
46
+        :return: Molecules dict or empty dict of no molecules
47
+        """
48
+        try:
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()
56
+        except NoCategoryInMolecule:
57
+            return {}
58
+
59
+    def get_types(self, category):
60
+        if category not in self._flavour:
61
+            raise NoCategoryInMolecule()
62
+        return self._flavour[category]
63
+
64
+    def set_molecule(self, molecule):
65
+        category = molecule.get_category()
66
+        type = molecule.get_type()
67
+
68
+        if category not in self._flavour:
69
+            self._flavour[category] = {}
70
+
71
+        self._flavour[category][type] = molecule
72
+
73
+    def remove_molecule(self, molecule):
74
+        category = molecule.get_category()
75
+        type = molecule.get_type()
76
+        del(self._flavour[category][type])

+ 66 - 36
intelligine/simulation/object/brain/AntBrain.py View File

@@ -1,73 +1,103 @@
1 1
 from intelligine.simulation.object.brain.Brain import Brain
2 2
 from intelligine.simulation.object.brain.part.attack.AttackBrainPart import AttackBrainPart
3 3
 from intelligine.simulation.object.brain.part.move.AntMoveBrainPart import AntMoveBrainPart
4
-from intelligine.cst import MOVE_MODE, MOVE_MODE_EXPLO, MOVE_MODE_GOHOME, PHEROMON_DIR_HOME, PHEROMON_DIR_EXPLO, \
5
-    BRAIN_PART_TAKE, BRAIN_PART_PUT, MOVE_MODE_NURSE, PHEROMON_DIR_NONE, BRAIN_PART_ATTACK
6
-from intelligine.cst import PHEROMONE_SEARCHING
4
+from intelligine.cst import MODE, MODE_EXPLO, MODE_GOHOME, PHEROMON_DIR_EXPLO, \
5
+    BRAIN_PART_TAKE, BRAIN_PART_PUT, MODE_NURSE, PHEROMON_DIR_NONE, BRAIN_PART_ATTACK, MODE_HOME, \
6
+    SMELL_FOOD, SMELL_EGG
7
+from intelligine.cst import MOLECULE_SEARCHING
7 8
 from intelligine.cst import BRAIN_PART_MOVE
8 9
 from intelligine.simulation.object.brain.part.transport.AntPutBrainPart import AntPutBrainPart
9 10
 from intelligine.simulation.object.brain.part.transport.AntTakeBrainPart import AntTakeBrainPart
11
+from intelligine.synergy.object.Food import Food
12
+from intelligine.synergy.object.ant.Egg import Egg
13
+from synergine.core.exceptions import NotFound
10 14
 
11 15
 
12 16
 class AntBrain(Brain):
13 17
 
14
-    # TODO: methode __init_ pour la classe ? Pour surcharger ici.
15
-    _brain_parts = {
18
+    _brain_parts = Brain._brain_parts.copy()
19
+    _brain_parts.update({
16 20
         BRAIN_PART_MOVE: AntMoveBrainPart,
17 21
         BRAIN_PART_TAKE: AntTakeBrainPart,
18 22
         BRAIN_PART_PUT: AntPutBrainPart,
19 23
         BRAIN_PART_ATTACK: AttackBrainPart
24
+    })
25
+
26
+    _taken_smell_matches = {
27
+        Food: SMELL_FOOD,
28
+        Egg: SMELL_EGG
20 29
     }
30
+    """ Correspondance entre ce qui est ramassé et où ce doit être stocké """
21 31
 
22 32
     def __init__(self, context, host):
23 33
         super().__init__(context, host)
24
-        self._movement_mode = MOVE_MODE_EXPLO
25
-        self._distance_from_objective = 0  # TODO rename: distance_since_objective
26
-        self._pheromone_searching = PHEROMON_DIR_EXPLO
34
+        self._movement_mode = MODE_HOME
35
+        self._distance_from_objective = 0
36
+        self._molecule_searching = PHEROMON_DIR_EXPLO
27 37
 
28 38
     def switch_to_mode(self, mode):
29 39
         self._movement_mode = mode
30
-        self._update_pheromone_gland(mode)
31
-        self._context.metas.value.set(MOVE_MODE, self._host.get_id(), mode)
32
-        self._distance_from_objective = 0
33
-        self._update_pheromone_searching(mode)
34
-
35
-    def _update_pheromone_gland(self, mode):
36
-        if mode == MOVE_MODE_EXPLO:
37
-            pheromone_direction_type = PHEROMON_DIR_HOME
38
-        elif mode == MOVE_MODE_GOHOME:
39
-            pheromone_direction_type = PHEROMON_DIR_EXPLO
40
-        elif mode == MOVE_MODE_NURSE:
41
-            pheromone_direction_type = None
40
+        self._update_molecule_gland(mode)
41
+        self._context.metas.value.set(MODE, self._host.get_id(), mode)
42
+        self._update_molecule_searching(mode)
43
+
44
+    def _update_molecule_gland(self, mode):
45
+        if mode == MODE_EXPLO:
46
+            molecule_direction_type = None
47
+        elif mode == MODE_GOHOME:
48
+            molecule_direction_type = PHEROMON_DIR_EXPLO
49
+            self._distance_from_objective = 0
50
+        elif mode == MODE_NURSE:
51
+            molecule_direction_type = None
52
+        elif mode == MODE_HOME:
53
+            molecule_direction_type = PHEROMON_DIR_EXPLO
42 54
         else:
43 55
             raise NotImplementedError()
44 56
 
45
-        if pheromone_direction_type:
46
-            self._host.get_movement_pheromone_gland().set_pheromone_type(pheromone_direction_type)
47
-            self._host.get_movement_pheromone_gland().enable()
57
+        if molecule_direction_type:
58
+            self._host.get_movement_molecule_gland().set_molecule_type(molecule_direction_type)
59
+            self._host.get_movement_molecule_gland().enable()
48 60
         else:
49
-            self._host.get_movement_pheromone_gland().disable()
50
-
51
-    def _update_pheromone_searching(self, mode):
52
-        if mode == MOVE_MODE_EXPLO:
53
-            pheromone_searching = PHEROMON_DIR_EXPLO
54
-        elif mode == MOVE_MODE_GOHOME:
55
-            pheromone_searching = PHEROMON_DIR_HOME
56
-        elif mode == MOVE_MODE_NURSE:
57
-            pheromone_searching = PHEROMON_DIR_NONE
61
+            self._host.get_movement_molecule_gland().disable()
62
+
63
+    def _update_molecule_searching(self, mode):
64
+        if mode == MODE_EXPLO:
65
+            molecule_searching = PHEROMON_DIR_EXPLO
66
+        elif mode == MODE_GOHOME:
67
+            molecule_searching = PHEROMON_DIR_NONE
68
+        elif mode == MODE_NURSE:
69
+            molecule_searching = PHEROMON_DIR_NONE
70
+        elif mode == MODE_HOME:
71
+            # TODO: Ca depend de ce que fait la fourmis, si s'occupe des oeufs, etc
72
+            molecule_searching = self.get_part(BRAIN_PART_TAKE).get_smell_target()
58 73
         else:
59 74
             raise NotImplementedError()
60
-        self._pheromone_searching = pheromone_searching
61
-        self._context.metas.value.set(PHEROMONE_SEARCHING, self._host.get_id(), pheromone_searching)
75
+
76
+        self._molecule_searching = molecule_searching
77
+        self._context.metas.value.set(MOLECULE_SEARCHING, self._host.get_id(), molecule_searching)
62 78
 
63 79
     def get_movement_mode(self):
64 80
         return self._movement_mode
65 81
 
66 82
     def host_moved(self, distance=1):
67
-        self._distance_from_objective += 1
83
+        self._distance_from_objective += distance
68 84
 
69 85
     def set_distance_from_objective(self, distance):
70 86
         self._distance_from_objective = distance
71 87
 
72 88
     def get_distance_from_objective(self):
73
-        return self._distance_from_objective
89
+        return self._distance_from_objective
90
+
91
+    def get_smell_for_object_taken(self, obj):
92
+        for take_class in self._taken_smell_matches:
93
+            if isinstance(obj, take_class):
94
+                return self._taken_smell_matches[take_class]
95
+        raise NotFound()
96
+
97
+    @classmethod
98
+    def get_home_smells(cls):
99
+        """
100
+        Note: Actually return all know smells. Not really HOME smells.
101
+        :return:
102
+        """
103
+        return cls._taken_smell_matches.values()

+ 7 - 16
intelligine/simulation/object/brain/Brain.py View File

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

+ 9 - 1
intelligine/simulation/object/brain/part/BrainPart.py View File

@@ -2,6 +2,14 @@ class BrainPart():
2 2
 
3 3
     def __init__(self, host_brain):
4 4
         self._host_brain = host_brain
5
+        self._context = self._host_brain.get_context()
6
+        self._host = self._host_brain.get_host()
5 7
 
6
-    def done(self, obj, context):
8
+    def get_host_brain(self):
9
+        return self._host_brain
10
+
11
+    def get_host(self):
12
+        return self.get_host_brain().get_host()
13
+
14
+    def done(self):
7 15
         pass

+ 131 - 30
intelligine/simulation/object/brain/part/move/AntMoveBrainPart.py View File

@@ -1,54 +1,155 @@
1
+from intelligine.shorcut.brain import get_brain_class
2
+from intelligine.simulation.object.brain.part.move.AntStar.ByPass import ByPass
3
+from intelligine.simulation.object.brain.part.move.AntStar.Host import Host
1 4
 from intelligine.simulation.object.brain.part.move.MoveBrainPart import MoveBrainPart
5
+from intelligine.synergy.event.move.direction import directions_modifiers, get_position_with_direction_decal
2 6
 from synergine_xyz.cst import POSITION
3
-from intelligine.core.exceptions import NoPheromone
4
-from intelligine.cst import PHEROMONE_SEARCHING, MOVE_MODE_EXPLO, COL_TRANSPORTER_NOT_CARRYING, COL_TRANSPORTER_CARRYING
5
-from intelligine.simulation.pheromone.DirectionPheromone import DirectionPheromone
7
+from intelligine.core.exceptions import NoMolecule
8
+from intelligine.cst import MOLECULE_SEARCHING, MODE_EXPLO, MODE_HOME, MODE, MODE_GOHOME, \
9
+    EXPLORATION_VECTOR, MOLECULES_DIRECTION
10
+from intelligine.simulation.molecule.DirectionMolecule import DirectionMolecule
6 11
 
7 12
 
8 13
 class AntMoveBrainPart(MoveBrainPart):
9 14
 
15
+    def __init__(self, host_brain):
16
+        super().__init__(host_brain)
17
+        self._exploration_vector = (0, 0)
18
+
19
+    def _set_exploration_vector(self, new_vector):
20
+        self._exploration_vector = new_vector
21
+        self._context.metas.value.set(EXPLORATION_VECTOR,
22
+                                      self._host_brain.get_host().get_id(),
23
+                                      new_vector)
24
+
10 25
     @classmethod
11 26
     def get_direction(cls, context, object_id):
12
-        try:
13
-            return cls._get_direction_with_pheromones(context, object_id)
14
-        except NoPheromone:
15
-            return super().get_direction(context, object_id)
27
+        move_mode = context.metas.value.get(MODE, object_id)
28
+        if move_mode == MODE_GOHOME:
29
+            return cls._get_direction_with_exploration_vector(context, object_id)
30
+        else:
31
+            try:
32
+                return cls._get_direction_with_molecules(context, object_id)
33
+            except NoMolecule:
34
+                return super().get_direction(context, object_id)
35
+
36
+        return super().get_direction(context, object_id)
16 37
 
17 38
     @classmethod
18
-    def _get_direction_with_pheromones(cls, context, object_id):
39
+    def _get_direction_with_molecules(cls, context, object_id):
19 40
         object_point = context.metas.value.get(POSITION, object_id)
20
-        pheromone_type = context.metas.value.get(PHEROMONE_SEARCHING, object_id)
41
+        molecule_type = context.metas.value.get(MOLECULE_SEARCHING, object_id)
21 42
         try:
22
-            direction = cls._get_pheromone_direction_for_point(context, object_point, pheromone_type)
23
-        except NoPheromone:
43
+            direction = cls._get_molecule_direction_for_point(context, object_point, molecule_type)
44
+        except NoMolecule:
24 45
             try:
25
-                direction = cls._get_direction_of_pheromone(context, object_point, pheromone_type)
26
-            except NoPheromone:
46
+                direction = cls._get_direction_of_molecule(context, object_point, molecule_type)
47
+            except NoMolecule:
27 48
                 raise
28 49
         return direction
29 50
 
30 51
     @staticmethod
31
-    def _get_pheromone_direction_for_point(context, point, pheromone_type):
32
-        return DirectionPheromone.get_direction_for_point(context, point, pheromone_type)
52
+    def _get_molecule_direction_for_point(context, point, molecule_type):
53
+        return DirectionMolecule.get_direction_for_point(context, point, molecule_type)
33 54
 
34 55
     @staticmethod
35
-    def _get_direction_of_pheromone(context, point, pheromone_type):
36
-        search_pheromone_in_points = context.get_around_points_of_point(point)
56
+    def _get_direction_of_molecule(context, point, molecule_type):
57
+        search_molecule_in_points = context.get_around_points_of_point(point)
37 58
         try:
38
-            best_pheromone_direction = DirectionPheromone.get_best_pheromone_direction_in(context,
39
-                                                                                          point,
40
-                                                                                          search_pheromone_in_points,
41
-                                                                                          pheromone_type)
42
-            return best_pheromone_direction
43
-        except NoPheromone as err:
59
+            best_molecule_direction = DirectionMolecule.get_best_molecule_direction_in(context,
60
+                                                                                       point,
61
+                                                                                       search_molecule_in_points,
62
+                                                                                       molecule_type)
63
+            return best_molecule_direction
64
+        except NoMolecule as err:
44 65
             raise err
45 66
 
46
-    def done(self, obj, context):
47
-        super().done(obj, context)
48
-        self._appose_pheromone(obj)
67
+    @classmethod
68
+    def _get_direction_with_exploration_vector(cls, context, object_id):
69
+        ant_star = cls._get_by_pass_brain(context, object_id)
70
+        ant_star.advance()
71
+        return ant_star.get_host().get_moved_to_direction()
49 72
 
50
-    @staticmethod
51
-    def _appose_pheromone(obj):
52
-        if obj.get_movement_pheromone_gland().is_enabled():
53
-            obj.get_movement_pheromone_gland().appose()
73
+    @classmethod
74
+    def _get_by_pass_brain(cls, context, object_id):
75
+        # We use an adaptation of AntStar
76
+        exploration_vector = context.metas.value.get(EXPLORATION_VECTOR, object_id)
77
+        home_vector = (-exploration_vector[0], -exploration_vector[1])
78
+        ant_host = Host(context, object_id)
79
+        return ByPass(ant_host, home_vector, context, object_id)
80
+
81
+    def done(self):
82
+        super().done()
83
+        self._appose_molecule()
84
+        self._check_context()
85
+        self._apply_context()
86
+
87
+    def _appose_molecule(self):
88
+        if self._host.get_movement_molecule_gland().is_enabled():
89
+            self._host.get_movement_molecule_gland().appose()
90
+
91
+    def _check_context(self):
92
+        """
93
+
94
+        If was in exploration, and just found home smell;
95
+            -> home mode (then, in this mode: no update vector, put food if food, etc)
96
+        If was in home, and just loose home smell:
97
+            -> exploration mode
98
+
99
+        :param obj:
100
+        :param context:
101
+        :return:
102
+        """
103
+        movement_mode = self._host_brain.get_movement_mode()
104
+
105
+        if movement_mode == MODE_GOHOME and self._on_home_smell(self._context, self._host.get_id()):
106
+            self._arrived_at_home()
107
+
108
+        elif movement_mode == MODE_HOME and not self._on_home_smell(self._context, self._host.get_id()):
109
+            self._start_new_exploration()
110
+
111
+        elif movement_mode == MODE_EXPLO and self._on_home_smell(self._context, self._host.get_id()):
112
+            self._init_exploration_vector()
113
+
114
+        # TODO: sitch explo si rien a faire (rien a poser par exemple) et HOME
115
+
116
+    @classmethod
117
+    def _on_home_smell(cls, context, object_id):
118
+        current_position = context.metas.value.get(POSITION, object_id)
119
+        flavour = context.molecules().get_flavour(current_position)
120
+        molecules = flavour.get_molecules_types(MOLECULES_DIRECTION)
121
+
122
+        if not molecules:
123
+            return False
124
+
125
+        brain_class = get_brain_class(context, object_id)
126
+        for smell_type in brain_class.get_home_smells():
127
+            if smell_type in molecules:
128
+                return True
129
+
130
+        return False
131
+
132
+    def _update_exploration_vector(self):
133
+        just_move_vector = directions_modifiers[self._host_brain.get_host().get_previous_direction()]
134
+        self._set_exploration_vector((self._exploration_vector[0] + just_move_vector[1],
135
+                                      self._exploration_vector[1] + just_move_vector[2]))
136
+
137
+    def _apply_context(self):
138
+        movement_mode = self._host_brain.get_movement_mode()
139
+        if movement_mode == MODE_EXPLO or movement_mode == MODE_GOHOME:
140
+            self._update_exploration_vector()
141
+
142
+    def _start_new_exploration(self):
143
+        self._init_exploration_vector()
144
+        self._host_brain.switch_to_mode(MODE_EXPLO)
145
+
146
+    def _init_exploration_vector(self):
147
+        # On vient de rentrer dans le monde exterieur, le vecteur de départ pointe vers la case précedente
148
+        # qui est une case dans la forteresse.
149
+        init_exploration_vector = get_position_with_direction_decal(self.get_host().get_previous_direction())
150
+        self._set_exploration_vector(init_exploration_vector)
54 151
 
152
+    def _arrived_at_home(self):
153
+        self._host_brain.switch_to_mode(MODE_HOME)
154
+        ant_star = self._get_by_pass_brain(self._context, self._host.get_id())
155
+        ant_star.erase()

+ 64 - 0
intelligine/simulation/object/brain/part/move/AntStar/ByPass.py View File

@@ -0,0 +1,64 @@
1
+from antstar.GlueWallAntBrain import GlueWallAntBrain
2
+from intelligine.cst import EXPLORATION_VECTOR, MOVE_BYBASS, MOVE_BYBASS_DISTANCE, MOVE_BYBASS_MEMORY, MOVE_BYBASS_WALL, MOVE_BYBASS_RE_WALKING
3
+
4
+
5
+class ByPass(GlueWallAntBrain):
6
+
7
+    def __init__(self, host, home_vector, context, object_id):
8
+        """
9
+
10
+        Note: We broke Liskov principle here.
11
+
12
+        :param host:
13
+        :param home_vector:
14
+        :param context:
15
+        :param object_id:
16
+        :return:
17
+        """
18
+        super().__init__(host, home_vector)
19
+        self._context = context
20
+        self._object_id = object_id
21
+        self._memory_since_blocked = context.metas.value.get(MOVE_BYBASS_MEMORY,
22
+                                                             object_id,
23
+                                                             allow_empty=True,
24
+                                                             empty_value=[])
25
+        self._by_passing = context.metas.value.get(MOVE_BYBASS,
26
+                                                   object_id,
27
+                                                   allow_empty=True,
28
+                                                   empty_value=False)
29
+        self._distance_when_blocked = context.metas.value.get(MOVE_BYBASS_DISTANCE,
30
+                                                              object_id,
31
+                                                              allow_empty=True,
32
+                                                              empty_value=None)
33
+        self._current_wall_square_position = context.metas.value.get(MOVE_BYBASS_WALL,
34
+                                                                     object_id,
35
+                                                                     allow_empty=True,
36
+                                                                     empty_value=None)
37
+        self._is_re_walking = context.metas.value.get(MOVE_BYBASS_RE_WALKING,
38
+                                                      object_id,
39
+                                                      allow_empty=True,
40
+                                                      empty_value=False)
41
+
42
+    def _set_home_vector(self, home_vector):
43
+        super()._set_home_vector(home_vector)
44
+        self._context.metas.value.set(EXPLORATION_VECTOR, self._object_id, home_vector)
45
+
46
+    def _set_memory_since_blocked(self, memory_since_blocked):
47
+        super()._set_memory_since_blocked(memory_since_blocked)
48
+        self._context.metas.value.set(MOVE_BYBASS_MEMORY, self._object_id, memory_since_blocked)
49
+
50
+    def _set_by_passing(self, by_passing):
51
+        super()._set_by_passing(by_passing)
52
+        self._context.metas.value.set(MOVE_BYBASS, self._object_id, by_passing)
53
+
54
+    def _set_distance_when_blocked(self, distance):
55
+        super()._set_distance_when_blocked(distance)
56
+        self._context.metas.value.set(MOVE_BYBASS_DISTANCE, self._object_id, distance)
57
+
58
+    def _set_current_wall_square(self, position_of_square):
59
+        super()._set_current_wall_square(position_of_square)
60
+        self._context.metas.value.set(MOVE_BYBASS_WALL, self._object_id, position_of_square)
61
+
62
+    def _set_is_re_walking(self, is_re_walking):
63
+        super()._set_is_re_walking(is_re_walking)
64
+        self._context.metas.value.set(MOVE_BYBASS_RE_WALKING, self._object_id, is_re_walking)

+ 26 - 0
intelligine/simulation/object/brain/part/move/AntStar/Host.py View File

@@ -0,0 +1,26 @@
1
+from intelligine.simulation.object.brain.part.move.AntStar.HostFeeler import HostFeeler
2
+from intelligine.synergy.event.move.direction import get_position_with_direction_decal
3
+from synergine_xyz.cst import POSITION
4
+
5
+
6
+class Host:
7
+
8
+    def __init__(self, context, object_id):
9
+        self._context = context
10
+        self._object_id = object_id
11
+        self._feeler = HostFeeler(context, object_id)
12
+        self._moved_to_direction = None
13
+        self._position_3d = self._context.metas.value.get(POSITION, self._object_id)
14
+
15
+    def get_position(self):
16
+        return self._position_3d[1], self._position_3d[2]
17
+
18
+    def get_feeler(self):
19
+        return self._feeler
20
+
21
+    def move_to(self, direction):
22
+        self._moved_to_direction = direction
23
+        self._position_3d = get_position_with_direction_decal(direction, self._position_3d)
24
+
25
+    def get_moved_to_direction(self):
26
+        return self._moved_to_direction

+ 24 - 0
intelligine/simulation/object/brain/part/move/AntStar/HostFeeler.py View File

@@ -0,0 +1,24 @@
1
+from intelligine.synergy.event.move.direction import get_position_with_direction_decal
2
+from synergine_xyz.cst import POSITION
3
+from synergine_xyz.geometry import distance_from_points
4
+
5
+
6
+class HostFeeler:
7
+
8
+    def __init__(self, context, object_id):
9
+        self._context = context
10
+        self._object_id = object_id
11
+        self._current_position = context.metas.value.get(POSITION, self._object_id)
12
+
13
+    def direction_is_free(self, direction_of_home):
14
+        position_will_be = get_position_with_direction_decal(direction_of_home, self._current_position)
15
+        return self._context.position_is_penetrable(position_will_be)
16
+
17
+    def position_is_free(self, position):
18
+        threed_position = (0, position[0], position[1])
19
+        points_distance = distance_from_points(threed_position, self._current_position)
20
+        if points_distance > 1:
21
+            raise Exception("Can't feel so far (%s to %s: %s)" % (str(self._current_position),
22
+                                                                  str(position),
23
+                                                                  str(points_distance)))
24
+        return self._context.position_is_penetrable(threed_position)

+ 27 - 17
intelligine/simulation/object/brain/part/transport/AntPutBrainPart.py View File

@@ -1,22 +1,34 @@
1
+from intelligine.synergy.object.Food import Food
2
+from synergine.core.Core import Core
1 3
 from intelligine.core.exceptions import CantFindWhereToPut
2
-from intelligine.cst import MOVE_MODE_EXPLO, TYPE_RESOURCE_EXPLOITABLE, CARRIED
4
+from intelligine.cst import MODE_EXPLO, TYPE_RESOURCE_EXPLOITABLE, MODE_NURSE, TYPE_NURSERY, \
5
+    MODE_HOME, TYPE_RESOURCE_EATABLE, MODE_GOHOME, CARRY
3 6
 from intelligine.simulation.object.brain.part.transport.TransportBrainPart import TransportBrainPart
4
-from intelligine.synergy.object.Food import Food
5 7
 from synergine_xyz.cst import POSITION, POSITIONS
6 8
 
7 9
 
8 10
 class AntPutBrainPart(TransportBrainPart):
9 11
 
10
-    # TODO: methode __nit_ pour la classe ?
11
-    _mode_matches = {
12
-        MOVE_MODE_EXPLO: [TYPE_RESOURCE_EXPLOITABLE],
12
+    _mode_matches = TransportBrainPart._mode_matches.copy()
13
+    _mode_matches.update({
14
+        MODE_NURSE: [TYPE_NURSERY],
15
+        MODE_HOME: [TYPE_RESOURCE_EATABLE],
16
+        MODE_GOHOME: []
17
+    })
18
+
19
+    _types_matches = {
20
+        TYPE_RESOURCE_EXPLOITABLE: [TYPE_RESOURCE_EATABLE],
21
+        TYPE_NURSERY: [TYPE_NURSERY]
13 22
     }
14 23
 
15 24
     @classmethod
16 25
     def can_put(cls, context, object_id, object_near_id):
17
-        object_carried_id = context.metas.value.get(CARRIED, object_id)
18
-        #  Pour le moment on considere qu'un objet peut-etre depose a cote d'un objet qui a un type identique
19
-        return cls._objects_have_same_type(context, object_carried_id, object_near_id)
26
+        # Si l'objet à coté fait partie des objets concernés par le mode du porteur
27
+        if cls._match_with_mode(context, object_id, object_near_id):
28
+            # Et si les objet sont rangeable enssemble:
29
+            object_carried_id = context.metas.value.get(CARRY, object_id)
30
+            return cls._objects_types_match(context, object_carried_id, object_near_id)
31
+        return False
20 32
 
21 33
     @classmethod
22 34
     def get_put_position(cls, context, object_id, object_near_id):
@@ -44,17 +56,15 @@ class AntPutBrainPart(TransportBrainPart):
44 56
 
45 57
     @staticmethod
46 58
     def _is_available_position(context, position):
47
-        # TODO: Pour le moment on ne regarde pas si ce sont tous des obj identique
59
+        if not context.position_is_penetrable(position):
60
+            return False
61
+
48 62
         count_obj_here = len(context.metas.list.get(POSITIONS, position, allow_empty=True))
49
-        # TODO: 5 est hardcode; de plus cette cntrainte (not brain) devrait dependre de l'objet, du contexte ...
50
-        if count_obj_here <= 5 and (context.position_is_penetrable(position) or position == (0, 0, 0)):  # TODO TEST !!!
63
+        if count_obj_here <= Core.get_configuration_manager().get('ant.put.max_objects_at_same_position', 5):
51 64
             return True
52 65
         return False
53 66
 
54
-    def done(self, obj, puted_object, context):
55
-        # TODO: Il faut refact/logique qqpart pour ca !! Genre Brain.done(PUT, ??)
67
+    def done(self, puted_object):
68
+        # TODO: lancer le choix d'un nouveau mode dans le brain.
56 69
         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
-
70
+            self._host.get_brain().switch_to_mode(MODE_EXPLO)

+ 19 - 8
intelligine/simulation/object/brain/part/transport/AntTakeBrainPart.py View File

@@ -1,25 +1,36 @@
1 1
 from intelligine.simulation.object.brain.part.transport.TakeBrainPart import TakeBrainPart
2 2
 from intelligine.synergy.object.ressource.Ressource import Resource
3
-from intelligine.cst import MOVE_MODE_EXPLO, TYPE_RESOURCE_EXPLOITABLE, \
4
-    MOVE_MODE_GOHOME, MOVE_MODE_NURSE, TYPE_NURSERY
3
+from intelligine.cst import MODE_EXPLO, TYPE_RESOURCE_EXPLOITABLE, \
4
+    MODE_GOHOME, MODE_NURSE, TYPE_NURSERY, MODE_HOME
5 5
 
6 6
 
7 7
 class AntTakeBrainPart(TakeBrainPart):
8 8
 
9 9
     # TODO: methode __init_ pour la classe ? Pour surcharger ici.
10 10
     _mode_matches = {
11
-        MOVE_MODE_EXPLO: [TYPE_RESOURCE_EXPLOITABLE],
12
-        MOVE_MODE_NURSE: [TYPE_NURSERY],
13
-        MOVE_MODE_GOHOME: []
11
+        MODE_EXPLO: [TYPE_RESOURCE_EXPLOITABLE],
12
+        MODE_NURSE: [TYPE_NURSERY],
13
+        MODE_GOHOME: []
14 14
     }
15 15
 
16
+    def __init__(self, host_brain):
17
+        super().__init__(host_brain)
18
+        self._smell_target = None
19
+
20
+    def get_smell_target(self):
21
+        if not self._smell_target:
22
+            raise Exception('No _smell_target')
23
+        return self._smell_target
24
+
16 25
     @classmethod
17 26
     def can_take(cls, context, object_id, object_to_take_id):
18 27
         # Pour le moment si le type de l'objet fait partie des types admis pour le mode courant du porteur, c'est bon.
19 28
         return cls._match_with_mode(context, object_id, object_to_take_id)
20 29
 
21
-    def done(self, obj, take_object, context):
30
+    def done(self, take_object):
22 31
         # TODO: Ranger ca ? Truc plus dynamique/configurable ?
32
+        # TODO: qqch plus generique ... (attention aux eggs)
23 33
         if isinstance(take_object, Resource):
24
-            obj.get_brain().switch_to_mode(MOVE_MODE_GOHOME)
25
-            obj.get_movement_pheromone_gland().appose()
34
+            self._smell_target = self._host_brain.get_smell_for_object_taken(take_object)
35
+            self._host.get_brain().switch_to_mode(MODE_GOHOME)
36
+            self._host.get_movement_molecule_gland().appose()

+ 25 - 8
intelligine/simulation/object/brain/part/transport/TransportBrainPart.py View File

@@ -1,23 +1,40 @@
1
-from intelligine.cst import MOVE_MODE, TYPE
1
+from intelligine.cst import MODE, TYPE
2 2
 from intelligine.simulation.object.brain.part.BrainPart import BrainPart
3 3
 
4 4
 
5 5
 class TransportBrainPart(BrainPart):
6 6
 
7 7
     _mode_matches = {}
8
+    _types_matches = {}
8 9
 
9 10
     @classmethod
10 11
     def _match_with_mode(cls, context, object_id, concerned_object_id):
11
-        move_mode = context.metas.value.get(MOVE_MODE, object_id)
12
+        move_mode = context.metas.value.get(MODE, object_id)
12 13
         for takable_type in cls._mode_matches[move_mode]:
13 14
             if context.metas.list.have(TYPE, concerned_object_id, takable_type, allow_empty=True):
14 15
                 return True
15 16
         return False
16 17
 
17 18
     @classmethod
18
-    def _objects_have_same_type(cls, context, object_carried_id, object_to_put_id):
19
-        object_carried_types = context.metas.list.get(TYPE, object_carried_id)
20
-        for object_carried_type in object_carried_types:
21
-            if context.metas.list.have(TYPE, object_to_put_id, object_carried_type):
22
-                return True
23
-        return False
19
+    def _objects_types_match(cls, context, object_a_id, object_b_id):
20
+        """
21
+
22
+        Retourne vrai si un des type de l'objet b se trouve dans la lise de type définis dans _types_matches pour
23
+        l'un des types de l'objet a.
24
+
25
+        :param context:
26
+        :param object_a_id:
27
+        :param object_b_id:
28
+        :return: bool
29
+        """
30
+        object_a_types = context.metas.list.get(TYPE, object_a_id)
31
+        object_b_types = context.metas.list.get(TYPE, object_b_id)
32
+
33
+        for object_a_type in object_a_types:
34
+            if object_a_type in cls._types_matches:
35
+                wanted_types = cls._types_matches[object_a_type]
36
+                for object_b_type in object_b_types:
37
+                    if object_b_type in wanted_types:
38
+                        return True
39
+
40
+        return False

+ 42 - 0
intelligine/simulation/object/molecule/MoleculeGland.py View File

@@ -0,0 +1,42 @@
1
+from intelligine.core.exceptions import BestMoleculeHere, MoleculeGlandDisabled
2
+from intelligine.simulation.molecule.DirectionMolecule import DirectionMolecule
3
+
4
+
5
+class MoleculeGland():
6
+
7
+    def __init__(self, host, context):
8
+        self._molecule_type = None
9
+        self._host = host
10
+        self._context = context
11
+        self._enabled = False
12
+
13
+    def set_molecule_type(self, molecule_type):
14
+        self._molecule_type = molecule_type
15
+
16
+    def get_molecule_type(self):
17
+        if self._molecule_type is None:
18
+            raise Exception("molecule_type not specified")
19
+        return self._molecule_type
20
+
21
+    def get_molecule(self):
22
+        raise NotImplementedError()
23
+
24
+    def appose(self):
25
+        if not self._enabled:
26
+            raise MoleculeGlandDisabled()
27
+
28
+        try:
29
+            DirectionMolecule.appose(self._context,
30
+                                     self._host.get_position(),
31
+                                     self.get_molecule())
32
+        except BestMoleculeHere as best_molecule_here:
33
+            self._host.get_brain().set_distance_from_objective(best_molecule_here.get_best_distance())
34
+
35
+    def disable(self):
36
+        self._enabled = False
37
+
38
+    def enable(self):
39
+        self._enabled = True
40
+
41
+    def is_enabled(self):
42
+        return self._enabled

+ 15 - 0
intelligine/simulation/object/molecule/MovementMoleculeGland.py View File

@@ -0,0 +1,15 @@
1
+from intelligine.cst import MOLECULES_DIRECTION
2
+from intelligine.simulation.object.molecule.MoleculeGland import MoleculeGland
3
+from intelligine.simulation.molecule.Molecule import Molecule
4
+
5
+
6
+class MovementMoleculeGland(MoleculeGland):
7
+
8
+    def get_molecule(self):
9
+        """
10
+        :return: Molecule
11
+        """
12
+        return Molecule(MOLECULES_DIRECTION,
13
+                        self._molecule_type,
14
+                        self._host.get_brain().get_distance_from_objective(),
15
+                        1)

+ 0 - 12
intelligine/simulation/object/pheromone/MovementPheromoneGland.py View File

@@ -1,12 +0,0 @@
1
-from intelligine.cst import PHEROMON_DIRECTION
2
-from intelligine.simulation.object.pheromone.PheromoneGland import PheromoneGland
3
-from intelligine.simulation.pheromone.Pheromone import Pheromone
4
-
5
-
6
-class MovementPheromoneGland(PheromoneGland):
7
-
8
-    def get_pheromone(self):
9
-        """
10
-        :return: pheromone_type, distance_from_objective
11
-        """
12
-        return Pheromone(PHEROMON_DIRECTION, self._pheromone_type, self._host.get_brain().get_distance_from_objective(), 1)

+ 0 - 41
intelligine/simulation/object/pheromone/PheromoneGland.py View File

@@ -1,41 +0,0 @@
1
-from intelligine.core.exceptions import BestPheromoneHere, PheromoneGlandDisabled
2
-from intelligine.simulation.pheromone.DirectionPheromone import DirectionPheromone
3
-
4
-class PheromoneGland():
5
-
6
-    def __init__(self, host, context):
7
-        self._pheromone_type = None
8
-        self._host = host
9
-        self._context = context
10
-        self._enabled = False
11
-
12
-    def set_pheromone_type(self, pheromone_type):
13
-        self._pheromone_type = pheromone_type
14
-
15
-    def get_pheromone_type(self):
16
-        if self._pheromone_type is None:
17
-            raise Exception("pheromone_type not specified")
18
-        return self._pheromone_type
19
-
20
-    def get_pheromone(self):
21
-        raise NotImplementedError()
22
-
23
-    def appose(self):
24
-        if not self._enabled:
25
-            raise PheromoneGlandDisabled()
26
-
27
-        try:
28
-            DirectionPheromone.appose(self._context,
29
-                                      self._host.get_position(),
30
-                                      self.get_pheromone())
31
-        except BestPheromoneHere as best_pheromone_here:
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

+ 0 - 85
intelligine/simulation/pheromone/DirectionPheromone.py View File

@@ -1,85 +0,0 @@
1
-from intelligine.cst import PHEROMON_DIRECTION, PHEROMON_POSITIONS
2
-from intelligine.core.exceptions import NoPheromone
3
-from random import shuffle
4
-from synergine_xyz.geometry import get_degree_from_north
5
-from intelligine.synergy.event.move.direction import get_direction_for_degrees
6
-
7
-
8
-class DirectionPheromone():
9
-
10
-    @staticmethod
11
-    def appose(context, point, pheromone):
12
-        context.pheromones().increment_with_pheromone(point, pheromone)
13
-        context.metas.list.add(PHEROMON_POSITIONS, PHEROMON_POSITIONS, point, assert_not_in=False)
14
-
15
-    @classmethod
16
-    def get_direction_for_point(cls, context, point, pheromone_type):
17
-        flavour = context.pheromones().get_flavour(point)
18
-        pheromone = flavour.get_pheromone(category=PHEROMON_DIRECTION, type=pheromone_type)
19
-
20
-        distance = pheromone.get_distance()
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)
24
-
25
-        if not around_pheromones_points:
26
-            raise NoPheromone()
27
-
28
-        shuffle(around_pheromones_points)
29
-        around_pheromones_sorted = sorted(around_pheromones_points, key=lambda x: x[1].get_intensity(), reverse=True)
30
-        max_intensity = around_pheromones_sorted[0][1].get_intensity()
31
-
32
-        around_pheromones_max = []
33
-        for around_pheromone_sorted in around_pheromones_sorted:
34
-            if around_pheromone_sorted[1].get_intensity() == max_intensity:
35
-                around_pheromones_max.append(around_pheromone_sorted)
36
-
37
-        around_pheromones_sorted_by_distance = sorted(around_pheromones_max,
38
-                                                      key=lambda x: x[1].get_distance(),
39
-                                                      reverse=False)
40
-
41
-        go_to_point = around_pheromones_sorted_by_distance[0][0]
42
-
43
-        direction_degrees = get_degree_from_north(point, go_to_point)
44
-        direction = get_direction_for_degrees(direction_degrees)
45
-
46
-        return direction
47
-
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_point(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
65
-    def get_best_pheromone_direction_in(context, reference_point, points, pheromone_type):
66
-        around_pheromones_points = []
67
-        for around_point in points:
68
-            flavour = context.pheromones().get_flavour(around_point)
69
-            try:
70
-                around_pheromone = flavour.get_pheromone(category=PHEROMON_DIRECTION, type=pheromone_type)
71
-                around_pheromones_points.append((around_point, around_pheromone))
72
-            except NoPheromone:
73
-                pass  # Ok, no pheromone, continue to sniff around
74
-
75
-        if not around_pheromones_points:
76
-            raise NoPheromone()
77
-
78
-        shuffle(around_pheromones_points)
79
-        around_pheromones_sorted = sorted(around_pheromones_points, key=lambda x: x[1].get_intensity(), reverse=True)
80
-        go_to_point = around_pheromones_sorted[0][0]
81
-
82
-        direction_degrees = get_degree_from_north(reference_point, go_to_point)
83
-        direction = get_direction_for_degrees(direction_degrees)
84
-
85
-        return direction

+ 0 - 51
intelligine/simulation/pheromone/PheromoneFlavour.py View File

@@ -1,51 +0,0 @@
1
-from intelligine.core.exceptions import NoTypeInPheromone, NoCategoryInPheromone
2
-from intelligine.simulation.pheromone.Pheromone import Pheromone
3
-
4
-
5
-class PheromoneFlavour():
6
-
7
-    @classmethod
8
-    def new_from_raw_data(cls, raw_data):
9
-        flavour = {}
10
-        for category in raw_data:
11
-            pheromones_by_category = raw_data[category]
12
-            for type in pheromones_by_category:
13
-                distance, intensity = pheromones_by_category[type]
14
-                if category not in flavour:
15
-                    flavour[category] = {}
16
-                flavour[category][type] = Pheromone(category, type, distance, intensity)
17
-        return cls(flavour)
18
-
19
-    def get_raw_data(self):
20
-        raw_data = {}
21
-        for category in self._flavour:
22
-            pheromones_by_category = self._flavour[category]
23
-            for type in pheromones_by_category:
24
-                pheromone = pheromones_by_category[type]
25
-                if category not in raw_data:
26
-                    raw_data[category] = {}
27
-                raw_data[category][type] = (pheromone.get_distance(), pheromone.get_intensity())
28
-        return raw_data
29
-
30
-    def __init__(self, flavour):
31
-        self._flavour = flavour
32
-
33
-    def get_pheromone(self, category, type):
34
-        types = self.get_types(category)
35
-        if type not in types:
36
-            raise NoTypeInPheromone()
37
-        return types[type]
38
-
39
-    def get_types(self, category):
40
-        if category not in self._flavour:
41
-            raise NoCategoryInPheromone()
42
-        return self._flavour[category]
43
-
44
-    def set_pheromone(self, pheromone):
45
-        category = pheromone.get_category()
46
-        type = pheromone.get_type()
47
-
48
-        if category not in self._flavour:
49
-            self._flavour[category] = {}
50
-
51
-        self._flavour[category][type] = pheromone

+ 29 - 1
intelligine/synergy/Simulation.py View File

@@ -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 - 5
intelligine/synergy/event/Event.py View File

@@ -3,8 +3,4 @@ from intelligine.cst import BRAIN_SCHEMA
3 3
 
4 4
 
5 5
 class Event(BaseEvent):
6
-
7
-    @classmethod
8
-    def _get_brain_part(cls, context, object_id, brain_part_name):
9
-        object_brain_schema = context.metas.value.get(BRAIN_SCHEMA, object_id)
10
-        return object_brain_schema[brain_part_name]
6
+    pass

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

@@ -1,4 +1,5 @@
1 1
 from intelligine.core.exceptions import NearNothingFound
2
+from intelligine.shorcut.brain import get_brain_part
2 3
 from synergine.core.exceptions import NotConcernedEvent
3 4
 from intelligine.synergy.event.src.NearEvent import NearEvent
4 5
 from synergine_xyz.mechanism.AroundMechanism import AroundMechanism
@@ -22,7 +23,7 @@ class NearAttackableEvent(NearEvent):
22 23
         except NearNothingFound:
23 24
             raise NotConcernedEvent()
24 25
 
25
-        brain_part = self._get_brain_part(context, object_id, BRAIN_PART_ATTACK)
26
+        brain_part = get_brain_part(context, object_id, BRAIN_PART_ATTACK)
26 27
         if not brain_part.can_attack(context, object_id, parameters[self._near_name][0]):
27 28
             raise NotConcernedEvent()
28 29
 

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

@@ -29,4 +29,4 @@ class MoveAction(Action):
29 29
 
30 30
         obj.set_position(self._parameters[MoveEvent.PARAM_POSITION])
31 31
         obj.set_previous_direction(self._parameters[MoveEvent.PARAM_DIRECTION])
32
-        obj.get_brain().get_part(BRAIN_PART_MOVE).done(obj, context)
32
+        obj.get_brain().get_part(BRAIN_PART_MOVE).done()

+ 2 - 2
intelligine/synergy/event/move/MoveEvent.py View File

@@ -1,5 +1,6 @@
1 1
 from intelligine.core.exceptions import UnableToFoundMovement
2 2
 from intelligine.synergy.event.move.direction import get_position_with_direction_decal
3
+from intelligine.shorcut.brain import get_brain_part
3 4
 from synergine.core.exceptions import NotConcernedEvent
4 5
 from intelligine.synergy.event.Event import Event
5 6
 from synergine.core.simulation.mechanism.Mechanism import Mechanism
@@ -31,8 +32,7 @@ class MoveEvent(Event):
31 32
         return parameters
32 33
 
33 34
     def _get_direction(self, object_id, context):
34
-        object_brain_schema = context.metas.value.get(BRAIN_SCHEMA, object_id)
35
-        object_move_brain_part = object_brain_schema[BRAIN_PART_MOVE]
35
+        object_move_brain_part = get_brain_part(context, object_id, BRAIN_PART_MOVE)
36 36
         return object_move_brain_part.get_direction(context, object_id)
37 37
 
38 38
     @staticmethod

+ 5 - 1
intelligine/synergy/event/move/direction.py View File

@@ -17,6 +17,9 @@ directions = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20,
17 17
 directions_under_level = (1, 2, 3, 4, 5, 6, 7, 8, 9)
18 18
 directions_same_level = (10, 11, 12, 13, 15, 16, 17, 18)
19 19
 directions_upper_level = (19, 20, 21, 22, 23, 24, 25, 26, 27)
20
+
21
+directions_by_levels = (directions_under_level, directions_same_level, directions_upper_level)
22
+
20 23
 directions_modifiers = {
21 24
     # (z, x, y)
22 25
     1: (-1, -1, -1),
@@ -117,6 +120,7 @@ directions_degrees = {
117 120
     (202.5, 247.5): 16,
118 121
     (247.5, 292.5): 13,
119 122
     (292.5, 337.5): 10,
123
+    (337.5, 360): 11,
120 124
     (337.5, 0): 11
121 125
 }
122 126
 
@@ -127,7 +131,7 @@ def get_direction_for_degrees(degrees):
127 131
     for plage in directions_degrees:
128 132
         if plage[0] <= degrees <= plage[1]:
129 133
             return directions_degrees[plage]
130
-    raise Exception("Unknow plage for degree \"" + degrees + '"')
134
+    raise Exception("Unknow plage for degree \"" + str(degrees) + '"')
131 135
 
132 136
 
133 137
 """

+ 30 - 18
intelligine/synergy/event/smell/SmellAction.py View File

@@ -1,4 +1,9 @@
1
-from intelligine.cst import POINT_SMELL, POINTS_SMELL
1
+from intelligine.core.exceptions import BestMoleculeHere
2
+from intelligine.cst import POINT_SMELL, POINTS_SMELL, MOLECULES_INFOS, MOLECULES_DIRECTION, SMELL_FOOD, SMELL_EGG, \
3
+    PHEROMON_DIR_EXPLO
4
+from intelligine.simulation.molecule.DirectionMolecule import DirectionMolecule
5
+from intelligine.simulation.molecule.Evaporation import Evaporation
6
+from intelligine.simulation.molecule.Molecule import Molecule
2 7
 from intelligine.synergy.event.smell.SmellEvent import SmellEvent
3 8
 from synergine.synergy.event.Action import Action
4 9
 
@@ -9,10 +14,8 @@ class SmellAction(Action):
9 14
 
10 15
     @classmethod
11 16
     def cycle_pre_run(cls, context, synergy_manager):
12
-        smell_positions = context.metas.list.get(POINTS_SMELL, POINTS_SMELL, allow_empty=True)
13
-        for smell_position in smell_positions:
14
-            context.metas.value.unset(POINT_SMELL, smell_position)
15
-        context.metas.list.unset(POINTS_SMELL, POINTS_SMELL, allow_empty=True)
17
+        evaporation = Evaporation(context, molecules_include_types=[SMELL_FOOD, SMELL_EGG])
18
+        evaporation.remove()
16 19
 
17 20
     def run(self, obj, context, synergy_manager):
18 21
 
@@ -20,16 +23,25 @@ class SmellAction(Action):
20 23
         smell_type = obj.get_smell()
21 24
 
22 25
         for smell_point in points_distances:
23
-
24
-            where_to_put_smells = context.metas.value.get(POINT_SMELL, smell_point, allow_empty=True, empty_value={})
25
-            current_point_smell = points_distances[smell_point]
26
-
27
-            if smell_type not in where_to_put_smells:
28
-                where_to_put_smells[smell_type] = current_point_smell
29
-            else:
30
-                where_to_put_smell = where_to_put_smells[smell_type]
31
-                if current_point_smell < where_to_put_smell:
32
-                    where_to_put_smells[smell_type] = where_to_put_smell
33
-
34
-            context.metas.value.set(POINT_SMELL, smell_point, where_to_put_smells)
35
-            context.metas.list.add(POINTS_SMELL, POINTS_SMELL, smell_point, assert_not_in=False)
26
+            distance = points_distances[smell_point]
27
+            molecule = Molecule(MOLECULES_DIRECTION, smell_type, distance)
28
+
29
+            try:
30
+                DirectionMolecule.appose(context, smell_point, molecule)
31
+            except BestMoleculeHere:
32
+                pass  # TODO: Pas l'inverse ? A voir apres avoir fix la disparition.
33
+
34
+            #
35
+            # current_point_smell = points_distances[smell_point]
36
+            # where_to_put_smells = context.metas.value.get(POINT_SMELL, smell_point, allow_empty=True, empty_value={})
37
+            #
38
+            #
39
+            # if smell_type not in where_to_put_smells:
40
+            #     where_to_put_smells[smell_type] = current_point_smell
41
+            # else:
42
+            #     where_to_put_smell = where_to_put_smells[smell_type]
43
+            #     if current_point_smell < where_to_put_smell:
44
+            #         where_to_put_smells[smell_type] = where_to_put_smell
45
+            #
46
+            # context.metas.value.set(POINT_SMELL, smell_point, where_to_put_smells)
47
+            # context.metas.list.add(POINTS_SMELL, POINTS_SMELL, smell_point, assert_not_in=False)

+ 6 - 2
intelligine/synergy/event/smell/SmellEvent.py View File

@@ -1,4 +1,4 @@
1
-from intelligine.cst import COL_SMELL
1
+from intelligine.cst import COL_SMELL, CARRIED_BY
2 2
 from intelligine.mechanism.TraversableDistanceFromMechanism import TraversableDistanceFromMechanism
3 3
 from intelligine.synergy.event.Event import Event
4 4
 from synergine.core.exceptions import NotConcernedEvent
@@ -12,7 +12,11 @@ class SmellEvent(Event):
12 12
     _first_cycle_force = True
13 13
 
14 14
     def _prepare(self, object_id, context, parameters={}):
15
-        if not parameters['points_distances']:
15
+        if not parameters['points_distances'] or not self._concerned_object(context, object_id):
16 16
             raise NotConcernedEvent()
17 17
 
18 18
         return parameters
19
+
20
+    def _concerned_object(self, context, object_id):
21
+        # TODO: Un peu hardcodé etant donné que cet event concerne tout les COL_SMELL et pas que les transportable ...
22
+        return not context.metas.value.get(CARRIED_BY, object_id, allow_empty=True, empty_value=False)

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

@@ -1,4 +1,5 @@
1 1
 from intelligine.synergy.event.move.MoveAction import MoveAction
2
+from intelligine.synergy.object.Food import Food
2 3
 from synergine.synergy.event.Action import Action
3 4
 from intelligine.synergy.event.transport.PutableEvent import PutableEvent
4 5
 from intelligine.cst import CANT_CARRY_STILL, BRAIN_PART_PUT
@@ -17,8 +18,15 @@ class PutableAction(Action):
17 18
         obj_transported = obj.get_carried()
18 19
 
19 20
         obj_transported.set_carried_by(None)
20
-        #  TODO: re controle de si posable ? (5 max etc)
21
+        #  TODO: re controle de si posable ? La position a été calculé
22
+        #  dans le process. Ce qui fait que la situation peut avoir changer.
23
+        # Soit: Recalculer d'office BrainPut.cant_put_at.. Soit le recalculer que si le hash
24
+        # de ce qu'il y a la a changer ?
21 25
         obj.put_carry(obj_transported, position_to_put)
22 26
         context.metas.value.set(CANT_CARRY_STILL, obj.get_id(), 5)
23 27
 
24
-        obj.get_brain().get_part(BRAIN_PART_PUT).done(obj, obj_transported, context)
28
+        obj.get_brain().get_part(BRAIN_PART_PUT).done(obj_transported)
29
+
30
+        # TODO: DEBUG
31
+        if isinstance(obj_transported, Food):
32
+            obj_transported.set_position((-1, 0, 0))

+ 3 - 2
intelligine/synergy/event/transport/PutableEvent.py View File

@@ -1,4 +1,5 @@
1 1
 from intelligine.core.exceptions import NearNothingFound, CantFindWhereToPut
2
+from intelligine.shorcut.brain import get_brain_part
2 3
 from intelligine.synergy.event.src.NearEvent import NearEvent
3 4
 from synergine.core.exceptions import NotConcernedEvent
4 5
 from intelligine.cst import CANT_PUT_STILL, COL_TRANSPORTER_CARRYING, TRANSPORTABLE, BRAIN_SCHEMA, BRAIN_PART_PUT
@@ -27,7 +28,7 @@ class PutableEvent(NearEvent):
27 28
             raise NotConcernedEvent()
28 29
 
29 30
         object_near_id = parameters[self._near_name][0]
30
-        brain_part = self._get_brain_part(context, object_id, BRAIN_PART_PUT)
31
+        brain_part = get_brain_part(context, object_id, BRAIN_PART_PUT)
31 32
 
32 33
         if not brain_part.can_put(context, object_id, object_near_id):
33 34
             raise NotConcernedEvent()
@@ -47,5 +48,5 @@ class PutableEvent(NearEvent):
47 48
 
48 49
     @classmethod
49 50
     def _object_can_put(cls, object_id, context, object_to_put_id):
50
-        object_take_brain_part = cls._get_brain_part(context, object_id, BRAIN_PART_PUT)
51
+        object_take_brain_part = get_brain_part(context, object_id, BRAIN_PART_PUT)
51 52
         return object_take_brain_part.can_put(context, object_id, object_to_put_id)

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

@@ -26,4 +26,4 @@ class TakeableAction(Action):
26 26
         obj.carry(obj_carried)
27 27
         cant_put_still = Core.get_configuration_manager().get('ant.take.cant_put_still')
28 28
         context.metas.value.set(CANT_PUT_STILL, obj.get_id(), cant_put_still)
29
-        obj.get_brain().get_part(BRAIN_PART_TAKE).done(obj, obj_carried, context)
29
+        obj.get_brain().get_part(BRAIN_PART_TAKE).done(obj_carried)

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

@@ -1,4 +1,5 @@
1 1
 from intelligine.core.exceptions import NearNothingFound
2
+from intelligine.shorcut.brain import get_brain_part
2 3
 from synergine.core.exceptions import NotConcernedEvent
3 4
 from intelligine.synergy.event.src.NearEvent import NearEvent
4 5
 from synergine_xyz.mechanism.AroundMechanism import AroundMechanism
@@ -34,5 +35,5 @@ class TakeableEvent(NearEvent):
34 35
 
35 36
     @classmethod
36 37
     def _object_can_take(cls, object_id, context, object_to_take_id):
37
-        object_take_brain_part = cls._get_brain_part(context, object_id, BRAIN_PART_TAKE)
38
-        return object_take_brain_part.can_take(context, object_id, object_to_take_id)
38
+        object_take_brain_part = get_brain_part(context, object_id, BRAIN_PART_TAKE)
39
+        return object_take_brain_part.can_take(context, object_id, object_to_take_id)

+ 4 - 5
intelligine/synergy/object/BaseBug.py View File

@@ -1,6 +1,6 @@
1 1
 from intelligine.core.exceptions import BodyPartAlreadyExist
2 2
 from intelligine.synergy.object.Transportable import Transportable
3
-from intelligine.cst import COL_ALIVE, COLONY, ACTION_DIE
3
+from intelligine.cst import COL_ALIVE, COLONY, ACTION_DIE, BRAIN
4 4
 from intelligine.simulation.object.brain.Brain import Brain
5 5
 from intelligine.cst import ALIVE, ATTACKABLE
6 6
 from synergine.core.Signals import Signals
@@ -9,6 +9,7 @@ from synergine.core.Signals import Signals
9 9
 class BaseBug(Transportable):
10 10
 
11 11
     _body_parts = {}
12
+    _brain_class = Brain
12 13
 
13 14
     def __init__(self, collection, context):
14 15
         super().__init__(collection, context)
@@ -18,7 +19,8 @@ class BaseBug(Transportable):
18 19
         self._life_points = 10
19 20
         self._alive = True
20 21
         self._movements_count = -1
21
-        self._brain = self._get_brain_instance()
22
+        self._brain = self._brain_class(self._context, self)
23
+        self._context.metas.value.set(BRAIN, self.__class__, self._brain_class)
22 24
         self._parts = {}
23 25
         self._init_parts()
24 26
 
@@ -62,8 +64,5 @@ class BaseBug(Transportable):
62 64
     def get_movements_count(self):
63 65
         return self._movements_count
64 66
 
65
-    def _get_brain_instance(self):
66
-        return Brain(self._context, self)
67
-
68 67
     def get_brain(self):
69 68
         return self._brain

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

@@ -1,5 +1,5 @@
1 1
 from intelligine.synergy.object.BaseBug import BaseBug
2
-from intelligine.cst import TYPE_NURSERY, TYPE, SMELL_EGG
2
+from intelligine.cst import TYPE_NURSERY, TYPE, SMELL_EGG, COL_SMELL
3 3
 
4 4
 
5 5
 class Egg(BaseBug):
@@ -8,4 +8,5 @@ class Egg(BaseBug):
8 8
         super().__init__(collection, context)
9 9
         context.metas.list.add(TYPE, self.get_id(), TYPE_NURSERY)
10 10
         self._life_points = 1
11
+        self._add_col(COL_SMELL)
11 12
         self._set_smell(SMELL_EGG)

+ 2 - 1
intelligine/synergy/object/StockedFood.py View File

@@ -1,4 +1,4 @@
1
-from intelligine.cst import TYPE, TYPE_RESOURCE_EXPLOITABLE, COL_EATABLE, COL_SMELL, SMELL_FOOD
1
+from intelligine.cst import TYPE, TYPE_RESOURCE_EXPLOITABLE, COL_EATABLE, COL_SMELL, SMELL_FOOD, TYPE_RESOURCE_EATABLE
2 2
 from intelligine.synergy.object.Food import Food
3 3
 
4 4
 
@@ -7,6 +7,7 @@ class StockedFood(Food):
7 7
     def __init__(self, collection, context):
8 8
         super().__init__(collection, context)
9 9
         context.metas.list.remove(TYPE, self.get_id(), TYPE_RESOURCE_EXPLOITABLE)
10
+        context.metas.list.add(TYPE, self.get_id(), TYPE_RESOURCE_EATABLE)
10 11
         self._add_col(COL_EATABLE)
11 12
         self._add_col(COL_SMELL)
12 13
         self._set_smell(SMELL_FOOD)

+ 4 - 1
intelligine/synergy/object/SynergyObject.py View File

@@ -1,4 +1,5 @@
1
-from intelligine.cst import OBJ_SMELL
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
 
@@ -7,10 +8,12 @@ class SynergyObject(XyzSynergyObject):
7 8
     def __init__(self, collection, context):
8 9
         super().__init__(collection, context)
9 10
         self._smell = None
11
+        context.metas.value.set(INSTANCE_CLASS, self.get_id(), self.__class__)
10 12
 
11 13
     def _set_smell(self, smell_type):
12 14
         self._smell = smell_type
13 15
         self._context.metas.value.set(OBJ_SMELL, self.get_id(), smell_type)
16
+        Simulation.add_smell(smell_type)
14 17
 
15 18
     def get_smell(self):
16 19
         if not self._smell:

+ 3 - 3
intelligine/synergy/object/Transportable.py View File

@@ -1,4 +1,4 @@
1
-from intelligine.cst import TRANSPORTABLE, CARRIED
1
+from intelligine.cst import TRANSPORTABLE, CARRIED_BY, CARRY
2 2
 from intelligine.synergy.object.SynergyObject import SynergyObject
3 3
 
4 4
 
@@ -34,6 +34,6 @@ class Transportable(SynergyObject):
34 34
     def set_is_carried(self, is_carried, by_obj):
35 35
         self._is_carried = bool(is_carried)
36 36
         if self._is_carried:
37
-            self._context.metas.value.set(CARRIED, subject=by_obj.get_id(), value=self.get_id())
37
+            self._context.metas.value.set(CARRIED_BY, self.get_id(), by_obj.get_id())
38 38
         else:
39
-            self._context.metas.value.unset(CARRIED, subject=by_obj.get_id())
39
+            self._context.metas.value.unset(CARRIED_BY, self.get_id())

+ 16 - 15
intelligine/synergy/object/ant/Ant.py View File

@@ -1,18 +1,19 @@
1
-from intelligine.core.exceptions import PheromoneException
1
+from intelligine.core.exceptions import MoleculeException
2 2
 from intelligine.synergy.object.Bug import Bug
3 3
 from intelligine.cst import CARRYING, TRANSPORTER, ATTACKER, COL_TRANSPORTER, COL_TRANSPORTER_NOT_CARRYING, \
4
-    COL_FIGHTER, MOVE_MODE_EXPLO, MOVE_MODE_GOHOME, BODY_PART_PHEROMONE_GLAND, TYPE, TYPE_ANT, \
5
-    COL_TRANSPORTER_CARRYING, MOVE_MODE_NURSE
4
+    COL_FIGHTER, MODE_EXPLO, MODE_GOHOME, BODY_PART_PHEROMONE_GLAND, TYPE, TYPE_ANT, \
5
+    COL_TRANSPORTER_CARRYING, MODE_NURSE, MODE_HOME, CARRY
6 6
 from intelligine.synergy.object.Food import Food
7
-from intelligine.simulation.object.pheromone.MovementPheromoneGland import MovementPheromoneGland
7
+from intelligine.simulation.object.molecule.MovementMoleculeGland import MovementMoleculeGland
8 8
 from intelligine.simulation.object.brain.AntBrain import AntBrain
9 9
 
10 10
 
11 11
 class Ant(Bug):
12 12
 
13 13
     _body_parts = {
14
-        BODY_PART_PHEROMONE_GLAND: MovementPheromoneGland
14
+        BODY_PART_PHEROMONE_GLAND: MovementMoleculeGland
15 15
     }
16
+    _brain_class = AntBrain
16 17
 
17 18
     def __init__(self, collection, context):
18 19
         super().__init__(collection, context)
@@ -21,7 +22,8 @@ class Ant(Bug):
21 22
                                                            COL_TRANSPORTER_NOT_CARRYING,
22 23
                                                            COL_FIGHTER])
23 24
         self._carried = None
24
-        self._brain.switch_to_mode(MOVE_MODE_EXPLO)
25
+        #  TODO: Comme pour lorsque une action put est faite, lancer un algo de choix de la mission a suivre.
26
+        self._brain.switch_to_mode(MODE_EXPLO)
25 27
         context.metas.list.add(TYPE, self.get_id(), TYPE_ANT)
26 28
 
27 29
     def die(self):
@@ -33,10 +35,7 @@ class Ant(Bug):
33 35
         self._remove_col(COL_TRANSPORTER_CARRYING, allow_not_in=True)
34 36
         self._remove_col(COL_FIGHTER)
35 37
 
36
-    def _get_brain_instance(self):
37
-        return AntBrain(self._context, self)
38
-
39
-    def get_movement_pheromone_gland(self):
38
+    def get_movement_molecule_gland(self):
40 39
         return self.get_body_part(BODY_PART_PHEROMONE_GLAND)
41 40
 
42 41
     def put_carry(self, obj, position=None):
@@ -46,6 +45,7 @@ class Ant(Bug):
46 45
         obj.set_position(position)
47 46
         obj.set_is_carried(False, self)
48 47
         self._context.metas.states.remove(self.get_id(), CARRYING)
48
+        self._context.metas.value.unset(CARRY, self.get_id())
49 49
         self._add_col(COL_TRANSPORTER_NOT_CARRYING)
50 50
         self._remove_col(COL_TRANSPORTER_CARRYING)
51 51
 
@@ -58,10 +58,11 @@ class Ant(Bug):
58 58
         self._add_col(COL_TRANSPORTER_CARRYING)
59 59
         self._remove_col(COL_TRANSPORTER_NOT_CARRYING)
60 60
         obj.set_is_carried(True, self)
61
+        self._context.metas.value.set(CARRY, self.get_id(), obj.get_id())
61 62
         # TODO: pour le moment hardcode, a gerer dans AntTakeBrainPart (callback en fct de ce qui est depose)
62 63
         if isinstance(obj, Food):
63
-            self.get_brain().switch_to_mode(MOVE_MODE_GOHOME)
64
-            self.get_movement_pheromone_gland().appose()
64
+            self.get_brain().switch_to_mode(MODE_GOHOME)
65
+            self.get_movement_molecule_gland().appose()
65 66
 
66 67
     def is_carrying(self):
67 68
         if self._carried:
@@ -77,10 +78,10 @@ class Ant(Bug):
77 78
 
78 79
     def initialize(self):
79 80
         super().initialize()
80
-        if self.get_movement_pheromone_gland().is_enabled():
81
+        if self.get_movement_molecule_gland().is_enabled():
81 82
             try:
82
-                self.get_movement_pheromone_gland().appose()
83
-            except PheromoneException:
83
+                self.get_movement_molecule_gland().appose()
84
+            except MoleculeException:
84 85
                 pass
85 86
 
86 87
     def get_colony(self):

+ 50 - 0
intelligine/synergy/stigmergy/MoleculesManager.py View File

@@ -0,0 +1,50 @@
1
+from intelligine.core.exceptions import BestMoleculeHere, NoMolecule
2
+from intelligine.cst import MOLECULES_INFOS
3
+from intelligine.simulation.molecule.MoleculeFlavour import MoleculeFlavour
4
+from intelligine.simulation.molecule.Molecule import Molecule
5
+
6
+
7
+class MoleculesManager():
8
+
9
+    def __init__(self, context):
10
+        self._context = context
11
+
12
+    def get_flavour(self, position):
13
+        point_molecules = self._context.metas.value.get(MOLECULES_INFOS,
14
+                                                        position,
15
+                                                        allow_empty=True,
16
+                                                        empty_value={})
17
+        return MoleculeFlavour.new_from_raw_data(point_molecules)
18
+
19
+    def set_flavour(self, position, flavour):
20
+        self._context.metas.value.set(MOLECULES_INFOS, position, flavour.get_raw_data())
21
+
22
+    def get_molecule(self, position, category, type, allow_empty=False):
23
+        flavour = self.get_flavour(position)
24
+        try:
25
+            return flavour.get_molecule(category, type)
26
+        except NoMolecule:
27
+            if allow_empty:
28
+                return Molecule()
29
+            raise
30
+
31
+    def increment_with_molecule(self, position, apposed_molecule, cycle_age):
32
+        flavour = self.get_flavour(position)
33
+        try:
34
+            position_molecule = flavour.get_molecule(apposed_molecule.get_category(), apposed_molecule.get_type())
35
+        except NoMolecule:
36
+            position_molecule = Molecule(apposed_molecule.get_category(),
37
+                                         apposed_molecule.get_type(),
38
+                                         distance=apposed_molecule.get_distance(),
39
+                                         cycle_age=cycle_age)
40
+
41
+        position_molecule.increment_intensity(apposed_molecule.get_intensity())
42
+
43
+        if apposed_molecule.get_distance() < position_molecule.get_distance():
44
+            position_molecule.set_distance(apposed_molecule.get_distance())
45
+
46
+        flavour.set_molecule(position_molecule)
47
+        self.set_flavour(position, flavour)
48
+
49
+        if apposed_molecule.get_distance() > position_molecule.get_distance():
50
+            raise BestMoleculeHere(position_molecule.get_distance())

+ 0 - 49
intelligine/synergy/stigmergy/PheromonesManager.py View File

@@ -1,49 +0,0 @@
1
-from intelligine.core.exceptions import BestPheromoneHere, NoPheromone
2
-from intelligine.cst import PHEROMON_INFOS
3
-from intelligine.simulation.pheromone.PheromoneFlavour import PheromoneFlavour
4
-from intelligine.simulation.pheromone.Pheromone import Pheromone
5
-
6
-
7
-class PheromonesManager():
8
-
9
-    def __init__(self, context):
10
-        self._context = context
11
-
12
-    def get_flavour(self, position):
13
-        point_pheromones = self._context.metas.value.get(PHEROMON_INFOS,
14
-                                                         position,
15
-                                                         allow_empty=True,
16
-                                                         empty_value={})
17
-        return PheromoneFlavour.new_from_raw_data(point_pheromones)
18
-
19
-    def set_flavour(self, position, flavour):
20
-        self._context.metas.value.set(PHEROMON_INFOS, position, flavour.get_raw_data())
21
-
22
-    def get_pheromone(self, position, category, type, allow_empty=False):
23
-        flavour = self.get_flavour(position)
24
-        try:
25
-            return flavour.get_pheromone(category, type)
26
-        except NoPheromone:
27
-            if allow_empty:
28
-                return Pheromone()
29
-            raise
30
-
31
-    def increment_with_pheromone(self, position, apposed_pheromone):
32
-        flavour = self.get_flavour(position)
33
-        try:
34
-            position_pheromone = flavour.get_pheromone(apposed_pheromone.get_category(), apposed_pheromone.get_type())
35
-        except NoPheromone:
36
-            position_pheromone = Pheromone(apposed_pheromone.get_category(),
37
-                                           apposed_pheromone.get_type(),
38
-                                           distance=apposed_pheromone.get_distance())
39
-
40
-        position_pheromone.increment_intensity(apposed_pheromone.get_intensity())
41
-
42
-        if apposed_pheromone.get_distance() < position_pheromone.get_distance():
43
-            position_pheromone.set_distance(apposed_pheromone.get_distance())
44
-
45
-        flavour.set_pheromone(position_pheromone)
46
-        self.set_flavour(position, flavour)
47
-
48
-        if apposed_pheromone.get_distance() > position_pheromone.get_distance():
49
-            raise BestPheromoneHere(position_pheromone.get_distance())

+ 26 - 0
intelligine/tests/simulation/bypass/TestByPass.py View File

@@ -0,0 +1,26 @@
1
+from intelligine.synergy.Colony import Colony
2
+from intelligine.synergy.object.ant.Ant import Ant
3
+from intelligine.tests.src.simulation.SimpleTestWorld1Simulation import SimpleTestWorld1Simulation
4
+
5
+
6
+class TestByPass(SimpleTestWorld1Simulation):
7
+
8
+    _ant_move_history = []
9
+    _assert_ant_move_history = [(0, 21, 20), (0, 21, 19), (0, 21, 18), (0, 21, 17), (0, 21, 16), (0, 21, 15), (0, 21, 14), (0, 21, 14), (0, 22, 13), (0, 23, 12), (0, 24, 11), (0, 24, 11), (0, 24, 11), (0, 24, 11), (0, 24, 11), (0, 23, 11), (0, 22, 11), (0, 21, 11), (0, 21, 11), (0, 21, 11), (0, 21, 11), (0, 21, 11), (0, 22, 12), (0, 23, 13), (0, 24, 14), (0, 24, 14), (0, 24, 14), (0, 24, 14), (0, 24, 14), (0, 23, 15), (0, 22, 16), (0, 21, 17), (0, 21, 17), (0, 21, 17), (0, 21, 17), (0, 21, 17), (0, 21, 16), (0, 21, 15), (0, 21, 14), (0, 21, 13), (0, 21, 12), (0, 21, 11), (0, 21, 10), (0, 21, 9), (0, 21, 8), (0, 21, 7), (0, 21, 6), (0, 21, 5), (0, 21, 4), (0, 21, 3), (0, 22, 2), (0, 23, 1), (0, 23, 1), (0, 23, 1), (0, 23, 1), (0, 23, 1), (0, 22, 1), (0, 21, 1), (0, 20, 1), (0, 19, 1), (0, 18, 1), (0, 17, 1), (0, 16, 1), (0, 15, 1), (0, 14, 1), (0, 13, 1), (0, 12, 1), (0, 11, 1), (0, 10, 1), (0, 9, 1), (0, 8, 2), (0, 7, 2), (0, 6, 3), (0, 5, 4), (0, 4, 5), (0, 3, 5), (0, 4, 6), (0, 5, 7), (0, 6, 8), (0, 7, 9), (0, 8, 10), (0, 9, 11), (0, 10, 12), (0, 11, 13), (0, 11, 14), (0, 12, 15), (0, 13, 16), (0, 14, 17), (0, 15, 17), (0, 16, 17), (0, 17, 17), (0, 18, 17), (0, 19, 17), (0, 19, 16), (0, 19, 15), (0, 19, 14), (0, 19, 13), (0, 19, 12), (0, 19, 11), (0, 19, 10), (0, 19, 9), (0, 18, 9), (0, 17, 9), (0, 16, 9), (0, 15, 9), (0, 14, 9), (0, 13, 9), (0, 13, 10), (0, 13, 11), (0, 13, 12), (0, 13, 13), (0, 14, 13), (0, 15, 13), (0, 16, 13), (0, 17, 13), (0, 17, 14), (0, 16, 15), (0, 15, 15), (0, 14, 15), (0, 13, 15), (0, 14, 15), (0, 15, 15), (0, 16, 15), (0, 17, 15), (0, 17, 14), (0, 16, 13), (0, 15, 13), (0, 14, 13), (0, 13, 13), (0, 13, 12), (0, 13, 11), (0, 13, 10), (0, 13, 9), (0, 14, 9), (0, 15, 9), (0, 16, 9), (0, 17, 9), (0, 18, 9), (0, 19, 9), (0, 19, 10), (0, 19, 11), (0, 19, 12), (0, 19, 13), (0, 19, 14), (0, 19, 15), (0, 19, 16), (0, 19, 17), (0, 18, 17), (0, 17, 17), (0, 16, 17), (0, 15, 17), (0, 14, 17), (0, 13, 17), (0, 12, 17), (0, 11, 17), (0, 10, 17), (0, 9, 17), (0, 8, 17), (0, 7, 17), (0, 6, 17), (0, 5, 17), (0, 4, 17), (0, 3, 17), (0, 2, 17), (0, 1, 17), (0, 1, 16), (0, 1, 15), (0, 1, 14), (0, 1, 13), (0, 1, 12), (0, 1, 11), (0, 1, 10), (0, 1, 9), (0, 1, 8), (0, 1, 7), (0, 1, 6), (0, 1, 5), (0, 1, 4), (0, 1, 3), (0, 1, 2), (0, 1, 1), (0, 2, 1), (0, 3, 1), (0, 4, 1), (0, 5, 1), (0, 6, 1), (0, 7, 1), (0, 8, 1), (0, 9, 1), (0, 10, 1), (0, 11, 1), (0, 12, 1), (0, 13, 1), (0, 14, 1), (0, 15, 1), (0, 16, 1), (0, 17, 1), (0, 18, 1), (0, 19, 1), (0, 20, 1), (0, 21, 1), (0, 22, 1), (0, 23, 1), (0, 24, 1), (0, 24, 2), (0, 24, 3), (0, 24, 4), (0, 24, 5), (0, 24, 6), (0, 24, 7), (0, 24, 8), (0, 24, 9), (0, 24, 10), (0, 24, 11), (0, 24, 12), (0, 24, 13), (0, 24, 14), (0, 24, 15), (0, 24, 16), (0, 24, 17), (0, 23, 17), (0, 22, 17), (0, 21, 17), (0, 21, 18), (0, 21, 19), (0, 21, 20), (0, 21, 21), (0, 20, 22), (0, 19, 22), (0, 18, 23), (0, 18, 24), (0, 18, 23), (0, 19, 22), (0, 20, 22), (0, 21, 21), (0, 21, 20), (0, 21, 19), (0, 21, 18), (0, 22, 17), (0, 23, 17), (0, 24, 16), (0, 24, 15), (0, 24, 14), (0, 24, 13), (0, 24, 12), (0, 24, 11), (0, 24, 10), (0, 24, 9), (0, 24, 8), (0, 24, 7), (0, 24, 6), (0, 24, 5), (0, 24, 4), (0, 24, 3), (0, 24, 2), (0, 23, 1), (0, 22, 1), (0, 21, 1), (0, 20, 1), (0, 19, 1), (0, 18, 1), (0, 17, 1), (0, 16, 1), (0, 15, 1), (0, 14, 1), (0, 13, 1), (0, 12, 1), (0, 11, 1), (0, 10, 1), (0, 9, 1), (0, 8, 1), (0, 7, 1), (0, 6, 1), (0, 7, 2), (0, 8, 3), (0, 9, 4), (0, 10, 5), (0, 11, 6), (0, 12, 7), (0, 13, 7), (0, 14, 7), (0, 15, 7), (0, 16, 7), (0, 17, 7), (0, 18, 7), (0, 19, 7), (0, 20, 7), (0, 21, 7), (0, 21, 8), (0, 21, 9), (0, 21, 10), (0, 21, 11), (0, 21, 12), (0, 21, 13), (0, 21, 14), (0, 21, 15), (0, 21, 16), (0, 21, 17), (0, 21, 18), (0, 21, 19), (0, 21, 20)]
10
+
11
+    def setUp(self):
12
+        super().setUp()
13
+        self._ant_move_history = []
14
+
15
+    def test_simulation_road(self):
16
+        self._connection.receive_callback = self._record_ant_moves
17
+        self._run_and_get_core(300)
18
+        self.assertEquals(self._assert_ant_move_history, self._ant_move_history)
19
+
20
+    def _record_ant_moves(self, terminal, actions_done):
21
+        collections = terminal.get_synergy_manager().get_simulations()[0].get_collections()
22
+        for collection in collections:
23
+            if isinstance(collection, Colony):
24
+                ant = collection.get_objects()[0]
25
+                self.assertIsInstance(ant, Ant)
26
+                self._ant_move_history.append(ant.get_position())

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

@@ -1,11 +1,6 @@
1
-from os import getcwd
2
-from sys import path as ppath
3
-from intelligine.core.exceptions import NoPheromone
4
-
5
-ppath.insert(1,getcwd()+'/modules')
6
-
7
-
1
+from intelligine.synergy.Environment import Environment
8 2
 from intelligine.synergy.object.Food import Food
3
+from intelligine.synergy.object.StockedFood import StockedFood
9 4
 from intelligine.tests.simulation.mode.Base import Base
10 5
 from intelligine.synergy.Colony import Colony
11 6
 from intelligine.synergy.Simulation import Simulation
@@ -16,27 +11,27 @@ from intelligine.tests.src.event.MoveAction import MoveAction as TestMoveAction
16 11
 from synergine.synergy.collection.SynergyCollection import SynergyCollection
17 12
 from synergine.synergy.collection.Configuration import Configuration
18 13
 from intelligine.core.Context import Context
19
-from intelligine.cst import MOVE_MODE_EXPLO, MOVE_MODE_GOHOME, MOVE_MODE
20
-from intelligine.cst import PHEROMON_DIR_HOME, PHEROMON_DIR_EXPLO
14
+from intelligine.cst import MODE_EXPLO, MODE_GOHOME, MODE, MODE_HOME, PHEROMON_DIR_NONE
15
+from intelligine.cst import PHEROMON_DIR_EXPLO
21 16
 
22 17
 
23 18
 class TestChangeMode(Base):
24 19
 
25
-    def __init__(self, methodName='runTest'):
26
-        super().__init__(methodName)
20
+    def __init__(self, *args, **kwargs):
21
+        super().__init__(*args, **kwargs)
27 22
         self.ant = None
28 23
         self.food = None
29 24
         self._force_move = self._force_move
30 25
 
31 26
     @staticmethod
32 27
     def _force_move(self_move_action, object_id, context):
33
-        object_movement_mode = context.metas.value.get(MOVE_MODE, object_id)
34
-        if object_movement_mode == MOVE_MODE_GOHOME:
28
+        object_movement_mode = context.metas.value.get(MODE, object_id)
29
+        if object_movement_mode == MODE_GOHOME or object_movement_mode == MODE_HOME:
35 30
             return SOUTH
36 31
         return NORTH
37 32
 
38 33
     def _get_set_up_simulations(self):
39
-        return [Simulation([self._get_colony(), self._get_foods()])]
34
+        return [Simulation([self._get_colony(), self._get_foods(), self._get_environment()])]
40 35
 
41 36
     def _get_colony(self):
42 37
         test_case = self
@@ -70,17 +65,25 @@ class TestChangeMode(Base):
70 65
             def get_start_objects(self, collection, context):
71 66
                 foods = []
72 67
                 food = Food(collection, context)
73
-                food.set_position((0, 0, -3))
74
-                #  TEST (en attendant d'avoir des algo pour deposer dans un depot)
75
-                food1 = Food(collection, context)
76
-                food1.set_position((0, 0, -1))
77
-                food1.is_takable = lambda: False
78
-                foods.append(food1)
68
+                stocked_food = StockedFood(collection, context)
69
+                food.set_position((0, 0, -20))
70
+                stocked_food.set_position((0, 0, 0))
71
+                foods.append(stocked_food)
79 72
                 foods.append(food)
80 73
                 test_case.food = food
81 74
                 return foods
82 75
         return FoodConfiguration()
83 76
 
77
+    def _get_environment(self):
78
+        class TestEnvironment(Environment):
79
+            pass
80
+        return TestEnvironment(self._get_environment_configuration())
81
+
82
+    def _get_environment_configuration(self):
83
+        class TestEnvironmentConfiguration(Configuration):
84
+            pass
85
+        return TestEnvironmentConfiguration()
86
+
84 87
     def _get_core_configuration(self, cycles, main_process=True):
85 88
         config = super()._get_core_configuration(cycles, main_process)
86 89
         config.update({
@@ -101,33 +104,45 @@ class TestChangeMode(Base):
101 104
     def test_from_exploration_to_go_home(self):
102 105
         self._run_and_get_core(0)
103 106
         self.assertEquals((0, 0, 0), self.ant.get_position())
104
-        self.assertEquals(MOVE_MODE_EXPLO, self.ant.get_brain().get_movement_mode())
107
+        self.assertEquals(MODE_EXPLO, self.ant.get_brain().get_movement_mode())
105 108
         self.assertFalse(self.ant.is_carrying())
106 109
 
107 110
         self._run_and_get_core(1)
108 111
         self.assertEquals((0, 0, -1), self.ant.get_position())
109
-        self.assertEquals(MOVE_MODE_EXPLO, self.ant.get_brain().get_movement_mode())
112
+        self.assertEquals(MODE_EXPLO, self.ant.get_brain().get_movement_mode())
110 113
         self.assertFalse(self.ant.is_carrying())
111 114
 
112 115
         # Ant has take Food piece
113
-        self._run_and_get_core(2)
114
-        self.assertEquals((0, 0, -2), self.ant.get_position())
116
+        self._run_and_get_core(19)
117
+        self.assertEquals((0, 0, -19), self.ant.get_position())
115 118
         self.assertTrue(self.ant.is_carrying())
116 119
         self.assertIsNotNone(self.ant.get_carried())
117 120
         self.assertEquals(self.food.__class__, self.ant.get_carried().__class__)
118
-        pheromone = self.ant.get_movement_pheromone_gland().get_pheromone()
119
-        # Now it appose exploration pheromone
120
-        self.assertEquals((PHEROMON_DIR_EXPLO, 0), (pheromone.get_type(), pheromone.get_distance()))
121
-        self.assertEquals(MOVE_MODE_GOHOME, self.ant.get_brain().get_movement_mode())
122
-        self.assertEquals(PHEROMON_DIR_EXPLO, self.ant.get_movement_pheromone_gland().get_pheromone_type())
121
+        molecule = self.ant.get_movement_molecule_gland().get_molecule()
122
+        # Now it appose exploration molecule
123
+        self.assertEquals((PHEROMON_DIR_EXPLO, 0), (molecule.get_type(), molecule.get_distance()))
124
+        self.assertEquals(MODE_GOHOME, self.ant.get_brain().get_movement_mode())
125
+        self.assertEquals(PHEROMON_DIR_EXPLO, self.ant.get_movement_molecule_gland().get_molecule_type())
126
+
127
+        self._run_and_get_core(32)
128
+        self.assertEquals((0, 0, -6), self.ant.get_position())
129
+        self.assertTrue(self.ant.is_carrying())
130
+        self.assertEquals(MODE_HOME, self.ant.get_brain().get_movement_mode())
123 131
 
124
-        self._run_and_get_core(3)
125
-        self.assertEquals((0, 0, -1), self.ant.get_position())
132
+        self._run_and_get_core(33)
133
+        self.assertEquals((0, 0, -5), self.ant.get_position())
126 134
         self.assertTrue(self.ant.is_carrying())
135
+        self.assertEquals(MODE_HOME, self.ant.get_brain().get_movement_mode())
127 136
 
128
-        self._run_and_get_core(4)
129
-        self.assertEquals((0, 0, 0), self.ant.get_position())
130
-        # Ant has put his food piece
137
+        self._run_and_get_core(34)
138
+        self.assertEquals((0, 0, -4), self.ant.get_position())
139
+        self.assertEquals(MODE_HOME, self.ant.get_brain().get_movement_mode())
140
+
141
+        self._run_and_get_core(37)
142
+        self.assertEquals((0, 0, -1), self.ant.get_position())
143
+        # Ant has NOT put his food piece
144
+        self.assertFalse(self.ant.is_carrying())
145
+
146
+        self._run_and_get_core(38)
147
+        self.assertEquals((0, 0, -2), self.ant.get_position())
131 148
         self.assertFalse(self.ant.is_carrying())
132
-        self.assertEquals(MOVE_MODE_EXPLO, self.ant.get_brain().get_movement_mode())
133
-        self.assertEquals(PHEROMON_DIR_HOME, self.ant.get_movement_pheromone_gland().get_pheromone_type())

intelligine/tests/simulation/pheromone/Base.py → intelligine/tests/simulation/molecule/Base.py View File


+ 227 - 0
intelligine/tests/simulation/molecule/TestDirection.py View File

@@ -0,0 +1,227 @@
1
+from intelligine.core.exceptions import NoMolecule
2
+from intelligine.simulation.molecule.Molecule import Molecule
3
+from intelligine.simulation.molecule.MoleculeFlavour import MoleculeFlavour
4
+from intelligine.tests.simulation.molecule.Base import Base
5
+from intelligine.simulation.molecule.DirectionMolecule import DirectionMolecule
6
+from intelligine.core.Context import Context
7
+from intelligine.cst import MOLECULES_DIRECTION, PHEROMON_DIR_EXPLO, PHEROMON_DIR_NONE
8
+from intelligine.synergy.event.move.direction import NORTH, NORTH_EST, EST, SOUTH_EST, SOUTH, SOUTH_WEST, WEST, \
9
+    NORTH_WEST, CENTER
10
+from intelligine.synergy.event.move.direction import get_position_with_direction_decal as _p
11
+
12
+
13
+class TestDirection(Base):
14
+
15
+    def __init__(self, *args, **kwargs):
16
+        super().__init__(*args, **kwargs)
17
+        self._context = Context()
18
+
19
+    def setUp(self):
20
+        self._context = Context()
21
+
22
+    def _set_up_molecules(self, molecules, re_init=True):
23
+        if re_init:
24
+            self._context = Context()
25
+        for position in molecules:
26
+            self._context.molecules().set_flavour(position, MoleculeFlavour.new_from_raw_data(molecules[position]))
27
+
28
+    def _test_direction_for_point(self, molecules, direction, molecule_type=PHEROMON_DIR_EXPLO,
29
+                                  reference_point=_p(CENTER), re_init=True):
30
+        """
31
+
32
+        :param molecules:
33
+        :param direction:
34
+        :param molecule_type:
35
+        :param reference_point:
36
+        :return:
37
+        """
38
+        self._set_up_molecules(molecules, re_init=re_init)
39
+        direction_tested = DirectionMolecule.get_direction_for_point(self._context, reference_point, molecule_type)
40
+        self.assertEqual(direction, direction_tested, "Direction must be %s" % direction)
41
+
42
+    def _test_direction_for_points(self, molecules, direction, molecule_type=PHEROMON_DIR_EXPLO,
43
+                                   reference_point=_p(CENTER), re_init=True):
44
+        """
45
+
46
+        :param molecules:
47
+        :param direction:
48
+        :param molecule_type:
49
+        :param reference_point:
50
+        :return:
51
+        """
52
+        self._set_up_molecules(molecules, re_init=re_init)
53
+        around_points = self._context.get_around_points_of_point(reference_point)
54
+        direction_tested = DirectionMolecule.get_best_molecule_direction_in(self._context,
55
+                                                                              reference_point,
56
+                                                                              around_points,
57
+                                                                              molecule_type)
58
+        self.assertEqual(direction, direction_tested, "Direction must be %s" % direction)
59
+
60
+    def test_route_direct_route(self):
61
+        """
62
+        Test easy direction with 1 best molecules just near actual position
63
+        :return:
64
+        """
65
+        test_data = {
66
+            NORTH_WEST: {
67
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
68
+                _p(NORTH_WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}}
69
+            },
70
+            NORTH: {
71
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
72
+                _p(NORTH): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}}
73
+            },
74
+            NORTH_EST: {
75
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
76
+                _p(NORTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}}
77
+            },
78
+            WEST: {
79
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
80
+                _p(WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}}
81
+            },
82
+            EST: {
83
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
84
+                _p(EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}}
85
+            },
86
+            SOUTH_WEST: {
87
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
88
+                _p(SOUTH_WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}}
89
+            },
90
+            SOUTH: {
91
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
92
+                _p(SOUTH): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}}
93
+            },
94
+            SOUTH_EST: {
95
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
96
+                _p(SOUTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}}
97
+            }
98
+        }
99
+
100
+        for direction_wanted in test_data:
101
+            self._test_direction_for_point(test_data[direction_wanted], direction_wanted)
102
+
103
+    def test_route_with_multiple_same_intensity(self):
104
+        """
105
+        Test find route in middle of multiple molecules
106
+        :return:
107
+        """
108
+        test_data = {
109
+            NORTH_WEST: {
110
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
111
+                _p(NORTH_WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}},
112
+                _p(SOUTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (12, 1, 0)}}
113
+            },
114
+            NORTH_WEST: {
115
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
116
+                _p(NORTH_WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}},
117
+                _p(SOUTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (12, 1, 0)}},
118
+                _p(SOUTH): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (12, 1, 0)}}
119
+            },
120
+            NORTH_WEST: {
121
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1, 0)}},
122
+                _p(NORTH_WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1, 0)}},
123
+                _p(SOUTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (12, 1, 0)}},
124
+                _p(SOUTH): {MOLECULES_DIRECTION: {PHEROMON_DIR_NONE: (8, 1, 0)}}
125
+            },
126
+        }
127
+
128
+        for direction_wanted in test_data:
129
+            self._test_direction_for_point(test_data[direction_wanted], direction_wanted)
130
+
131
+    def test_route_with_multiple_different_intensity(self):
132
+        """
133
+        Test find route in middle of multiple molecules
134
+        :return:
135
+        """
136
+        test_data = {
137
+            NORTH_WEST: {
138
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 2, 0)}},
139
+                _p(NORTH_WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 2, 0)}},
140
+                _p(SOUTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (8, 1, 0)}}
141
+            },
142
+            NORTH_WEST: {
143
+                _p(CENTER): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 2, 0)}},
144
+                _p(NORTH_WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 2, 0)}},
145
+                _p(SOUTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (8, 1, 0)}},
146
+                _p(SOUTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_NONE: (5, 10, 0)}}  # an other molecule type
147
+            }
148
+        }
149
+
150
+        for direction_wanted in test_data:
151
+            self._test_direction_for_point(test_data[direction_wanted], direction_wanted)
152
+
153
+    def test_direction_direct(self):
154
+        test_data = {
155
+            NORTH: {
156
+                _p(NORTH): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 2, 0)}}
157
+            },
158
+            NORTH: {
159
+                _p(NORTH): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 2, 0)}},
160
+                _p(NORTH_WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_NONE: (9, 500, 0)}}  # An other molecule type
161
+            }
162
+        }
163
+
164
+        for direction in test_data:
165
+            self._test_direction_for_points(test_data[direction], direction)
166
+
167
+    def test_direction_with_multiple_intensity(self):
168
+        test_data = {
169
+            NORTH: {
170
+                _p(NORTH): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 5, 0)}},
171
+                _p(SOUTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 4, 0)}},
172
+                _p(NORTH_WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 4, 0)}}
173
+            },
174
+            NORTH: {
175
+                _p(NORTH): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 5, 0)}},
176
+                _p(WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_NONE: (9, 500, 0)}},  # An other molecule_type
177
+                _p(SOUTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 4, 0)}},
178
+                _p(NORTH_WEST): {MOLECULES_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 4, 0)}}
179
+            }
180
+        }
181
+
182
+        for direction in test_data:
183
+            self._test_direction_for_points(test_data[direction], direction)
184
+
185
+    def test_no_molecules_around(self):
186
+        # No molecule
187
+        with self.assertRaises(NoMolecule):
188
+            self._test_direction_for_points({}, -1)
189
+
190
+        # Wrong molecule type
191
+        with self.assertRaises(NoMolecule):
192
+            self._test_direction_for_points({
193
+                _p(SOUTH_EST): {MOLECULES_DIRECTION: {PHEROMON_DIR_NONE: (9, 5, 0)}}
194
+            }, -1)
195
+
196
+    def test_appose(self):
197
+        self._test_point_raise_no_molecule()
198
+        self._test_points_raise_no_molecule()
199
+
200
+        # Une molecule au centre
201
+        DirectionMolecule.appose(self._context,
202
+                                  _p(CENTER),
203
+                                  self._get_molecule(PHEROMON_DIR_EXPLO, 2))
204
+        # Ne permet pas de trouver une route
205
+        self._test_point_raise_no_molecule(re_init=False)
206
+        self._test_points_raise_no_molecule(re_init=False)
207
+
208
+        # Une molecule au nord
209
+        DirectionMolecule.appose(self._context,
210
+                                  _p(NORTH),
211
+                                  self._get_molecule(PHEROMON_DIR_EXPLO, 1))
212
+        # le permet
213
+        self._test_direction_for_points({}, NORTH, re_init=False)
214
+        self._test_direction_for_point({}, NORTH, re_init=False)
215
+
216
+    def _test_point_raise_no_molecule(self, molecules={}, direction=-1, molecule_type=PHEROMON_DIR_EXPLO,
217
+                                 reference_point=_p(CENTER), re_init=True):
218
+        with self.assertRaises(NoMolecule):
219
+            self._test_direction_for_point(molecules, direction, re_init=re_init)
220
+
221
+    def _test_points_raise_no_molecule(self, molecules={}, direction=-1, molecule_type=PHEROMON_DIR_EXPLO,
222
+                                 reference_point=_p(CENTER), re_init=True):
223
+        with self.assertRaises(NoMolecule):
224
+            self._test_direction_for_points(molecules, direction, re_init=re_init)
225
+
226
+    def _get_molecule(self, type, distance):
227
+        return Molecule(MOLECULES_DIRECTION, type, distance=distance)

+ 0 - 241
intelligine/tests/simulation/pheromone/TestDirection.py View File

@@ -1,241 +0,0 @@
1
-from os import getcwd
2
-from sys import path as ppath
3
-from intelligine.core.exceptions import NoPheromone
4
-from intelligine.simulation.pheromone.Pheromone import Pheromone
5
-from intelligine.simulation.pheromone.PheromoneFlavour import PheromoneFlavour
6
-
7
-ppath.insert(1,getcwd()+'/modules')
8
-
9
-from intelligine.tests.simulation.pheromone.Base import Base
10
-from intelligine.simulation.pheromone.DirectionPheromone import DirectionPheromone
11
-from intelligine.core.Context import Context
12
-from intelligine.cst import PHEROMON_DIRECTION, PHEROMON_DIR_EXPLO, PHEROMON_DIR_HOME
13
-from intelligine.synergy.event.move.direction import NORTH, NORTH_EST, EST, SOUTH_EST, SOUTH, SOUTH_WEST, WEST, \
14
-    NORTH_WEST, CENTER
15
-from intelligine.synergy.event.move.direction import get_position_with_direction_decal as _p
16
-
17
-
18
-class TestDirection(Base):
19
-
20
-    def __init__(self, *args, **kwargs):
21
-        super().__init__(*args, **kwargs)
22
-        self._context = Context()
23
-
24
-    def setUp(self):
25
-        self._context = Context()
26
-
27
-    def _set_up_pheromones(self, pheromones, re_init=True):
28
-        if re_init:
29
-            self._context = Context()
30
-        for position in pheromones:
31
-            self._context.pheromones().set_flavour(position, PheromoneFlavour.new_from_raw_data(pheromones[position]))
32
-
33
-    def _test_direction_for_point(self, pheromones, direction, pheromone_type=PHEROMON_DIR_EXPLO,
34
-                                  reference_point=_p(CENTER), re_init=True):
35
-        """
36
-
37
-        :param pheromones:
38
-        :param direction:
39
-        :param pheromone_type:
40
-        :param reference_point:
41
-        :return:
42
-        """
43
-        self._set_up_pheromones(pheromones, re_init=re_init)
44
-        direction_tested = DirectionPheromone.get_direction_for_point(self._context, reference_point, pheromone_type)
45
-        self.assertEqual(direction, direction_tested, "Direction must be %s" % direction)
46
-
47
-    def _test_direction_for_points(self, pheromones, direction, pheromone_type=PHEROMON_DIR_EXPLO,
48
-                                   reference_point=_p(CENTER), re_init=True):
49
-        """
50
-
51
-        :param pheromones:
52
-        :param direction:
53
-        :param pheromone_type:
54
-        :param reference_point:
55
-        :return:
56
-        """
57
-        self._set_up_pheromones(pheromones, re_init=re_init)
58
-        around_points = self._context.get_around_points_of_point(reference_point)
59
-        direction_tested = DirectionPheromone.get_best_pheromone_direction_in(self._context,
60
-                                                                              reference_point,
61
-                                                                              around_points,
62
-                                                                              pheromone_type)
63
-        self.assertEqual(direction, direction_tested, "Direction must be %s" % direction)
64
-
65
-    def test_route_direct_route(self):
66
-        """
67
-        Test easy direction with 1 best pheromones just near actual position
68
-        :return:
69
-        """
70
-        test_data = {
71
-            NORTH_WEST: {
72
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
73
-                _p(NORTH_WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}}
74
-            },
75
-            NORTH: {
76
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
77
-                _p(NORTH): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}}
78
-            },
79
-            NORTH_EST: {
80
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
81
-                _p(NORTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}}
82
-            },
83
-            WEST: {
84
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
85
-                _p(WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}}
86
-            },
87
-            EST: {
88
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
89
-                _p(EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}}
90
-            },
91
-            SOUTH_WEST: {
92
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
93
-                _p(SOUTH_WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}}
94
-            },
95
-            SOUTH: {
96
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
97
-                _p(SOUTH): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}}
98
-            },
99
-            SOUTH_EST: {
100
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
101
-                _p(SOUTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}}
102
-            }
103
-        }
104
-
105
-        for direction_wanted in test_data:
106
-            self._test_direction_for_point(test_data[direction_wanted], direction_wanted)
107
-
108
-    def test_route_with_multiple_same_intensity(self):
109
-        """
110
-        Test find route in middle of multiple pheromones
111
-        :return:
112
-        """
113
-        test_data = {
114
-            NORTH_WEST: {
115
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
116
-                _p(NORTH_WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}},
117
-                _p(SOUTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (12, 1)}}
118
-            },
119
-            NORTH_WEST: {
120
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
121
-                _p(NORTH_WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}},
122
-                _p(SOUTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (12, 1)}},
123
-                _p(SOUTH): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (12, 1)}}
124
-            },
125
-            NORTH_WEST: {
126
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 1)}},
127
-                _p(NORTH_WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 1)}},
128
-                _p(SOUTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (12, 1)}},
129
-                _p(SOUTH): {PHEROMON_DIRECTION: {PHEROMON_DIR_HOME: (8, 1)}}
130
-            },
131
-        }
132
-
133
-        for direction_wanted in test_data:
134
-            self._test_direction_for_point(test_data[direction_wanted], direction_wanted)
135
-
136
-    def test_route_with_multiple_different_intensity(self):
137
-        """
138
-        Test find route in middle of multiple pheromones
139
-        :return:
140
-        """
141
-        test_data = {
142
-            NORTH_WEST: {
143
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 2)}},
144
-                _p(NORTH_WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 2)}},
145
-                _p(SOUTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (8, 1)}}
146
-            },
147
-            NORTH_WEST: {
148
-                _p(CENTER): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (10, 2)}},
149
-                _p(NORTH_WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 2)}},
150
-                _p(SOUTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (8, 1)}},
151
-                _p(SOUTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_HOME: (5, 10)}}  # an other pheromone type
152
-            }
153
-        }
154
-
155
-        for direction_wanted in test_data:
156
-            self._test_direction_for_point(test_data[direction_wanted], direction_wanted)
157
-
158
-    def test_direction_direct(self):
159
-        test_data = {
160
-            NORTH: {
161
-                _p(NORTH): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 2)}}
162
-            },
163
-            NORTH: {
164
-                _p(NORTH): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 2)}},
165
-                _p(NORTH_WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_HOME: (9, 500)}}  # An other pheromone type
166
-            }
167
-        }
168
-
169
-        for direction in test_data:
170
-            self._test_direction_for_points(test_data[direction], direction)
171
-
172
-    def test_direction_with_multiple_intensity(self):
173
-        test_data = {
174
-            NORTH: {
175
-                _p(NORTH): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 5)}},
176
-                _p(SOUTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 4)}},
177
-                _p(NORTH_WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 4)}}
178
-            },
179
-            NORTH: {
180
-                _p(NORTH): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 5)}},
181
-                _p(WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_HOME: (9, 500)}},  # An other pheromone_type
182
-                _p(SOUTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 4)}},
183
-                _p(NORTH_WEST): {PHEROMON_DIRECTION: {PHEROMON_DIR_EXPLO: (9, 4)}}
184
-            }
185
-        }
186
-
187
-        for direction in test_data:
188
-            self._test_direction_for_points(test_data[direction], direction)
189
-
190
-    def test_no_pheromones_around(self):
191
-        # No pheromone
192
-        try:  # WTF ?
193
-            self.assertRaises(NoPheromone, self._test_direction_for_points({}, -1))
194
-        except NoPheromone:
195
-            self.assertTrue(True)
196
-
197
-        # Wrong pheromone type
198
-        try:  # WTF ?
199
-            self.assertRaises(NoPheromone, self._test_direction_for_points({
200
-                _p(SOUTH_EST): {PHEROMON_DIRECTION: {PHEROMON_DIR_HOME: (9, 5)}}
201
-            }, -1))
202
-        except NoPheromone:
203
-            self.assertTrue(True)
204
-
205
-    def test_appose(self):
206
-        self._test_point_raise_no_pheromone()
207
-        self._test_points_raise_no_pheromone()
208
-
209
-        # Une pheromone au centre
210
-        DirectionPheromone.appose(self._context,
211
-                                  _p(CENTER),
212
-                                  self._get_pheromone(PHEROMON_DIR_EXPLO, 2))
213
-        # Ne permet pas de trouver une route
214
-        self._test_point_raise_no_pheromone(re_init=False)
215
-        self._test_points_raise_no_pheromone(re_init=False)
216
-
217
-        # Une pheromone au nord
218
-        DirectionPheromone.appose(self._context,
219
-                                  _p(NORTH),
220
-                                  self._get_pheromone(PHEROMON_DIR_EXPLO, 1))
221
-        # le permet
222
-        self._test_direction_for_points({}, NORTH, re_init=False)
223
-        self._test_direction_for_point({}, NORTH, re_init=False)
224
-
225
-
226
-    def _test_point_raise_no_pheromone(self, pheromones={}, direction=-1, pheromone_type=PHEROMON_DIR_EXPLO,
227
-                                 reference_point=_p(CENTER), re_init=True):
228
-        try:  # WTF ?
229
-            self._test_direction_for_point(pheromones, direction, re_init=re_init)
230
-        except NoPheromone:
231
-            self.assertTrue(True)
232
-
233
-    def _test_points_raise_no_pheromone(self, pheromones={}, direction=-1, pheromone_type=PHEROMON_DIR_EXPLO,
234
-                                 reference_point=_p(CENTER), re_init=True):
235
-        try:  # WTF ?
236
-            self._test_direction_for_points(pheromones, direction, re_init=re_init)
237
-        except NoPheromone:
238
-            self.assertTrue(True)
239
-
240
-    def _get_pheromone(self, type, distance):
241
-        return Pheromone(PHEROMON_DIRECTION, type, distance=distance)

File diff suppressed because it is too large
+ 10215 - 0
intelligine/tests/src/simulation/SimpleTestWorld1.tmx


+ 19 - 0
intelligine/tests/src/simulation/SimpleTestWorld1Simulation.py View File

@@ -0,0 +1,19 @@
1
+from intelligine.display.map import get_map_connector
2
+from intelligine.display.pygame.config import map_config
3
+from synergine.test.TestSimulation import TestSimulation
4
+from os import getcwd
5
+
6
+
7
+class SimpleTestWorld1Simulation(TestSimulation):
8
+
9
+    def __init__(self, *args, **kwargs):
10
+        super().__init__(*args, **kwargs)
11
+
12
+        map_connector = get_map_connector(
13
+            getcwd()+"/intelligine/tests/src/simulation/SimpleTestWorld1.tmx",
14
+            map_config
15
+        )
16
+        self._simulations = map_connector.create_simulations()
17
+
18
+    def _get_set_up_simulations(self):
19
+        return self._simulations

+ 5 - 2
requirements.txt View File

@@ -1,2 +1,5 @@
1
-synergine>=0.0.1
2
-synergine_xyz>=0.0.1
1
+git+https://github.com/buxx/synergine.git
2
+git+https://github.com/buxx/synergine_xyz.git
3
+git+https://github.com/buxx/AntStar.git
4
+tmx==1.2.3
5
+Pillow==2.8.1

+ 3 - 2
tests.py View File

@@ -5,12 +5,13 @@ from sys import path as ppath
5 5
 ppath.insert(1,getcwd()+'/modules') # TODO: win32 compatibilite (python path)
6 6
 
7 7
 """
8
-python3.4 -m unittest /home/bux/Projets/socialintengine/intelligine/tests/simulation/mode/TestChangeMode.py && python3.4 -m unittest intelligine/tests/simulation/pheromone/TestDirection.py
8
+python3.4 -m unittest /home/bux/Projets/socialintengine/intelligine/tests/simulation/mode/TestChangeMode.py && python3.4 -m unittest intelligine/tests/simulation/molecule/TestDirection.py
9 9
 """
10 10
 
11 11
 test_modules = [
12 12
     'intelligine.tests.simulation.mode.TestChangeMode.TestChangeMode',
13
-    'intelligine.tests.simulation.pheromone.TestDirection.TestDirection',
13
+    'intelligine.tests.simulation.molecule.TestDirection.TestDirection',
14
+    'intelligine.tests.simulation.bypass.TestByPass.TestByPass',
14 15
 ]
15 16
 
16 17
 suite = unittest.TestSuite()

+ 3 - 0
tests_requirements.txt View File

@@ -1,2 +1,5 @@
1 1
 git+http://github.com/buxx/synergine.git
2 2
 git+http://github.com/buxx/synergine_xyz.git
3
+git+https://github.com/buxx/AntStar.git
4
+tmx==1.2.3
5
+Pillow==2.8.1