DirectionMolecule.py 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. from intelligine.cst import POINTS_SMELL, MOLECULES, MOLECULES_DIRECTION
  2. from intelligine.core.exceptions import NoMolecule
  3. from random import shuffle
  4. from synergine_xyz.geometry import get_degree_from_north
  5. from intelligine.synergy.event.move.direction import get_direction_for_degrees
  6. class DirectionMolecule():
  7. WAY_UP = 'u'
  8. WAY_DOWN = 'd'
  9. _positions_key = None
  10. @classmethod
  11. def appose(cls, context, point, molecule):
  12. context.molecules().increment_with_molecule(point, molecule, context.get_cycle())
  13. context.metas.list.add(MOLECULES, MOLECULES, point, assert_not_in=False)
  14. @classmethod
  15. def get_direction_for_point(cls, context, point, molecule_type, molecule_way=WAY_UP):
  16. flavour = context.molecules().get_flavour(point)
  17. molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
  18. distance = molecule.get_distance()
  19. around_molecule_filter = lambda around_molecule: around_molecule.get_distance() < distance # TODO <= ?
  20. if molecule_way == cls.WAY_DOWN:
  21. around_molecule_filter = lambda around_molecule: around_molecule.get_distance() >= distance
  22. around_molecules_points = cls._get_around_molecules(context, point, molecule_type,
  23. molecule_filter=around_molecule_filter)
  24. if not around_molecules_points \
  25. or (len(around_molecules_points) == 1 and around_molecules_points[0][0] == point):
  26. raise NoMolecule()
  27. shuffle(around_molecules_points)
  28. around_molecules_sorted = sorted(around_molecules_points, key=lambda x: x[1].get_intensity(), reverse=True)
  29. max_intensity = around_molecules_sorted[0][1].get_intensity()
  30. around_molecules_max = []
  31. for around_molecule_sorted in around_molecules_sorted:
  32. if around_molecule_sorted[1].get_intensity() == max_intensity:
  33. around_molecules_max.append(around_molecule_sorted)
  34. reverse = False
  35. if molecule_way == cls.WAY_DOWN:
  36. reverse = True
  37. around_molecules_sorted_by_distance = sorted(around_molecules_max,
  38. key=lambda x: x[1].get_distance(),
  39. reverse=reverse)
  40. go_to_point = around_molecules_sorted_by_distance[0][0]
  41. direction_degrees = get_degree_from_north(point, go_to_point)
  42. direction = get_direction_for_degrees(direction_degrees)
  43. return direction
  44. @classmethod
  45. def _get_around_molecules(cls, context, reference_point, molecule_type,
  46. molecule_filter=lambda around_molecule: True):
  47. around_points = context.get_around_points_of_point(reference_point)
  48. around_molecules_points = []
  49. for around_point in around_points:
  50. flavour = context.molecules().get_flavour(around_point)
  51. try:
  52. around_molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
  53. if molecule_filter(around_molecule):
  54. around_molecules_points.append((around_point, around_molecule))
  55. except NoMolecule:
  56. pass # No molecule, ok continue to sniff around
  57. return around_molecules_points
  58. @classmethod
  59. def get_best_molecule_direction_in(cls, context, reference_point, points, molecule_type):
  60. around_molecules_points = []
  61. for around_point in points:
  62. flavour = context.molecules().get_flavour(around_point)
  63. try:
  64. around_molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
  65. around_molecules_points.append((around_point, around_molecule))
  66. except NoMolecule:
  67. pass # Ok, no molecule, continue to sniff around
  68. if not around_molecules_points:
  69. raise NoMolecule()
  70. shuffle(around_molecules_points)
  71. around_molecules_sorted = sorted(around_molecules_points, key=lambda x: x[1].get_intensity(), reverse=True)
  72. go_to_point = around_molecules_sorted[0][0]
  73. direction_degrees = get_degree_from_north(reference_point, go_to_point)
  74. direction = get_direction_for_degrees(direction_degrees)
  75. return direction