|
@@ -6,7 +6,8 @@ from sandbox.engulf.const import COLLECTION_GRASS
|
6
|
6
|
from synergine2.simulation import SubjectBehaviour, SimulationMechanism, SimulationBehaviour, SubjectBehaviourSelector
|
7
|
7
|
from synergine2.simulation import Event
|
8
|
8
|
from synergine2.utils import ChunkManager
|
9
|
|
-from synergine2.xyz import ProximitySubjectMechanism, DIRECTIONS, DIRECTION_SLIGHTLY
|
|
9
|
+from synergine2.xyz import ProximitySubjectMechanism, DIRECTIONS, DIRECTION_SLIGHTLY, DIRECTION_FROM_NORTH_DEGREES, \
|
|
10
|
+ get_direction_from_north_degree
|
10
|
11
|
from synergine2.xyz_utils import get_around_positions_of_positions, get_around_positions_of, get_position_for_direction
|
11
|
12
|
|
12
|
13
|
|
|
@@ -148,7 +149,19 @@ class SearchFood(SubjectBehaviour):
|
148
|
149
|
use = [EatableDirectProximityMechanism]
|
149
|
150
|
|
150
|
151
|
def run(self, data):
|
151
|
|
- pass
|
|
152
|
+ if not data[EatableDirectProximityMechanism]:
|
|
153
|
+ return False
|
|
154
|
+
|
|
155
|
+ direction_degrees = [d['direction'] for d in data[EatableDirectProximityMechanism]]
|
|
156
|
+ return get_direction_from_north_degree(choice(direction_degrees))
|
|
157
|
+
|
|
158
|
+ def action(self, data) -> [Event]:
|
|
159
|
+ direction = data
|
|
160
|
+ position = get_position_for_direction(self.subject.position, direction)
|
|
161
|
+ self.subject.position = position
|
|
162
|
+ self.subject.previous_direction = direction
|
|
163
|
+
|
|
164
|
+ return [MoveTo(self.subject.id, position)]
|
152
|
165
|
|
153
|
166
|
|
154
|
167
|
class Eat(SubjectBehaviour):
|
|
@@ -165,6 +178,9 @@ class Explore(SubjectBehaviour):
|
165
|
178
|
"""
|
166
|
179
|
use = []
|
167
|
180
|
|
|
181
|
+ def run(self, data):
|
|
182
|
+ return True
|
|
183
|
+
|
168
|
184
|
def action(self, data) -> [Event]:
|
169
|
185
|
direction = self.get_random_direction()
|
170
|
186
|
position = get_position_for_direction(self.subject.position, direction)
|
|
@@ -173,9 +189,6 @@ class Explore(SubjectBehaviour):
|
173
|
189
|
|
174
|
190
|
return [MoveTo(self.subject.id, position)]
|
175
|
191
|
|
176
|
|
- def run(self, data):
|
177
|
|
- return True
|
178
|
|
-
|
179
|
192
|
def get_random_direction(self):
|
180
|
193
|
if not self.subject.previous_direction:
|
181
|
194
|
return choice(DIRECTIONS)
|
|
@@ -194,6 +207,55 @@ class CellBehaviourSelector(SubjectBehaviourSelector):
|
194
|
207
|
|
195
|
208
|
def reduce_behaviours(
|
196
|
209
|
self,
|
197
|
|
- behaviours: typing.Dict[typing.Type[SubjectBehaviour], dict],
|
198
|
|
- ) -> typing.Dict[typing.Type[SubjectBehaviour], dict]:
|
199
|
|
- return behaviours
|
|
210
|
+ behaviours: typing.Dict[typing.Type[SubjectBehaviour], object],
|
|
211
|
+ ) -> typing.Dict[typing.Type[SubjectBehaviour], object]:
|
|
212
|
+ reduced_behaviours = {}
|
|
213
|
+
|
|
214
|
+ for behaviour_class, behaviour_data in behaviours.items():
|
|
215
|
+ if not self.behaviour_class_in_sublist(behaviour_class):
|
|
216
|
+ reduced_behaviours[behaviour_class] = behaviour_data
|
|
217
|
+ elif self.behaviour_class_is_prior(behaviour_class, behaviours):
|
|
218
|
+ reduced_behaviours[behaviour_class] = behaviour_data
|
|
219
|
+
|
|
220
|
+ return reduced_behaviours
|
|
221
|
+
|
|
222
|
+ def behaviour_class_in_sublist(self, behaviour_class: typing.Type[SubjectBehaviour]) -> bool:
|
|
223
|
+ for sublist in self.behaviour_hierarchy:
|
|
224
|
+ if behaviour_class in sublist:
|
|
225
|
+ return True
|
|
226
|
+ return False
|
|
227
|
+
|
|
228
|
+ def behaviour_class_is_prior(
|
|
229
|
+ self,
|
|
230
|
+ behaviour_class: typing.Type[SubjectBehaviour],
|
|
231
|
+ behaviours: typing.Dict[typing.Type[SubjectBehaviour], object],
|
|
232
|
+ ) -> bool:
|
|
233
|
+ for sublist in self.behaviour_hierarchy:
|
|
234
|
+ if behaviour_class in sublist:
|
|
235
|
+ behaviour_position = sublist.index(behaviour_class)
|
|
236
|
+ other_behaviour_top_position = self.get_other_behaviour_top_position(
|
|
237
|
+ behaviour_class,
|
|
238
|
+ behaviours,
|
|
239
|
+ sublist,
|
|
240
|
+ )
|
|
241
|
+ if other_behaviour_top_position is not None and behaviour_position > other_behaviour_top_position:
|
|
242
|
+ return False
|
|
243
|
+ return True
|
|
244
|
+
|
|
245
|
+ def get_other_behaviour_top_position(
|
|
246
|
+ self,
|
|
247
|
+ exclude_behaviour_class,
|
|
248
|
+ behaviours,
|
|
249
|
+ sublist,
|
|
250
|
+ ) -> typing.Union[None, int]:
|
|
251
|
+ position = None
|
|
252
|
+ for behaviour_class in behaviours.keys():
|
|
253
|
+ if behaviour_class != exclude_behaviour_class:
|
|
254
|
+ try:
|
|
255
|
+ behaviour_position = sublist.index(behaviour_class)
|
|
256
|
+ except ValueError:
|
|
257
|
+ pass
|
|
258
|
+ if position is None or behaviour_position < position:
|
|
259
|
+ position = behaviour_position
|
|
260
|
+
|
|
261
|
+ return position
|