DirectionMolecule.py 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. all_same_distance = True
  41. for mol in around_molecules_sorted_by_distance:
  42. mol_mol = mol[1]
  43. if mol_mol.get_distance() != distance:
  44. all_same_distance = False
  45. break
  46. if all_same_distance:
  47. raise NoMolecule()
  48. go_to_point = around_molecules_sorted_by_distance[0][0]
  49. direction_degrees = get_degree_from_north(point, go_to_point)
  50. direction = get_direction_for_degrees(direction_degrees)
  51. return direction
  52. @classmethod
  53. def _get_around_molecules(cls, context, reference_point, molecule_type,
  54. molecule_filter=lambda around_molecule: True):
  55. around_points = context.get_around_points_of_point(reference_point)
  56. around_molecules_points = []
  57. for around_point in around_points:
  58. flavour = context.molecules().get_flavour(around_point)
  59. try:
  60. around_molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
  61. if molecule_filter(around_molecule):
  62. around_molecules_points.append((around_point, around_molecule))
  63. except NoMolecule:
  64. pass # No molecule, ok continue to sniff around
  65. return around_molecules_points
  66. @classmethod
  67. def get_best_molecule_direction_in(cls, context, reference_point, points, molecule_type):
  68. around_molecules_points = []
  69. for around_point in points:
  70. flavour = context.molecules().get_flavour(around_point)
  71. try:
  72. around_molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type)
  73. around_molecules_points.append((around_point, around_molecule))
  74. except NoMolecule:
  75. pass # Ok, no molecule, continue to sniff around
  76. if not around_molecules_points \
  77. or (len(around_molecules_points) == 1 and around_molecules_points[0][0] == reference_point):
  78. raise NoMolecule()
  79. shuffle(around_molecules_points)
  80. around_molecules_sorted = sorted(around_molecules_points, key=lambda x: x[1].get_intensity(), reverse=True)
  81. go_to_point = around_molecules_sorted[0][0]
  82. direction_degrees = get_degree_from_north(reference_point, go_to_point)
  83. direction = get_direction_for_degrees(direction_degrees)
  84. return direction