run.py 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. """
  2. Engulf is simulation containing:
  3. * Subjects who need to:
  4. * eat
  5. * low energy ground stuff
  6. * other alive subjects
  7. * other dead subjects
  8. * sleep
  9. * want to be not alone
  10. * with non aggressive subjects
  11. * want to be alone
  12. * reproduce
  13. * with non aggressive subjects
  14. * and transmit tendencies because their cultures can be
  15. * eat: - eat background stuff, + eat subjects
  16. * alone/not alone: - be alone + not alone
  17. """
  18. import logging
  19. import os
  20. import sys
  21. import typing
  22. synergine2_ath = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../'))
  23. sys.path.append(synergine2_ath)
  24. from random import randint, seed
  25. from sandbox.engulf.behaviour import GrassGrownUp, GrassSpawn, MoveTo, EatEvent, AttackEvent, EatenEvent
  26. from synergine2.config import Config
  27. from synergine2.log import get_default_logger
  28. from sandbox.engulf.subject import Cell, Grass, PreyCell, PredatorCell
  29. from synergine2.core import Core
  30. from synergine2.cycle import CycleManager
  31. from synergine2.terminals import TerminalManager, Terminal, TerminalPackage
  32. from sandbox.engulf.simulation import EngulfSubjects, Engulf
  33. from synergine2.xyz_utils import get_around_positions_of, get_distance_between_points
  34. class GameTerminal(Terminal):
  35. subscribed_events = [
  36. GrassGrownUp,
  37. GrassSpawn,
  38. MoveTo,
  39. EatEvent,
  40. AttackEvent,
  41. EatenEvent,
  42. ]
  43. def __init__(self, *args, **kwargs):
  44. super().__init__(*args, **kwargs)
  45. self.gui = None
  46. self.asynchronous = False # TODO: config
  47. def receive(self, package: TerminalPackage):
  48. self.gui.before_received(package)
  49. super().receive(package)
  50. self.gui.after_received(package)
  51. def run(self):
  52. from sandbox.engulf import gui
  53. self.gui = gui.Game(self.config, self.logger, self)
  54. self.gui.run()
  55. def fill_with_random_cells(
  56. config,
  57. subjects: EngulfSubjects,
  58. count: int,
  59. start_position: tuple,
  60. end_position: tuple,
  61. cell_class: typing.Type[PreyCell],
  62. ) -> None:
  63. cells = []
  64. while len(cells) < count:
  65. position = (
  66. randint(start_position[0], end_position[0]+1),
  67. randint(start_position[1], end_position[1]+1),
  68. 0,
  69. )
  70. if position not in subjects.cell_xyz:
  71. cell = cell_class(
  72. config,
  73. simulation=subjects.simulation,
  74. position=position,
  75. )
  76. cells.append(cell)
  77. subjects.append(cell)
  78. def fill_with_random_grass(
  79. config,
  80. subjects: EngulfSubjects,
  81. start_count: int,
  82. start_position: tuple,
  83. end_position: tuple,
  84. density: int=5,
  85. ) -> None:
  86. grasses = []
  87. while len(grasses) < start_count:
  88. position = (
  89. randint(start_position[0], end_position[0]+1),
  90. randint(start_position[1], end_position[1]+1),
  91. 0,
  92. )
  93. if position not in subjects.grass_xyz:
  94. grass = Grass(
  95. config,
  96. simulation=subjects.simulation,
  97. position=position,
  98. )
  99. grasses.append(grass)
  100. subjects.append(grass)
  101. for grass in grasses:
  102. for around in get_around_positions_of(grass.position, distance=density):
  103. if around not in subjects.grass_xyz:
  104. if subjects.simulation.is_possible_position(around):
  105. new_grass = Grass(
  106. config,
  107. simulation=subjects.simulation,
  108. position=around,
  109. )
  110. distance = get_distance_between_points(around, grass.position)
  111. new_grass.density = 100 - round((distance * 100) / 7)
  112. subjects.append(new_grass)
  113. def main():
  114. seed(42)
  115. config = Config()
  116. config.load_files(['sandbox/engulf/config.yaml'])
  117. logger = get_default_logger(level=logging.DEBUG)
  118. simulation = Engulf(config)
  119. subjects = EngulfSubjects(simulation=simulation)
  120. fill_with_random_cells(
  121. config,
  122. subjects,
  123. 30,
  124. (-34, -34, 0),
  125. (34, 34, 0),
  126. cell_class=PreyCell,
  127. )
  128. fill_with_random_cells(
  129. config,
  130. subjects,
  131. 30,
  132. (-34, -34, 0),
  133. (34, 34, 0),
  134. cell_class=PredatorCell,
  135. )
  136. fill_with_random_grass(
  137. config,
  138. subjects,
  139. 5,
  140. (-34, -34, 0),
  141. (34, 34, 0),
  142. )
  143. simulation.subjects = subjects
  144. core = Core(
  145. config=config,
  146. logger=logger,
  147. simulation=simulation,
  148. cycle_manager=CycleManager(
  149. config=config,
  150. logger=logger,
  151. simulation=simulation,
  152. ),
  153. terminal_manager=TerminalManager(
  154. config=config,
  155. logger=logger,
  156. terminals=[GameTerminal(
  157. config,
  158. logger,
  159. asynchronous=False,
  160. )]
  161. ),
  162. cycles_per_seconds=1/config.core.cycle_duration,
  163. )
  164. core.run()
  165. if __name__ == '__main__':
  166. main()