AntMoveBrainPart.py 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. from intelligine.simulation.object.brain.part.move.MoveBrainPart import MoveBrainPart
  2. from intelligine.synergy.event.move.direction import directions_modifiers, get_direction_for_degrees
  3. from synergine_xyz.cst import POSITION
  4. from intelligine.core.exceptions import NoMolecule
  5. from intelligine.cst import PHEROMONE_SEARCHING, MOVE_MODE_EXPLO, \
  6. MOVE_MODE_HOME, MOVE_MODE, MOVE_MODE_GOHOME, EXPLORATION_VECTOR, POINTS_SMELL
  7. from intelligine.simulation.molecule.DirectionMolecule import DirectionMolecule
  8. from synergine_xyz.geometry import get_degree_from_north
  9. class AntMoveBrainPart(MoveBrainPart):
  10. def __init__(self, host_brain):
  11. super().__init__(host_brain)
  12. self._exploration_vector = (0, 0)
  13. def _set_exploration_vector(self, new_vector):
  14. self._exploration_vector = new_vector
  15. # TODO: On devrais donner le context aux brain parts
  16. self._host_brain.get_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_EXPLO:
  23. try:
  24. return cls._get_direction_with_molecules(context, object_id)
  25. except NoMolecule:
  26. return super().get_direction(context, object_id)
  27. elif move_mode == MOVE_MODE_GOHOME:
  28. return cls._get_direction_with_exploration_vector(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(PHEROMONE_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. @staticmethod
  57. def _get_direction_with_exploration_vector(context, object_id):
  58. current_position = context.metas.value.get(POSITION, object_id)
  59. exploration_vector = context.metas.value.get(EXPLORATION_VECTOR, object_id)
  60. # TODO: inverser
  61. home_vector = (exploration_vector[0] - (exploration_vector[0]*2),
  62. exploration_vector[1] - (exploration_vector[1]*2))
  63. home_position = (0, current_position[1]+home_vector[0], current_position[2]+home_vector[1])
  64. degree_from_north = get_degree_from_north(current_position, home_position)
  65. direction_for_home_vector = get_direction_for_degrees(degree_from_north)
  66. return direction_for_home_vector
  67. # TODO: obj pas necessaire, il est dans _host
  68. def done(self, obj, context):
  69. super().done(obj, context)
  70. self._appose_molecule(obj)
  71. self._check_context(obj, context)
  72. self._apply_context(obj, context)
  73. @staticmethod
  74. def _appose_molecule(obj):
  75. if obj.get_movement_molecule_gland().is_enabled():
  76. obj.get_movement_molecule_gland().appose()
  77. def _check_context(self, obj, context):
  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. if self._host_brain.get_movement_mode() == MOVE_MODE_EXPLO and self._on_home_smell(context, obj.get_id()):
  88. self._host_brain.switch_to_mode(MOVE_MODE_HOME)
  89. if self._host_brain.get_movement_mode() == MOVE_MODE_HOME and not self._on_home_smell(context, obj.get_id()):
  90. # TODO: sitwh explo que si rien a faire (rien a poser par exemple)
  91. self._host_brain.switch_to_mode(MOVE_MODE_EXPLO)
  92. self._start_new_exploration()
  93. @classmethod
  94. def _on_home_smell(cls, context, object_id):
  95. current_position = context.metas.value.get(POSITION, object_id)
  96. smell_points = context.metas.value.get(POINTS_SMELL, POINTS_SMELL, allow_empty=True, empty_value={})
  97. if current_position in smell_points:
  98. return True
  99. return False
  100. def _update_exploration_vector(self):
  101. # TODO: add tuple as vectors ?
  102. just_move_vector = directions_modifiers[self._host_brain.get_host().get_previous_direction()]
  103. self._set_exploration_vector((self._exploration_vector[0] + just_move_vector[1],
  104. self._exploration_vector[1] + just_move_vector[2]))
  105. def _apply_context(self, obj, context):
  106. movement_mode = self._host_brain.get_movement_mode()
  107. if movement_mode == MOVE_MODE_EXPLO or movement_mode == MOVE_MODE_GOHOME:
  108. self._update_exploration_vector()
  109. def _start_new_exploration(self):
  110. self._exploration_vector = (0, 0)