AntMoveBrainPart.py 6.6KB

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