def __init__(self, model_gui_elements, caption="Basic Model", patch_size=11, bounce=True, fps=None): # Constants for the main loop in start() below. self.CTRL_D = 'D:68' self.CTRL_d = 'd:68' self.ESCAPE = 'Escape:27' self.FPS = 'FPS' self.NORMAL = 'normal' self.Q = 'Q' self.q = 'q' self.clock = Clock() self.fps = 60 self.idle_fps = 10 self.world = None self.simple_gui = SimpleGUI(model_gui_elements, caption=caption, patch_size=patch_size, bounce=bounce, fps=fps) self.window = self.simple_gui.window self.graph_point = None
def __init__(self, gui_left_upper, caption="Basic Model", gui_right_upper=None, patch_size=11, board_rows_cols=(51, 51), bounce=None, fps=None): # Constants for the main loop in start() below. self.CTRL_D = 'D:68' self.CTRL_d = 'd:68' self.ESCAPE = 'Escape:27' self.FPS = 'FPS' self.NORMAL = 'normal' self.Q = 'Q' self.q = 'q' self.clock = Clock() self.fps = 60 self.idle_fps = 10 self.world = None self.simple_gui = SimpleGUI(gui_left_upper, caption=caption, gui_right_upper=gui_right_upper, patch_size=patch_size, board_rows_cols=board_rows_cols, bounce=bounce, fps=fps) self.graph_point = None
class SimEngine: def __init__(self, model_gui_elements, caption="Basic Model", patch_size=11, bounce=True, fps=None): # Constants for the main loop in start() below. self.CTRL_D = 'D:68' self.CTRL_d = 'd:68' self.ESCAPE = 'Escape:27' self.FPS = 'FPS' self.NORMAL = 'normal' self.Q = 'Q' self.q = 'q' self.clock = Clock() self.fps = 60 self.idle_fps = 10 self.world = None self.simple_gui = SimpleGUI(model_gui_elements, caption=caption, patch_size=patch_size, bounce=bounce, fps=fps) self.window = self.simple_gui.window self.graph_point = None def draw_world(self): # Fill the screen with the background color, draw the world, and update the display. self.simple_gui.fill_screen() self.world.draw() pg.display.update() def model_loop(self): # Run this loop until the model signals it is finished or until the user stops it by pressing the Stop button. while True: (event, values) = self.window.read(timeout=10) if event in (None, self.simple_gui.EXIT): return self.simple_gui.EXIT fps = values.get('fps', None) if fps: self.fps = int(fps) if event == self.simple_gui.GOSTOP: # Enable the GO_ONCE button self.window[self.simple_gui.GO_ONCE].update(disabled=False) break elif self.world.done(): self.window['GoStop'].update(disabled=True) break elif event == '__TIMEOUT__': # Take a step in the simulation. # TICKS are our local counter for the number of times we have gone around this loop. self.world.increment_ticks() self.world.save_event_and_values(event, values) self.world.step() # The next line limits how fast the simulation runs. It is not a counter. self.clock.tick(self.fps) else: self.world.save_event_and_values(event, values) self.world.handle_event_and_values() self.draw_world() return self.NORMAL def top_loop(self, world_class, patch_class, turtle_class): self.world = world_class(patch_class, turtle_class) # Let events come through pygame to this level. pg.event.set_grab(False) # Give event a value so that the while loop can look at it the first time through. event = None while event not in [ self.ESCAPE, self.q, self.Q, self.CTRL_D, self.CTRL_d ]: (event, values) = self.window.read(timeout=10) if event in (None, self.simple_gui.EXIT): self.window.close() break if event == '__TIMEOUT__': continue self.world.save_event_and_values(event, values) if event == self.simple_gui.GRAPH: self.world.mouse_click(values['-GRAPH-']) elif event == self.simple_gui.SETUP: self.window[self.simple_gui.GOSTOP].update(disabled=False) self.window[self.simple_gui.GO_ONCE].update(disabled=False) self.world.reset_all() self.world.setup() elif event == self.simple_gui.GO_ONCE: self.world.increment_ticks() self.world.step() elif event == self.simple_gui.GOSTOP: self.window[self.simple_gui.GOSTOP].update( text='stop', button_color=('white', 'red')) self.window[self.simple_gui.GO_ONCE].update(disabled=True) self.window[self.simple_gui.SETUP].update(disabled=True) returned_value = self.model_loop() self.window['GoStop'].update(text='go', button_color=('white', 'green')) self.window[self.simple_gui.SETUP].update(disabled=False) self.world.final_thoughts() if returned_value == self.simple_gui.EXIT: self.window.close() break else: self.world.handle_event_and_values() self.draw_world() self.clock.tick(self.idle_fps)
class SimEngine: event = None values = None def __init__(self, gui_left_upper, caption="Basic Model", gui_right_upper=None, patch_size=11, board_rows_cols=(51, 51), bounce=None, fps=None): # Constants for the main loop in start() below. self.CTRL_D = 'D:68' self.CTRL_d = 'd:68' self.ESCAPE = 'Escape:27' self.FPS = 'FPS' self.NORMAL = 'normal' self.Q = 'Q' self.q = 'q' self.clock = Clock() self.fps = 60 self.idle_fps = 10 self.world = None self.simple_gui = SimpleGUI(gui_left_upper, caption=caption, gui_right_upper=gui_right_upper, patch_size=patch_size, board_rows_cols=board_rows_cols, bounce=bounce, fps=fps) self.graph_point = None def draw_world(self): # Fill the screen with the background color, draw the world, and update the display. self.simple_gui.fill_screen() self.world.draw() pg.display.update() @staticmethod def get_gui_event(): return SimEngine.event @staticmethod def get_gui_event_and_values(): return (SimEngine.event, SimEngine.values) @staticmethod def get_gui_value(key): value = SimEngine.values.get(key, None) return int(value) if isinstance( value, float) and value == int(value) else value def model_loop(self): # Run this loop until the model signals it is finished or until the user stops it by pressing the Stop button. while True: (SimEngine.event, SimEngine.values) = gui.WINDOW.read(timeout=10) if SimEngine.event in (None, self.simple_gui.EXIT): return self.simple_gui.EXIT fps = SimEngine.values.get('fps', None) if fps: self.fps = fps if SimEngine.event == self.simple_gui.GOSTOP: # Enable the GO_ONCE button gui.WINDOW[self.simple_gui.GO_ONCE].update(disabled=False) break elif self.world._done(): gui.WINDOW['GoStop'].update(disabled=True) break elif SimEngine.event == '__TIMEOUT__': # Take a step in the simulation. # TICKS are our local counter for the number of times we have gone around this loop. self.world.increment_ticks() # self.world.save_event_and_values(SimEngine.event, SimEngine.values) self.world.step() # The next line limits how fast the simulation runs. It is not a counter. self.clock.tick(self.fps) else: # self.world.save_event_and_values(SimEngine.event, SimEngine.values) self.world.handle_event_and_values() self.draw_world() return self.NORMAL def top_loop(self, the_world): self.world = the_world # Let events come through pygame to this level. pg.event.set_grab(False) while SimEngine.event not in [ self.ESCAPE, self.q, self.Q, self.CTRL_D, self.CTRL_d ]: (SimEngine.event, SimEngine.values) = gui.WINDOW.read(timeout=10) if SimEngine.event in (None, self.simple_gui.EXIT): gui.WINDOW.close() break if SimEngine.event == '__TIMEOUT__': continue # self.world.save_event_and_values(event, values) if SimEngine.event == self.simple_gui.GRAPH: self.world.mouse_click(SimEngine.values['-GRAPH-']) elif SimEngine.event == self.simple_gui.SETUP: gui.WINDOW[self.simple_gui.GOSTOP].update(disabled=False) gui.WINDOW[self.simple_gui.GO_ONCE].update(disabled=False) self.world.reset_all() self.world.setup() elif SimEngine.event == self.simple_gui.GO_ONCE: self.world.increment_ticks() self.world.step() elif SimEngine.event == self.simple_gui.GOSTOP: gui.WINDOW[self.simple_gui.GOSTOP].update( text='stop', button_color=('white', 'red')) gui.WINDOW[self.simple_gui.GO_ONCE].update(disabled=True) gui.WINDOW[self.simple_gui.SETUP].update(disabled=True) returned_value = self.model_loop() gui.WINDOW['GoStop'].update(text='go', button_color=('white', 'green')) gui.WINDOW[self.simple_gui.SETUP].update(disabled=False) self.world.final_thoughts() if returned_value == self.simple_gui.EXIT: gui.WINDOW.close() break else: # For anything else, e.g., a button the user defined. self.world.handle_event_and_values() self.draw_world() self.clock.tick(self.idle_fps)
class SimEngine: event = None fps = 60 values = None def __init__(self, gui_left_upper, caption="Basic Model", gui_right_upper=None, patch_size=11, board_rows_cols=(51, 51), clear=None, bounce=None, fps=None): # Constants for the main loop in start() below. self.CTRL_D = 'D:68' self.CTRL_d = 'd:68' self.ESCAPE = 'Escape:27' self.NORMAL = 'normal' self.Q = 'Q' self.q = 'q' self.clock = Clock() SimEngine.fps = fps if fps else 60 self.idle_fps = 10 self.world = None self.simple_gui = SimpleGUI(gui_left_upper, caption=caption, gui_right_upper=gui_right_upper, patch_size=patch_size, board_rows_cols=board_rows_cols, clear=clear, bounce=bounce, fps=fps) self.graph_point = None def draw_world(self): """ Fill the screen with the background color, draw the world, and update the display. """ self.simple_gui.fill_screen() self.world.draw() pg.display.update() @staticmethod def gui_get(key): """ Widgets typically have a 'disabled' property. The following makes it possible to use 'enabled' as the negation of 'disabled'. """ flip = key == 'enabled' if not SimEngine.values: (SimEngine.event, SimEngine.values) = gui.WINDOW.read(timeout=10) value = SimEngine.values.get( key, None) if not flip else not SimEngine.values.get('disabled', None) return int(value) if isinstance( value, float) and value == int(value) else value @staticmethod def gui_set(key, **kwargs): """ Widgets typically have a 'disabled' property. The following makes it possible to use 'enabled' as the negation of 'disabled'. """ if 'enabled' in kwargs: value = kwargs.get('enabled') kwargs['disabled'] = not bool(value) kwargs.pop('enabled') widget = gui.WINDOW[key] widget.update(**kwargs) def model_loop(self): # Run this loop until the model signals it is finished or until the user stops it by pressing the Stop button. while True: (SimEngine.event, SimEngine.values) = gui.WINDOW.read(timeout=10) if SimEngine.event in (None, self.simple_gui.EXIT): return self.simple_gui.EXIT self.set_grab_anywhere(self.gui_get('Grab')) if SimEngine.event == FPS: SimEngine.fps = SimEngine.gui_get(FPS) if SimEngine.event == self.simple_gui.GRAPH: self.world.mouse_click(SimEngine.values['-GRAPH-']) if SimEngine.event == GOSTOP: SimEngine.gui_set(GO_ONCE, enabled=True) break elif self.world.done: SimEngine.gui_set(GOSTOP, enabled=True) SimEngine.gui_set(GO_ONCE, enabled=True) # self.world.done = False break elif SimEngine.event == '__TIMEOUT__': # This increments the World's tick counter for the number of times we have gone around this loop. # Examples.starburst uses it to decide when to "explode." Look at its step method. self.world.increment_ticks() # Take a step in the simulation. self.world.step() # This line limits how fast the simulation runs. It is not a counter. self.clock.tick(SimEngine.fps) else: self.world.handle_event(SimEngine.event) self.draw_world() return self.NORMAL @staticmethod def set_grab_anywhere(allow_grab_anywhere): if allow_grab_anywhere: gui.WINDOW.grab_any_where_on() else: gui.WINDOW.grab_any_where_off() def top_loop(self, the_world, auto_setup=False): self.world = the_world self.draw_world() # Keep setup enabled in case the user wants to change from the default setup. # Let events come through pygame to this level. pg.event.set_grab(False) while SimEngine.event not in [ self.ESCAPE, self.q, self.Q, self.CTRL_D, self.CTRL_d ]: (SimEngine.event, SimEngine.values) = gui.WINDOW.read(timeout=10) if SimEngine.event in (None, self.simple_gui.EXIT): gui.WINDOW.close() break self.set_grab_anywhere(self.gui_get('Grab')) if SimEngine.event == FPS: SimEngine.fps = SimEngine.gui_get(FPS) if not auto_setup and SimEngine.event == '__TIMEOUT__': continue if SimEngine.event == self.simple_gui.GRAPH: self.world.mouse_click(SimEngine.values['-GRAPH-']) elif auto_setup or SimEngine.event == self.simple_gui.SETUP: auto_setup = False SimEngine.gui_set(GOSTOP, enabled=True) SimEngine.gui_set(GO_ONCE, enabled=True) if SimEngine.gui_get('Clear?') in [True, None]: self.world.reset_all() self.world.setup() elif SimEngine.event == GO_ONCE: self.world.increment_ticks() self.world.step() elif SimEngine.event == GOSTOP: SimEngine.gui_set(GOSTOP, text='stop', button_color=('white', 'red')) SimEngine.gui_set(GO_ONCE, enabled=False) SimEngine.gui_set(self.simple_gui.SETUP, enabled=False) returned_value = self.model_loop() SimEngine.gui_set(GOSTOP, text='go', button_color=('white', 'green')) SimEngine.gui_set(self.simple_gui.SETUP, enabled=True) self.world.final_thoughts() if returned_value == self.simple_gui.EXIT: gui.WINDOW.close() break else: # For anything else, e.g., a button the user defined. self.world.handle_event(SimEngine.event) self.draw_world() self.clock.tick(self.idle_fps)