AntMoveBrainPart.py 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. from intelligine.simulation.molecule.DirectionMolecule import DirectionMolecule
  2. from intelligine.simulation.object.brain.part.move.MoveBrainPart import MoveBrainPart
  3. from intelligine.synergy.event.move.direction import directions_modifiers, get_direction_for_degrees
  4. from synergine_xyz.cst import POSITION
  5. from intelligine.core.exceptions import NoMolecule, NoTypeInMolecule
  6. from intelligine.cst import MOLECULE_SEARCHING, MOVE_MODE_EXPLO, \
  7. MOVE_MODE_HOME, MOVE_MODE, MOVE_MODE_GOHOME, EXPLORATION_VECTOR, POINTS_SMELL, MOLECULES, MOLECULES_DIRECTION, \
  8. SMELL_FOOD, SMELL_EGG
  9. from intelligine.simulation.molecule.DirectionMolecule import DirectionMolecule
  10. from synergine_xyz.geometry import get_degree_from_north
  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. # TODO: On devrais donner le context aux brain parts
  18. self._host_brain.get_context().metas.value.set(EXPLORATION_VECTOR,
  19. self._host_brain.get_host().get_id(),
  20. new_vector)
  21. @classmethod
  22. def get_direction(cls, context, object_id):
  23. move_mode = context.metas.value.get(MOVE_MODE, object_id)
  24. if move_mode == MOVE_MODE_GOHOME:
  25. return cls._get_direction_with_exploration_vector(context, object_id)
  26. else:
  27. try:
  28. return cls._get_direction_with_molecules(context, object_id)
  29. except NoMolecule:
  30. return super().get_direction(context, object_id)
  31. return super().get_direction(context, object_id)
  32. @classmethod
  33. def _get_direction_with_molecules(cls, context, object_id):
  34. object_point = context.metas.value.get(POSITION, object_id)
  35. molecule_type = context.metas.value.get(MOLECULE_SEARCHING, object_id)
  36. try:
  37. direction = cls._get_molecule_direction_for_point(context, object_point, molecule_type)
  38. except NoMolecule:
  39. try:
  40. direction = cls._get_direction_of_molecule(context, object_point, molecule_type)
  41. except NoMolecule:
  42. raise
  43. return direction
  44. @staticmethod
  45. def _get_molecule_direction_for_point(context, point, molecule_type):
  46. return DirectionMolecule.get_direction_for_point(context, point, molecule_type)
  47. @staticmethod
  48. def _get_direction_of_molecule(context, point, molecule_type):
  49. search_molecule_in_points = context.get_around_points_of_point(point)
  50. try:
  51. best_molecule_direction = DirectionMolecule.get_best_molecule_direction_in(context,
  52. point,
  53. search_molecule_in_points,
  54. molecule_type)
  55. return best_molecule_direction
  56. except NoMolecule as err:
  57. raise err
  58. @staticmethod
  59. def _get_direction_with_exploration_vector(context, object_id):
  60. current_position = context.metas.value.get(POSITION, object_id)
  61. exploration_vector = context.metas.value.get(EXPLORATION_VECTOR, object_id)
  62. # TODO: inverser (math)
  63. home_vector = (exploration_vector[0] - (exploration_vector[0]*2),
  64. exploration_vector[1] - (exploration_vector[1]*2))
  65. home_position = (0, current_position[1]+home_vector[0], current_position[2]+home_vector[1])
  66. degree_from_north = get_degree_from_north(current_position, home_position)
  67. direction_for_home_vector = get_direction_for_degrees(degree_from_north)
  68. return direction_for_home_vector
  69. # TODO: obj pas necessaire, il est dans _host
  70. def done(self, obj, context):
  71. super().done(obj, context)
  72. self._appose_molecule(obj)
  73. self._check_context(obj, context)
  74. self._apply_context(obj, context)
  75. @staticmethod
  76. def _appose_molecule(obj):
  77. if obj.get_movement_molecule_gland().is_enabled():
  78. obj.get_movement_molecule_gland().appose()
  79. def _check_context(self, obj, context):
  80. """
  81. If was in exploration, and just found home smell;
  82. -> home mode (then, in this mode: no update vector, put food if food, etc)
  83. If was in home, and just loose home smell:
  84. -> exploration mode
  85. :param obj:
  86. :param context:
  87. :return:
  88. """
  89. movement_mode = self._host_brain.get_movement_mode()
  90. if movement_mode == MOVE_MODE_GOHOME and self._on_home_smell(context, obj.get_id()):
  91. self._host_brain.switch_to_mode(MOVE_MODE_HOME)
  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(context, obj.get_id()):
  94. self._host_brain.switch_to_mode(MOVE_MODE_EXPLO)
  95. self._start_new_exploration()
  96. # TODO: sitch explo si rien a faire (rien a poser par exemple) et HOME
  97. # TODO: Poser sur StockedFood
  98. @classmethod
  99. def _on_home_smell(cls, context, object_id):
  100. current_position = context.metas.value.get(POSITION, object_id)
  101. flavour = context.molecules().get_flavour(current_position)
  102. # TODO: Idem, liste de smell_type ...
  103. for smell_type in (SMELL_FOOD, SMELL_EGG):
  104. try:
  105. molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=smell_type)
  106. return True
  107. except NoTypeInMolecule:
  108. pass # C'est qu'elle y est pas ^^
  109. return False
  110. def _update_exploration_vector(self):
  111. # TODO: add tuple as vectors ?
  112. just_move_vector = directions_modifiers[self._host_brain.get_host().get_previous_direction()]
  113. self._set_exploration_vector((self._exploration_vector[0] + just_move_vector[1],
  114. self._exploration_vector[1] + just_move_vector[2]))
  115. def _apply_context(self, obj, context):
  116. movement_mode = self._host_brain.get_movement_mode()
  117. if movement_mode == MOVE_MODE_EXPLO or movement_mode == MOVE_MODE_GOHOME:
  118. self._update_exploration_vector()
  119. def _start_new_exploration(self):
  120. self._exploration_vector = (0, 0)