DirectionMolecule.py 4.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. _positions_key = None
  8. @classmethod
  9. def appose(cls, context, point, molecule):
  10. context.molecules().increment_with_molecule(point, molecule, context.get_cycle())
  11. context.metas.list.add(MOLECULES, MOLECULES, point, assert_not_in=False)
  12. @classmethod
  13. def get_direction_for_point(cls, context, point, molecule_type):
  14. flavour = context.molecules().get_flavour(point)
  15. molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
  16. distance = molecule.get_distance()
  17. around_molecule_filter = lambda around_molecule: around_molecule.get_distance() < distance
  18. around_molecules_points = cls._get_around_molecules(context, point, molecule_type,
  19. molecule_filter=around_molecule_filter)
  20. if not around_molecules_points \
  21. or (len(around_molecules_points) == 1 and around_molecules_points[0][0] == point):
  22. raise NoMolecule()
  23. shuffle(around_molecules_points)
  24. around_molecules_sorted = sorted(around_molecules_points, key=lambda x: x[1].get_intensity(), reverse=True)
  25. max_intensity = around_molecules_sorted[0][1].get_intensity()
  26. around_molecules_max = []
  27. for around_molecule_sorted in around_molecules_sorted:
  28. if around_molecule_sorted[1].get_intensity() == max_intensity:
  29. around_molecules_max.append(around_molecule_sorted)
  30. around_molecules_sorted_by_distance = sorted(around_molecules_max,
  31. key=lambda x: x[1].get_distance(),
  32. reverse=False)
  33. go_to_point = around_molecules_sorted_by_distance[0][0]
  34. direction_degrees = get_degree_from_north(point, go_to_point)
  35. direction = get_direction_for_degrees(direction_degrees)
  36. return direction
  37. @classmethod
  38. def _get_around_molecules(cls, context, reference_point, molecule_type,
  39. molecule_filter=lambda around_molecule: True):
  40. around_points = context.get_around_points_of_point(reference_point)
  41. around_molecules_points = []
  42. for around_point in around_points:
  43. flavour = context.molecules().get_flavour(around_point)
  44. try:
  45. around_molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
  46. if molecule_filter(around_molecule):
  47. around_molecules_points.append((around_point, around_molecule))
  48. except NoMolecule:
  49. pass # No molecule, ok continue to sniff around
  50. return around_molecules_points
  51. @classmethod
  52. def get_best_molecule_direction_in(cls, context, reference_point, points, molecule_type):
  53. around_molecules_points = []
  54. for around_point in points:
  55. flavour = context.molecules().get_flavour(around_point)
  56. try:
  57. around_molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
  58. around_molecules_points.append((around_point, around_molecule))
  59. except NoMolecule:
  60. pass # Ok, no molecule, continue to sniff around
  61. if not around_molecules_points \
  62. or (len(around_molecules_points) == 1 and around_molecules_points[0][0] == reference_point):
  63. raise NoMolecule()
  64. shuffle(around_molecules_points)
  65. around_molecules_sorted = sorted(around_molecules_points, key=lambda x: x[1].get_intensity(), reverse=True)
  66. go_to_point = around_molecules_sorted[0][0]
  67. direction_degrees = get_degree_from_north(reference_point, go_to_point)
  68. direction = get_direction_for_degrees(direction_degrees)
  69. return direction