AntMoveBrainPart.py 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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
  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
  6. from synergine_xyz.cst import POSITION
  7. from intelligine.core.exceptions import NoMolecule
  8. from intelligine.cst import MOLECULE_SEARCHING, MOVE_MODE_EXPLO, MOVE_MODE_HOME, MOVE_MODE, MOVE_MODE_GOHOME, \
  9. EXPLORATION_VECTOR, MOLECULES_DIRECTION, SMELL_FOOD, SMELL_EGG, BRAIN_SCHEMA, BRAIN
  10. from intelligine.simulation.molecule.DirectionMolecule import DirectionMolecule
  11. class AntMoveBrainPart(MoveBrainPart):
  12. def __init__(self, host_brain):
  13. super().__init__(host_brain)
  14. self._exploration_vector = (0, 0)
  15. def _set_exploration_vector(self, new_vector):
  16. self._exploration_vector = new_vector
  17. self._context.metas.value.set(EXPLORATION_VECTOR,
  18. self._host_brain.get_host().get_id(),
  19. new_vector)
  20. @classmethod
  21. def get_direction(cls, context, object_id):
  22. move_mode = context.metas.value.get(MOVE_MODE, object_id)
  23. if move_mode == MOVE_MODE_GOHOME:
  24. return cls._get_direction_with_exploration_vector(context, object_id)
  25. else:
  26. try:
  27. return cls._get_direction_with_molecules(context, object_id)
  28. except NoMolecule:
  29. return super().get_direction(context, object_id)
  30. return super().get_direction(context, object_id)
  31. @classmethod
  32. def _get_direction_with_molecules(cls, context, object_id):
  33. object_point = context.metas.value.get(POSITION, object_id)
  34. molecule_type = context.metas.value.get(MOLECULE_SEARCHING, object_id)
  35. try:
  36. direction = cls._get_molecule_direction_for_point(context, object_point, molecule_type)
  37. except NoMolecule:
  38. try:
  39. direction = cls._get_direction_of_molecule(context, object_point, molecule_type)
  40. except NoMolecule:
  41. raise
  42. return direction
  43. @staticmethod
  44. def _get_molecule_direction_for_point(context, point, molecule_type):
  45. return DirectionMolecule.get_direction_for_point(context, point, molecule_type)
  46. @staticmethod
  47. def _get_direction_of_molecule(context, point, molecule_type):
  48. search_molecule_in_points = context.get_around_points_of_point(point)
  49. try:
  50. best_molecule_direction = DirectionMolecule.get_best_molecule_direction_in(context,
  51. point,
  52. search_molecule_in_points,
  53. molecule_type)
  54. return best_molecule_direction
  55. except NoMolecule as err:
  56. raise err
  57. @classmethod
  58. def _get_direction_with_exploration_vector(cls, context, object_id):
  59. ant_star = cls._get_by_pass_brain(context, object_id)
  60. ant_star.advance()
  61. return ant_star.get_host().get_moved_to_direction()
  62. @classmethod
  63. def _get_by_pass_brain(cls, context, object_id):
  64. # We use an adaptation of AntStar
  65. exploration_vector = context.metas.value.get(EXPLORATION_VECTOR, object_id)
  66. home_vector = (-exploration_vector[0], -exploration_vector[1])
  67. ant_host = Host(context, object_id)
  68. return ByPass(ant_host, home_vector, context, object_id)
  69. # TODO: obj pas necessaire, il est dans _host
  70. def done(self):
  71. super().done()
  72. self._appose_molecule()
  73. self._check_context()
  74. self._apply_context()
  75. def _appose_molecule(self):
  76. if self._host.get_movement_molecule_gland().is_enabled():
  77. self._host.get_movement_molecule_gland().appose()
  78. def _check_context(self):
  79. """
  80. If was in exploration, and just found home smell;
  81. -> home mode (then, in this mode: no update vector, put food if food, etc)
  82. If was in home, and just loose home smell:
  83. -> exploration mode
  84. :param obj:
  85. :param context:
  86. :return:
  87. """
  88. movement_mode = self._host_brain.get_movement_mode()
  89. if movement_mode == MOVE_MODE_GOHOME and self._on_home_smell(self._context, self._host.get_id()):
  90. self._host_brain.switch_to_mode(MOVE_MODE_HOME)
  91. ant_star = self._get_by_pass_brain(self._context, self._host.get_id())
  92. ant_star.erase()
  93. # TODO: on change les molecule recherché (Food => SmellFood, definis dans Take, en fct de ce qui est take)
  94. elif movement_mode == MOVE_MODE_HOME and not self._on_home_smell(self._context, self._host.get_id()):
  95. self._host_brain.switch_to_mode(MOVE_MODE_EXPLO)
  96. self._start_new_exploration()
  97. elif movement_mode == MOVE_MODE_EXPLO and self._on_home_smell(self._context, self._host.get_id()):
  98. self._start_new_exploration() # TODO: rename en reinit_explo
  99. # TODO: sitch explo si rien a faire (rien a poser par exemple) et HOME
  100. # TODO: Poser sur StockedFood
  101. @classmethod
  102. def _on_home_smell(cls, context, object_id):
  103. current_position = context.metas.value.get(POSITION, object_id)
  104. flavour = context.molecules().get_flavour(current_position)
  105. molecules = flavour.get_molecules(MOLECULES_DIRECTION)
  106. if not molecules:
  107. return False
  108. brain_class = get_brain_class(context, object_id)
  109. for smell_type in brain_class.get_home_smells():
  110. if smell_type in molecules:
  111. return True
  112. return False
  113. def _update_exploration_vector(self):
  114. just_move_vector = directions_modifiers[self._host_brain.get_host().get_previous_direction()]
  115. self._set_exploration_vector((self._exploration_vector[0] + just_move_vector[1],
  116. self._exploration_vector[1] + just_move_vector[2]))
  117. def _apply_context(self):
  118. movement_mode = self._host_brain.get_movement_mode()
  119. if movement_mode == MOVE_MODE_EXPLO or movement_mode == MOVE_MODE_GOHOME:
  120. self._update_exploration_vector()
  121. def _start_new_exploration(self):
  122. # On vient de rentrer dans le monde exterieur, le vecteur de départ pointe vers la case précedente
  123. # qui est une case dans la forteresse.
  124. self._exploration_vector = get_position_with_direction_decal(self.get_host().get_previous_direction())