# libraries import threading import pygame from pyglet.gl import * # for blocky textures # other files of this project from game import Game import project_constants as const from assets.explosion import Explosion def update_graphics(): const.EXPLOSIONS.update() const.EXPLOSIONS.draw(const.SCREEN) pygame.display.flip() def main(): pygame.init() pygame.display.set_caption(const.V_NAME_OF_WINDOW) # for blocky textures glEnable(GL_TEXTURE_2D) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) # FPS clock clock = pygame.time.Clock() # creating some auxiliary functions def is_quit_button_pressed(_events): return any([_event.type == pygame.QUIT for _event in _events]) # setting flags for program running = True in_menu = True auto = False genetics = False genetics_ready = False genetics_in_progress = False is_game_over = False # create and initialize_gui_components game instance game = Game() game.initialize_gui_components() while running: # ============== # # ==== MENU ==== # # ============== # while running and in_menu and not auto: events = pygame.event.get() # checking if game should stop running running = not is_quit_button_pressed(events) # drawing minefield and agent instances game.draw_minefield() # drawing gui overlay game.run_in_game_menu_overlay(pygame.mouse.get_pos(), events) # ticking to maintain good fps number clock.tick(const.V_FPS) # updating window graphics update_graphics() # if ok button is clicked then leave menu section in_menu = not game.button_ok.is_clicked(pygame.mouse.get_pos(), events) # if auto button is clicked then leave menu and start auto-mode auto = game.button_auto.is_clicked(pygame.mouse.get_pos(), events) # if genetics button is clocked then start genetic algorithm genetics = game.button_genetic_algorithm.is_clicked(pygame.mouse.get_pos(), events) if genetics and not (genetics_in_progress or genetics_ready): generations = game.get_input_generations() genetics_in_progress = True game.genetics_done = False threading.Thread(target=game.run_genetics, args=(int(generations), )).start() if genetics_in_progress: genetics = True genetics_ready = game.genetics_done if genetics and genetics_ready: genetics_in_progress = False auto = True # ========================== # # ==== BEFORE GAME LOOP ==== # # ========================== # # initializing action_sequence variable action_sequence = None # getting action sequence for agent if auto and running: in_menu = False if genetics: auto = game.set_next_genetic_target() action_sequence = game.get_action_sequence("mine") else: auto = game.set_random_mine_as_target() action_sequence = game.get_action_sequence("mine") elif running: action_sequence = game.get_action_sequence("tile") # initializing game attributes before the game loop game.initialize_before_game_loop() # prevent incrementing minefield turn before first action first_turn_flag = True # =================== # # ==== GAME LOOP ==== # # =================== # while running and not in_menu and not is_game_over: events = pygame.event.get() # checking if game should stop running running = not is_quit_button_pressed(events) # FPS control clock.tick(const.V_FPS) # getting time since last tick time = clock.get_time() # drawing minefield and agent instances game.draw_minefield() # handling auto button (clicking quits auto-mode) if auto: game.button_auto.set_flags(is_active=True) auto = not game.button_auto.is_clicked(pygame.mouse.get_pos(), events) # drawing inactive gui components so they don't "disappear" game.run_in_game_menu_overlay(pygame.mouse.get_pos(), events) game.set_is_active_flag_for_all_in_game_gui_components(False) # updating graphics update_graphics() # update turn game.update_time(time) game.update_turns() if first_turn_flag: game.revert_minefield_turn() first_turn_flag = False # make the next move from sequence of actions if game.agent_should_take_next_action(action_sequence): # give agent next action game.agent_take_next_action(action_sequence) # reset values after the game loop if game.agent_made_all_actions(action_sequence): if genetics: game.minefield.points -= 1 # clean up after game loop game.agent_take_last_action() game.cleanup_after_game_loop() game.draw_minefield() game.run_in_game_menu_overlay(pygame.mouse.get_pos(), events) update_graphics() if auto: if not game.agent.defuse_a_mine(game.get_mine(game.goal)): print("BOOOOOOM\n\n") game.explosion(game.get_mine(game.goal)) const.EXPLOSIONS.add(Explosion(mine=game.get_mine(game.goal))) else: print("guess you will live a little longer...\n\n") # reset in_menu flag in_menu = True # TODO temporarily disabling game over screen # if you want to enable game over uncomment line below # is_game_over = game.time_mine_exploded() while running and is_game_over: events = pygame.event.get() clock.tick(const.V_FPS) # runs game over screen game.run_game_over_screen(pygame.mouse.get_pos(), events) # checking if game should stop running running = not is_quit_button_pressed(events) \ and not game.button_close.is_clicked(pygame.mouse.get_pos(), events) # resetting is_game_over variable if player tries again if game.button_try_again.is_clicked(pygame.mouse.get_pos(), events): game.cleanup_after_game_loop() is_game_over = False in_menu = True auto = False # updating graphics update_graphics() if __name__ == "__main__": main()