|
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 |