play.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import pygame
  2. import argparse
  3. import time
  4. from os.path import exists, join, splitext
  5. import os
  6. import json
  7. from pygame.locals import QUIT, KEYDOWN, K_ESCAPE
  8. from simulation.interface import Interface
  9. from simulation.board import Board
  10. from simulation.player import Player
  11. from simulation.logic.blob_manager import BlobManager
  12. HIDE_GUI = 0
  13. WINDOW_GUI = 1
  14. BORDERLESS_GUI = 2
  15. FULLSCREEN_GUI = 3
  16. SCREEN_RESOLUTION = (1920, 1080)
  17. DEFAULT_DIR = "simulation/default"
  18. def main():
  19. parser = argparse.ArgumentParser()
  20. parser.add_argument('--height', type=int, default=40,
  21. help='New game board height resolution (default: 40)')
  22. parser.add_argument('--width', type=int, default=100,
  23. help='New game board width resolution (default: 100)')
  24. parser.add_argument('-i', '--input', type=str,
  25. help='Initialize game from a save. Overwrite height and width parameters. '
  26. 'Pass the board filename as input (.board extension)')
  27. parser.add_argument('-s', '--scale', type=int, default=10,
  28. help='Scales board resolution by this factor (default: x10)')
  29. parser.add_argument('--save', type=str, default="save/",
  30. help="Pass the directory where saves are stored. (default: save/)")
  31. parser.add_argument('--computing_ratio', type=int, default=1,
  32. help='how many times computing loop is done before drawing GUI')
  33. parser.add_argument('--auto_loops', type=int, default=-1,
  34. help='set number of loops needed before saving and closing automatically')
  35. parser.add_argument('--display', type=int, default=WINDOW_GUI,
  36. help="Set to '{}' to display as centered window, "
  37. "'{}' to display as centered window with no border, "
  38. "'{}' to display as fullscreen, "
  39. "'{}' to hide display (only if auto_loops is set correctly)"
  40. .format(WINDOW_GUI, BORDERLESS_GUI, FULLSCREEN_GUI, HIDE_GUI))
  41. parser.add_argument('--init_foods', type=int, default=0,
  42. help='Starts the game by initializing a certain quantity of foods in one of the half-board')
  43. args = parser.parse_args()
  44. player_file = join(DEFAULT_DIR, "player.json")
  45. blob_file = join(DEFAULT_DIR, "blob.json")
  46. gui_file = join(DEFAULT_DIR, "interface.json")
  47. results = dict()
  48. if args.input is not None:
  49. assert exists(args.input)
  50. root_name = splitext(args.input)[0]
  51. results['From'] = root_name
  52. board = Board(args.width, args.height)
  53. board.load(args.input)
  54. if exists(root_name + ".player.json"):
  55. player_file = root_name + ".player.json"
  56. if exists(root_name + ".blob.json"):
  57. blob_file = root_name + ".blob.json"
  58. else:
  59. board = Board(args.width, args.height)
  60. blob = BlobManager(board, blob_file)
  61. player = Player(board, blob, player_file)
  62. if args.init_foods > 0:
  63. results['Init_foods'] = player.set_random_food(args.init_foods, not player.clean_top)
  64. mode = 0
  65. window_x = int((SCREEN_RESOLUTION[0] - board.width * args.scale) / 2)
  66. window_y = int((SCREEN_RESOLUTION[1] - board.height * args.scale) / 2)
  67. os.environ['SDL_VIDEO_WINDOW_POS'] = str(window_x) + "," + str(window_y)
  68. if args.display == BORDERLESS_GUI:
  69. mode = mode | pygame.NOFRAME
  70. elif args.display == FULLSCREEN_GUI:
  71. mode = mode | pygame.FULLSCREEN
  72. elif args.display == HIDE_GUI:
  73. if args.auto_loops <= 0:
  74. args.display = WINDOW_GUI
  75. gui = Interface(board, player, blob, args.scale, args.save, mode, args.display == HIDE_GUI, gui_file)
  76. if args.auto_loops > 0:
  77. results['Loops'] = args.auto_loops
  78. gui.play = True
  79. init_counter = 100
  80. timer = time.time()
  81. counter = init_counter
  82. init_computing_ratio = args.computing_ratio
  83. ended = False
  84. while not ended and args.auto_loops != 0:
  85. computing_ratio = init_computing_ratio
  86. while computing_ratio > 0 and args.auto_loops != 0:
  87. if gui.play or gui.do_step:
  88. blob.move()
  89. gui.do_step = False
  90. if args.auto_loops > 0:
  91. args.auto_loops -= 1
  92. for event in pygame.event.get():
  93. if event.type == QUIT or event.type == KEYDOWN and event.key == K_ESCAPE:
  94. ended = True
  95. else:
  96. used = gui.event_listener(event)
  97. # Quit automatic mode if user had interactions
  98. if used and args.auto_loops != -1:
  99. args.auto_loops = -1
  100. print("User interaction detected ! \n\t --- Automatic mode stopped.")
  101. computing_ratio -= 1
  102. if args.display != HIDE_GUI:
  103. gui.draw()
  104. pygame.time.wait(10)
  105. counter -= 1
  106. if counter == 0:
  107. timing = time.time() - timer
  108. print("Loop mean time : {:.3f}s per iteration".format(timing / init_counter))
  109. counter = init_counter
  110. timer = time.time()
  111. if args.auto_loops == 0:
  112. name = gui.save()
  113. up_size_percent, down_size_percent = player.check_blob_cover()
  114. results['Covering'] = dict()
  115. results['Covering']['Total'] = (up_size_percent + down_size_percent)/2
  116. results['Covering']['Top'] = up_size_percent
  117. results['Covering']['Bottom'] = down_size_percent
  118. results['To'] = args.save + name
  119. with open(args.save + name + ".results.json", 'w') as file:
  120. json.dump(results, file, indent=4, sort_keys=True)
  121. if __name__ == "__main__":
  122. main()