AntPutBrainPart.py 4.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. from intelligine.synergy.object.Food import Food
  2. from synergine.core.Core import Core
  3. from intelligine.core.exceptions import CantFindWhereToPut
  4. from intelligine.cst import MODE_EXPLO, TYPE_RESOURCE_EXPLOITABLE, MODE_NURSE, TYPE_NURSERY, \
  5. MODE_HOME, TYPE_RESOURCE_EATABLE, MODE_GOHOME, CARRY, PUT_FAIL_COUNT, MODE_SEARCH_AROUND
  6. from intelligine.simulation.object.brain.part.transport.TransportBrainPart import TransportBrainPart
  7. from synergine_xyz.cst import POSITION, POSITIONS
  8. class AntPutBrainPart(TransportBrainPart):
  9. _mode_matches = TransportBrainPart._mode_matches.copy()
  10. _mode_matches.update({
  11. MODE_NURSE: [TYPE_NURSERY],
  12. MODE_HOME: [TYPE_RESOURCE_EATABLE],
  13. MODE_GOHOME: [],
  14. MODE_SEARCH_AROUND: []
  15. })
  16. _types_matches = {
  17. TYPE_RESOURCE_EXPLOITABLE: [TYPE_RESOURCE_EATABLE],
  18. TYPE_NURSERY: [TYPE_NURSERY]
  19. }
  20. @classmethod
  21. def can_put(cls, context, object_id, object_near_id):
  22. put_fail_count = context.metas.value.get(PUT_FAIL_COUNT, object_id, allow_empty=True, empty_value=0)
  23. put_fail_count_max = Core.get_configuration_manager().get('ant.max_put_fail_count', 20)
  24. if put_fail_count >= put_fail_count_max:
  25. return False
  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
  32. @classmethod
  33. def get_put_position(cls, context, object_id, object_near_id):
  34. """
  35. Maybe part "found available position arround" should be in other class.
  36. :param context:
  37. :param object_id:
  38. :param object_near_id:
  39. :return:
  40. """
  41. obj_near_position = context.metas.value.get(POSITION, object_near_id)
  42. if cls._is_available_position(context, obj_near_position):
  43. return obj_near_position
  44. obj_transporter_position = context.metas.value.get(POSITION, object_id)
  45. obj_transporter_around_positions = context.get_around_points_of_point(obj_transporter_position)
  46. obj_near_around_positions = context.get_around_points_of_point(obj_near_position)
  47. # For each position between target and current transporter
  48. for pos_around_target in obj_near_around_positions:
  49. if pos_around_target in obj_transporter_around_positions:
  50. if cls._is_available_position(context, pos_around_target):
  51. return pos_around_target
  52. raise CantFindWhereToPut()
  53. @classmethod
  54. def _is_available_position(cls, context, position):
  55. if not context.position_is_penetrable(position):
  56. return False
  57. if not cls._position_is_enought_place(context, position):
  58. return False
  59. if not cls._position_have_free_space_around(context, position):
  60. return False
  61. return True
  62. @classmethod
  63. def _position_is_enought_place(cls, context, position):
  64. count_obj_here = len(context.metas.list.get(POSITIONS, position, allow_empty=True))
  65. if count_obj_here < Core.get_configuration_manager().get('ant.put.max_objects_at_same_position', 5):
  66. return True
  67. return False
  68. @classmethod
  69. def _position_have_free_space_around(cls, context, position):
  70. # TODO: On regarde ces cases qui ne sont pas forcement visible par l'individu. On presupose ici qu'elle peut les
  71. # voir. Pour etre au top il faudrait une logie propre a l'individu qui definis ce qu'il voie.
  72. around_positions = context.get_around_points_of_point(position)
  73. for around_position in around_positions:
  74. if not context.position_is_penetrable(around_position):
  75. return False
  76. return True
  77. def done(self, puted_object):
  78. # TODO: lancer le choix d'un nouveau mode dans le brain.
  79. if isinstance(puted_object, Food):
  80. self._host.get_brain().switch_to_mode(MODE_EXPLO)