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
|
|
|
|
7
|
|
|
|
8
|
|
|
class DirectionMolecule(): |
9
|
|
|
|
10
|
|
|
WAY_UP = 'u' |
11
|
|
|
WAY_DOWN = 'd' |
12
|
|
|
|
13
|
|
|
_positions_key = None |
14
|
|
|
|
15
|
|
|
@classmethod |
16
|
|
|
def appose(cls, context, point, molecule): |
17
|
|
|
context.molecules().increment_with_molecule(point, molecule, context.get_cycle()) |
18
|
|
|
context.metas.list.add(MOLECULES, MOLECULES, point, assert_not_in=False) |
19
|
|
|
|
20
|
|
|
@classmethod |
21
|
|
|
def get_direction_for_point(cls, context, point, molecule_type, molecule_way=WAY_UP): |
22
|
|
|
flavour = context.molecules().get_flavour(point) |
23
|
|
|
molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type) |
24
|
|
|
|
25
|
|
|
distance = molecule.get_distance() |
26
|
|
|
around_molecule_filter = lambda around_molecule: around_molecule.get_distance() <= distance # TODO <= ? |
27
|
|
|
if molecule_way == cls.WAY_DOWN: |
28
|
|
|
around_molecule_filter = lambda around_molecule: around_molecule.get_distance() >= distance |
29
|
|
|
around_molecules_points = cls._get_around_molecules(context, point, molecule_type, |
30
|
|
|
molecule_filter=around_molecule_filter) |
31
|
|
|
|
32
|
|
|
if not around_molecules_points \ |
33
|
|
|
or (len(around_molecules_points) == 1 and around_molecules_points[0][0] == point): |
34
|
|
|
raise NoMolecule() |
35
|
|
|
|
36
|
|
|
shuffle(around_molecules_points) |
37
|
|
|
around_molecules_sorted = sorted(around_molecules_points, key=lambda x: x[1].get_intensity(), reverse=True) |
38
|
|
|
max_intensity = around_molecules_sorted[0][1].get_intensity() |
39
|
|
|
|
40
|
|
|
around_molecules_max = [] |
41
|
|
|
for around_molecule_sorted in around_molecules_sorted: |
42
|
|
|
if around_molecule_sorted[1].get_intensity() == max_intensity: |
43
|
|
|
around_molecules_max.append(around_molecule_sorted) |
44
|
|
|
|
45
|
|
|
reverse = False |
46
|
|
|
if molecule_way == cls.WAY_DOWN: |
47
|
|
|
reverse = True |
48
|
|
|
around_molecules_sorted_by_distance = sorted(around_molecules_max, |
49
|
|
|
key=lambda x: x[1].get_distance(), |
50
|
|
|
reverse=reverse) |
51
|
|
|
|
52
|
|
|
all_same_distance = True |
53
|
|
|
for mol in around_molecules_sorted_by_distance: |
54
|
|
|
mol_mol = mol[1] |
55
|
|
|
if mol_mol.get_distance() != distance: |
56
|
|
|
all_same_distance = False |
57
|
|
|
break |
58
|
|
|
|
59
|
|
|
if all_same_distance: |
60
|
|
|
raise NoMolecule() |
61
|
|
|
|
62
|
|
|
go_to_point = around_molecules_sorted_by_distance[0][0] |
63
|
|
|
|
64
|
|
|
direction_degrees = get_degree_from_north(point, go_to_point) |
65
|
|
|
direction = get_direction_for_degrees(direction_degrees) |
66
|
|
|
|
67
|
|
|
return direction |
68
|
|
|
|
69
|
|
|
@classmethod |
70
|
|
|
def _get_around_molecules(cls, context, reference_point, molecule_type, |
71
|
|
|
molecule_filter=lambda around_molecule: True): |
72
|
|
|
around_points = context.get_around_points_of_point(reference_point) |
73
|
|
|
around_molecules_points = [] |
74
|
|
|
for around_point in around_points: |
75
|
|
|
flavour = context.molecules().get_flavour(around_point) |
76
|
|
|
try: |
77
|
|
|
around_molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type) |
78
|
|
|
if molecule_filter(around_molecule): |
79
|
|
|
around_molecules_points.append((around_point, around_molecule)) |
80
|
|
|
except NoMolecule: |
81
|
|
|
pass # No molecule, ok continue to sniff around |
82
|
|
|
|
83
|
|
|
return around_molecules_points |
84
|
|
|
|
85
|
|
|
@classmethod |
86
|
|
|
def get_best_molecule_direction_in(cls, context, reference_point, points, molecule_type): |
87
|
|
|
around_molecules_points = [] |
88
|
|
|
for around_point in points: |
89
|
|
|
flavour = context.molecules().get_flavour(around_point) |
90
|
|
|
try: |
91
|
|
|
around_molecule = flavour.get_molecule(category=MOLECULES_DIRECTION, type=molecule_type) |
92
|
|
|
around_molecules_points.append((around_point, around_molecule)) |
93
|
|
|
except NoMolecule: |
94
|
|
|
pass # Ok, no molecule, continue to sniff around |
95
|
|
|
|
96
|
|
|
if not around_molecules_points \ |
97
|
|
|
or (len(around_molecules_points) == 1 and around_molecules_points[0][0] == reference_point): |
98
|
|
|
raise NoMolecule() |
99
|
|
|
|
100
|
|
|
shuffle(around_molecules_points) |
101
|
|
|
around_molecules_sorted = sorted(around_molecules_points, key=lambda x: x[1].get_intensity(), reverse=True) |
102
|
|
|
go_to_point = around_molecules_sorted[0][0] |
103
|
|
|
|
104
|
|
|
direction_degrees = get_degree_from_north(reference_point, go_to_point) |
105
|
|
|
direction = get_direction_for_degrees(direction_degrees) |
106
|
|
|
|
107
|
|
|
return direction |