|
@@ -2,9 +2,15 @@ from synergine.synergy.event.Action import Action
|
2
|
2
|
from intelligine.synergy.event.move.MoveEvent import MoveEvent
|
3
|
3
|
from random import randint, choice, randrange
|
4
|
4
|
from xyzworld.cst import POSITION, POSITIONS
|
5
|
|
-from intelligine.cst import PREVIOUS_DIRECTION, BLOCKED_SINCE
|
|
5
|
+from intelligine.cst import PREVIOUS_DIRECTION, BLOCKED_SINCE, MOVE_MODE, MOVE_MODE_GOHOME, MOVE_MODE_EXPLO, \
|
|
6
|
+ PHEROMON_DIR_EXPLO, PHEROMON_DIR_HOME, PHEROMON_DIRECTION, \
|
|
7
|
+ COL_TRANSPORTER_NOT_CARRYING, COL_TRANSPORTER_CARRYING
|
6
|
8
|
from intelligine.synergy.event.move.direction import directions_same_level, directions_modifiers, directions_slighty
|
7
|
|
-from intelligine.core.exceptions import NoPheromoneMove
|
|
9
|
+from intelligine.core.exceptions import NoPheromoneMove, NoPheromone, BestPheromoneHere
|
|
10
|
+import operator
|
|
11
|
+from intelligine.simulation.pheromone.DirectionPheromone import DirectionPheromone
|
|
12
|
+from xyzworld.geometry import get_degree_from_north
|
|
13
|
+from intelligine.synergy.event.move.direction import get_direction_for_degrees, directions_opposites
|
8
|
14
|
|
9
|
15
|
|
10
|
16
|
class MoveAction(Action):
|
|
@@ -12,28 +18,62 @@ class MoveAction(Action):
|
12
|
18
|
_listen = MoveEvent
|
13
|
19
|
|
14
|
20
|
def __init__(self, object_id, parameters):
|
15
|
|
- super().__init__(object_id, parameters)
|
16
|
|
- self._move_to_point = None
|
17
|
|
- self._move_to_direction = None
|
|
21
|
+ super().__init__(object_id, parameters)
|
|
22
|
+ self._move_to_point = None
|
|
23
|
+ self._move_to_direction = None
|
18
|
24
|
|
19
|
25
|
def prepare(self, context):
|
20
|
|
- object_point = context.metas.value.get(POSITION, self._object_id)
|
21
|
|
- try:
|
22
|
|
- choosed_direction_name, choosed_direction_point = self._get_pheromone_direction_point(context, object_point)
|
23
|
|
- except NoPheromoneMove:
|
24
|
|
- choosed_direction_name, choosed_direction_point = self._get_random_direction_point(context, object_point)
|
25
|
|
- if self._direction_point_is_possible(context, choosed_direction_point):
|
26
|
|
- self._move_to_point = choosed_direction_point
|
27
|
|
- self._move_to_direction = choosed_direction_name
|
28
|
|
-
|
29
|
|
- def _get_random_direction_point(self, context, reference_point):
|
30
|
|
- z, x, y = reference_point
|
31
|
|
- direction_name = self._get_random_direction_name(context)
|
32
|
|
- directions_modifier = directions_modifiers[direction_name]
|
33
|
|
- new_position = (z + directions_modifier[0], x + directions_modifier[1], y + directions_modifier[2])
|
34
|
|
- return (direction_name, new_position)
|
|
26
|
+ object_point = context.metas.value.get(POSITION, self._object_id)
|
|
27
|
+
|
|
28
|
+ try:
|
|
29
|
+ direction = self._get_direction_with_pheromones(context, object_point)
|
|
30
|
+ except NoPheromone:
|
|
31
|
+ direction = self._get_random_direction(context)
|
|
32
|
+
|
|
33
|
+ move_to_point = self._get_point_for_direction(object_point, direction)
|
|
34
|
+ if self._direction_point_is_possible(context, move_to_point):
|
|
35
|
+ self._move_to_point = move_to_point
|
|
36
|
+ self._move_to_direction = direction
|
|
37
|
+ else:
|
|
38
|
+ # TODO: mettre self._dont_move = True ?
|
|
39
|
+ pass
|
|
40
|
+
|
|
41
|
+ def _get_direction_with_pheromones(self, context, object_point):
|
|
42
|
+ # TODO: Placer directnement pheromone type dans les metas
|
|
43
|
+ object_movement_mode = context.metas.value.get(MOVE_MODE, self._object_id)
|
|
44
|
+ pheromone_type = DirectionPheromone.get_pheromone_type_for_move_mode(object_movement_mode)
|
|
45
|
+ try:
|
|
46
|
+ direction = self._get_pheromone_direction_for_point(context, object_point, pheromone_type)
|
|
47
|
+ except NoPheromone:
|
|
48
|
+ direction = self._get_direction_of_pheromone(context, object_point, pheromone_type)
|
|
49
|
+ return direction
|
|
50
|
+
|
|
51
|
+ @staticmethod
|
|
52
|
+ def _get_pheromone_direction_for_point(context, point, pheromone_type):
|
|
53
|
+ return DirectionPheromone.get_direction_for_point(context, point, pheromone_type)
|
|
54
|
+
|
|
55
|
+ @staticmethod
|
|
56
|
+ def _get_direction_of_pheromone(context, point, pheromone_type):
|
|
57
|
+ search_pheromone_distance = 1 # TODO: config
|
|
58
|
+ search_pheromone_in_points = context.get_arround_points_of(point, distance=search_pheromone_distance)
|
|
59
|
+ try:
|
|
60
|
+ # TODO: ? Avoir plutot un DirectionPheromone.get_best_pheromone_direction_in ?
|
|
61
|
+ best_pheromone_direction = DirectionPheromone.get_best_pheromone_direction_in(context,
|
|
62
|
+ point,
|
|
63
|
+ search_pheromone_in_points,
|
|
64
|
+ pheromone_type)
|
|
65
|
+ return best_pheromone_direction
|
|
66
|
+ except NoPheromone as err:
|
|
67
|
+ raise err
|
|
68
|
+
|
|
69
|
+ # def _get_random_direction_point(self, context, reference_point):
|
|
70
|
+ # z, x, y = reference_point
|
|
71
|
+ # direction_name = self._get_random_direction_name(context)
|
|
72
|
+ # directions_modifier = directions_modifiers[direction_name]
|
|
73
|
+ # new_position = (z + directions_modifier[0], x + directions_modifier[1], y + directions_modifier[2])
|
|
74
|
+ # return (direction_name, new_position)
|
35
|
75
|
|
36
|
|
- def _get_random_direction_name(self, context):
|
|
76
|
+ def _get_random_direction(self, context):
|
37
|
77
|
try:
|
38
|
78
|
blocked_since = context.metas.value.get(BLOCKED_SINCE, self._object_id)
|
39
|
79
|
except KeyError:
|
|
@@ -59,14 +99,45 @@ class MoveAction(Action):
|
59
|
99
|
|
60
|
100
|
return direction_name
|
61
|
101
|
|
62
|
|
- def _direction_point_is_possible(self, context, direction_point):
|
|
102
|
+ @staticmethod
|
|
103
|
+ def _get_point_for_direction(reference_point, direction):
|
|
104
|
+ # TODO: mettre une fonction cote direction.py pour appliquer le modifier.
|
|
105
|
+ z, x, y = reference_point
|
|
106
|
+ directions_modifier = directions_modifiers[direction]
|
|
107
|
+ return z + directions_modifier[0], x + directions_modifier[1], y + directions_modifier[2]
|
|
108
|
+
|
|
109
|
+ @staticmethod
|
|
110
|
+ def _direction_point_is_possible(context, direction_point):
|
63
|
111
|
return context.position_is_penetrable(direction_point)
|
64
|
112
|
|
65
|
113
|
def run(self, obj, context, synergy_manager):
|
66
|
|
- if self._move_to_point is not None:
|
|
114
|
+ if self._move_to_point is not None and self._move_to_direction != 14: # TODO: il ne faut pas choisir une direction 14.
|
67
|
115
|
obj.set_position(self._move_to_point)
|
|
116
|
+ #direction_from = directions_opposites[self._move_to_direction]
|
|
117
|
+ #obj.set_direction_from(direction_from)
|
68
|
118
|
context.metas.value.set(PREVIOUS_DIRECTION, self._object_id, self._move_to_direction)
|
69
|
119
|
context.metas.value.set(BLOCKED_SINCE, self._object_id, 0)
|
|
120
|
+ self._appose_pheromone(obj, context)
|
|
121
|
+
|
|
122
|
+ # TEST: le temps de tout tester
|
|
123
|
+ if self._move_to_point == (0, 5, 5) and obj.is_carrying():
|
|
124
|
+ obj_transported = obj.get_carried()
|
|
125
|
+ obj_transported.set_carried_by(None)
|
|
126
|
+ obj.put_carry(obj_transported, (-1, 0, 0))
|
|
127
|
+ obj.get_brain().switch_to_mode(MOVE_MODE_EXPLO)
|
|
128
|
+ context.metas.collections.add_remove(obj.get_id(),
|
|
129
|
+ COL_TRANSPORTER_NOT_CARRYING, COL_TRANSPORTER_CARRYING)
|
|
130
|
+
|
|
131
|
+ # TMP: Devra etre un event et une action
|
|
132
|
+ # if self._move_to_point == (0, 5, 5): # position de depart
|
|
133
|
+ # if len(obj._carried):
|
|
134
|
+ # obj_transported = obj.get_carried()
|
|
135
|
+ # obj_transported.set_carried_by(None)
|
|
136
|
+ # obj.put_carry(obj_transported, (-1, 5, 5))
|
|
137
|
+ # context.metas.collections.add_remove(obj.get_id(), COL_TRANSPORTER_NOT_CARRYING, COL_TRANSPORTER_CARRYING)
|
|
138
|
+ # obj.set_movement_mode(MOVE_MODE_EXPLO)
|
|
139
|
+
|
|
140
|
+
|
70
|
141
|
else:
|
71
|
142
|
try:
|
72
|
143
|
blocked_since = context.metas.value.get(BLOCKED_SINCE, self._object_id)
|
|
@@ -74,6 +145,66 @@ class MoveAction(Action):
|
74
|
145
|
blocked_since = 0
|
75
|
146
|
context.metas.value.set(BLOCKED_SINCE, self._object_id, blocked_since+1)
|
76
|
147
|
|
77
|
|
- def _get_pheromone_direction_point(self, context, object_point):
|
|
148
|
+ # def _get_pheromone_direction_point(self, context, object_point):
|
|
149
|
+ # try:
|
|
150
|
+ # blocked_since = context.metas.value.get(BLOCKED_SINCE, self._object_id)
|
|
151
|
+ # except KeyError:
|
|
152
|
+ # blocked_since = 0
|
|
153
|
+ # if blocked_since > 3:
|
|
154
|
+ # raise NoPheromoneMove()
|
|
155
|
+ # # Si on explore, on cherche pheromone d'explo
|
|
156
|
+ # # si on rentre a home, on cherche pheromone d'home...
|
|
157
|
+ # # TODO: code arrache
|
|
158
|
+ # object_movement_mode = context.metas.value.get(MOVE_MODE, self._object_id)
|
|
159
|
+ # if object_movement_mode == MOVE_MODE_EXPLO:
|
|
160
|
+ # pheromone_direction_type = PHEROMON_DIR_EXPLO
|
|
161
|
+ # elif object_movement_mode == MOVE_MODE_GOHOME:
|
|
162
|
+ # pheromone_direction_type = PHEROMON_DIR_HOME
|
|
163
|
+ #
|
|
164
|
+ # sniff_points = context.get_arround_points_of(object_point, distance=0)
|
|
165
|
+ # # Faire un compile des infos de pheromones
|
|
166
|
+ #
|
|
167
|
+ # directions = {}
|
|
168
|
+ # for sniff_point in sniff_points:
|
|
169
|
+ # info = context.pheromones().get_info(sniff_point,
|
|
170
|
+ # [PHEROMON_DIRECTION, pheromone_direction_type],
|
|
171
|
+ # allow_empty=True,
|
|
172
|
+ # empty_value={})
|
|
173
|
+ # for direction in info:
|
|
174
|
+ # if direction not in directions:
|
|
175
|
+ # directions[direction] = info[direction]
|
|
176
|
+ # else:
|
|
177
|
+ # directions[direction] += info[direction]
|
|
178
|
+ # if len(directions):
|
|
179
|
+ # sorted_directions = sorted(directions.items(), key=operator.itemgetter(1))
|
|
180
|
+ # sorted_directions.reverse()
|
|
181
|
+ # #best_direction_name = sorted_directions[0][0]
|
|
182
|
+ # best_direction_level = sorted_directions[0][1]
|
|
183
|
+ # best_direction_names = [direction for direction in directions \
|
|
184
|
+ # if directions[direction] == best_direction_level]
|
|
185
|
+ # # Si plusieurs best directions, choisir mm direction que la precedente
|
|
186
|
+ # # si y a pas, au hasard.
|
|
187
|
+ # last_dir_name = context.metas.value.get(PREVIOUS_DIRECTION, self._object_id)
|
|
188
|
+ # if last_dir_name in best_direction_names:
|
|
189
|
+ # direction_name = last_dir_name
|
|
190
|
+ # else:
|
|
191
|
+ # direction_name = choice(best_direction_names)
|
|
192
|
+ #
|
|
193
|
+ # # DRY
|
|
194
|
+ # z, x, y = object_point
|
|
195
|
+ # directions_modifier = directions_modifiers[direction_name]
|
|
196
|
+ # new_position = (z + directions_modifier[0], x + directions_modifier[1], y + directions_modifier[2])
|
|
197
|
+ # return (direction_name, new_position)
|
|
198
|
+ #
|
|
199
|
+ # pass
|
|
200
|
+ # raise NoPheromoneMove()
|
78
|
201
|
|
79
|
|
- raise NoPheromoneMove()
|
|
202
|
+ def _appose_pheromone(self, obj, context):
|
|
203
|
+ # TODO: Cette action de pheromone doit etre une surcharge de Move afin d'avoir une Action Move generique.
|
|
204
|
+ obj.get_brain().host_moved()
|
|
205
|
+ try:
|
|
206
|
+ DirectionPheromone.appose(context,
|
|
207
|
+ obj.get_position(),
|
|
208
|
+ obj.get_movement_pheromone_gland().get_movement_molecules())
|
|
209
|
+ except BestPheromoneHere as best_pheromone_here:
|
|
210
|
+ obj.get_brain().set_distance_from_objective(best_pheromone_here.get_best_distance())
|