behaviour.py 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. # coding: utf-8
  2. from random import randint
  3. from sandbox.engulf.const import COLLECTION_GRASS
  4. from synergine2.simulation import SubjectBehaviour, SimulationMechanism, SimulationBehaviour
  5. from synergine2.simulation import Event
  6. from synergine2.utils import ChunkManager
  7. from synergine2.xyz import ProximitySubjectMechanism
  8. from synergine2.xyz_utils import get_around_positions_of_positions, get_around_positions_of
  9. class GrassGrownUp(Event):
  10. def __init__(self, subject_id, density, *args, **kwargs):
  11. super().__init__(*args, **kwargs)
  12. self.subject_id = subject_id
  13. self.density = density
  14. def repr_debug(self) -> str:
  15. return '{}: subject_id:{}, density:{}'.format(
  16. self.__class__.__name__,
  17. self.subject_id,
  18. self.density,
  19. )
  20. class GrassSpawn(Event):
  21. def __init__(self, subject_id, position, density, *args, **kwargs):
  22. super().__init__(*args, **kwargs)
  23. self.subject_id = subject_id
  24. self.position = position
  25. self.density = density
  26. def repr_debug(self) -> str:
  27. return '{}: subject_id:{}, position:{}, density:{}'.format(
  28. self.__class__.__name__,
  29. self.subject_id,
  30. self.position,
  31. self.density,
  32. )
  33. class GrassSpotablePositionsMechanism(SimulationMechanism):
  34. parallelizable = True
  35. def run(self, process_number: int=None, process_count: int=None):
  36. chunk_manager = ChunkManager(process_count)
  37. positions = list(self.simulation.subjects.grass_xyz.keys())
  38. positions_chunks = chunk_manager.make_chunks(positions)
  39. spotables = []
  40. for position in positions_chunks[process_number]:
  41. arounds = get_around_positions_of_positions(position)
  42. from_subject = self.simulation.subjects.grass_xyz[position]
  43. around_data = {
  44. 'from_subject': from_subject,
  45. 'around': [],
  46. }
  47. for around in arounds:
  48. if around not in self.simulation.subjects.grass_xyz:
  49. around_data['around'].append(around)
  50. if around_data['around']:
  51. spotables.append(around_data)
  52. return spotables
  53. class GrowUp(SubjectBehaviour):
  54. frequency = 20
  55. def run(self, data):
  56. return True
  57. def action(self, data) -> [Event]:
  58. self.subject.density += 1
  59. return [GrassGrownUp(
  60. self.subject.id,
  61. self.subject.density,
  62. )]
  63. class GrassSpawnBehaviour(SimulationBehaviour):
  64. frequency = 100
  65. use = [GrassSpotablePositionsMechanism]
  66. def run(self, data):
  67. spawns = []
  68. for around_data in data[GrassSpotablePositionsMechanism]:
  69. from_subject = around_data['from_subject']
  70. arounds = around_data['around']
  71. if from_subject.density >= 40:
  72. spawns.extend(arounds)
  73. return spawns
  74. @classmethod
  75. def merge_data(cls, new_data, start_data=None):
  76. start_data = start_data or []
  77. start_data.extend(new_data)
  78. return start_data
  79. def action(self, data) -> [Event]:
  80. from sandbox.engulf.subject import Grass # cyclic
  81. events = []
  82. for position in data:
  83. if position not in list(self.simulation.subjects.grass_xyz.keys()):
  84. new_grass = Grass(
  85. self.simulation,
  86. position=position,
  87. density=20,
  88. )
  89. self.simulation.subjects.append(new_grass)
  90. events.append(GrassSpawn(
  91. new_grass.id,
  92. new_grass.position,
  93. new_grass.density,
  94. ))
  95. return events
  96. class EatableDirectProximityMechanism(ProximitySubjectMechanism):
  97. distance = 1.41 # distance when on angle
  98. feel_collections = [COLLECTION_GRASS]
  99. class MoveTo(Event):
  100. def __init__(self, subject_id: int, position: tuple, *args, **kwargs):
  101. super().__init__(*args, **kwargs)
  102. self.subject_id = subject_id
  103. self.position = position
  104. def repr_debug(self) -> str:
  105. return '{}: subject_id:{}, position:{}'.format(
  106. type(self).__name__,
  107. self.subject_id,
  108. self.position,
  109. )
  110. class SearchFood(SubjectBehaviour):
  111. """
  112. Si une nourriture a une case de distance et cellule non rassasié, move dans sa direction.
  113. """
  114. use = [EatableDirectProximityMechanism]
  115. def run(self, data):
  116. pass
  117. class Eat(SubjectBehaviour):
  118. """
  119. Prduit un immobilisme si sur une case de nourriture, dans le cas ou la cellule n'est as rassasié.
  120. """
  121. def run(self, data):
  122. pass
  123. class Explore(SubjectBehaviour):
  124. """
  125. Produit un mouvement au hasard (ou un immobilisme)
  126. """
  127. use = []
  128. def action(self, data) -> [Event]:
  129. position = self.get_random_around_position()
  130. return [MoveTo(self.subject.id, position)]
  131. def run(self, data):
  132. return True # for now, want move every time
  133. def get_random_around_position(self):
  134. around_positions = get_around_positions_of(self.subject.position)
  135. return around_positions[randint(0, len(around_positions)-1)]