From 71cda956e5b2726cf8c70faeefb20096a00869b4 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Tue, 18 Dec 2018 13:07:16 -0500 Subject: [PATCH 1/2] NEW Demo Program - Conways' Game of Life --- DemoPrograms/Demo_Conways_Game_of_Life.py | 162 ++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 DemoPrograms/Demo_Conways_Game_of_Life.py diff --git a/DemoPrograms/Demo_Conways_Game_of_Life.py b/DemoPrograms/Demo_Conways_Game_of_Life.py new file mode 100644 index 00000000..cb617af5 --- /dev/null +++ b/DemoPrograms/Demo_Conways_Game_of_Life.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python + +# John Conway's "Game of Life" using a GUI. +# Copyright (C) 2018 PySimpleGUI.org +# GUI provided by PySimpleGUI. +# Core game engine provied by Christian Jacobs + +# An implementation of Conway's Game of Life in Python. + +# Copyright (C) 2013 Christian Jacobs. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import numpy +import PySimpleGUI as sg + +BOX_SIZE = 15 + +class GameOfLife: + + def __init__(self, N=20, T=200): + """ Set up Conway's Game of Life. """ + # Here we create two grids to hold the old and new configurations. + # This assumes an N*N grid of points. + # Each point is either alive or dead, represented by integer values of 1 and 0, respectively. + self.N = N + self.old_grid = numpy.zeros(N * N, dtype='i').reshape(N, N) + self.new_grid = numpy.zeros(N * N, dtype='i').reshape(N, N) + self.T = T # The maximum number of generations + + # Set up a random initial configuration for the grid. + for i in range(0, self.N): + for j in range(0, self.N): + self.old_grid[i][j] = 0 + self.init_graphics() + self.manual_board_setup() + + def live_neighbours(self, i, j): + """ Count the number of live neighbours around point (i, j). """ + s = 0 # The total number of live neighbours. + # Loop over all the neighbours. + for x in [i - 1, i, i + 1]: + for y in [j - 1, j, j + 1]: + if (x == i and y == j): + continue # Skip the current point itself - we only want to count the neighbours! + if (x != self.N and y != self.N): + s += self.old_grid[x][y] + # The remaining branches handle the case where the neighbour is off the end of the grid. + # In this case, we loop back round such that the grid becomes a "toroidal array". + elif (x == self.N and y != self.N): + s += self.old_grid[0][y] + elif (x != self.N and y == self.N): + s += self.old_grid[x][0] + else: + s += self.old_grid[0][0] + return s + + def play(self): + """ Play Conway's Game of Life. """ + + # Write the initial configuration to file. + + self.t = 1 # Current time level + while self.t <= self.T: # Evolve! + # print( "At time level %d" % t) + + # Loop over each cell of the grid and apply Conway's rules. + for i in range(self.N): + for j in range(self.N): + live = self.live_neighbours(i, j) + if (self.old_grid[i][j] == 1 and live < 2): + self.new_grid[i][j] = 0 # Dead from starvation. + elif (self.old_grid[i][j] == 1 and (live == 2 or live == 3)): + self.new_grid[i][j] = 1 # Continue living. + elif (self.old_grid[i][j] == 1 and live > 3): + self.new_grid[i][j] = 0 # Dead from overcrowding. + elif (self.old_grid[i][j] == 0 and live == 3): + self.new_grid[i][j] = 1 # Alive from reproduction. + + # Output the new configuration. + + # The new configuration becomes the old configuration for the next generation. + self.old_grid = self.new_grid.copy() + self.draw_board() + # Move on to the next time level + self.t += 1 + + def init_graphics(self): + self.graph = sg.Graph((600, 600), (0, 0), (450, 450), key='_GRAPH_', change_submits=True, drag_submits=False, + background_color='lightblue') + layout = [ + [sg.Text('Game of Life ', font='ANY 15'), sg.Text('', key='_OUTPUT_', size=(30,1), font='ANY 15')], + [self.graph], + [sg.Button('Go!', key='_DONE_'), + sg.Text(' Delay (ms)') , sg.Slider([0,400], orientation='h', key='_SLIDER_'), + sg.Text(' Number Generations'), sg.Slider([0, 1000],default_value=200, orientation='h', key='_SLIDER2_')] + ] + + self.window = sg.Window('Window Title', ).Layout(layout).Finalize() + event, values = self.window.Read(timeout=0) + self.delay = values['_SLIDER_'] + + + def draw_board(self): + BOX_SIZE = 15 + self.graph.Erase() + for i in range(self.N): + for j in range(self.N): + if self.old_grid[i][j]: + self.graph.DrawRectangle((i * BOX_SIZE, j * BOX_SIZE), + (i * BOX_SIZE + BOX_SIZE, j * (BOX_SIZE) + BOX_SIZE), + line_color='black', fill_color='yellow') + event, values = self.window.Read(timeout=self.delay) + if event in (None, '_DONE_'): + exit() + self.delay = values['_SLIDER_'] + self.T = int(values['_SLIDER2_']) + self.window.Element('_OUTPUT_').Update('Generation {}'.format(self.t)) + + def manual_board_setup(self): + ids = [] + for i in range(self.N): + ids.append([]) + for j in range(self.N): + ids[i].append(0) + while True: # Event Loop + event, values = self.window.Read() + if event is None or event == '_DONE_': + break + mouse = values['_GRAPH_'] + + if event == '_GRAPH_': + if mouse == (None, None): + continue + box_x = mouse[0] // BOX_SIZE + box_y = mouse[1] // BOX_SIZE + if self.old_grid[box_x][box_y] == 1: + id = ids[box_x][box_y] + self.graph.DeleteFigure(id) + self.old_grid[box_x][box_y] = 0 + else: + id = self.graph.DrawRectangle((box_x * BOX_SIZE, box_y * BOX_SIZE), + (box_x * BOX_SIZE + BOX_SIZE, box_y * (BOX_SIZE) + BOX_SIZE), + line_color='black', fill_color='yellow') + ids[box_x][box_y] = id + self.old_grid[box_x][box_y] = 1 + self.window.Element('_DONE_').Update(text='Exit') + +if (__name__ == "__main__"): + game = GameOfLife(N=35, T=200) + game.play() From 098de18d752dbb6c4cf268e0ddbc9ebb1d4d42f2 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Tue, 18 Dec 2018 13:11:37 -0500 Subject: [PATCH 2/2] resized sliders --- DemoPrograms/Demo_Conways_Game_of_Life.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/DemoPrograms/Demo_Conways_Game_of_Life.py b/DemoPrograms/Demo_Conways_Game_of_Life.py index cb617af5..9fb43ba7 100644 --- a/DemoPrograms/Demo_Conways_Game_of_Life.py +++ b/DemoPrograms/Demo_Conways_Game_of_Life.py @@ -97,14 +97,13 @@ class GameOfLife: self.t += 1 def init_graphics(self): - self.graph = sg.Graph((600, 600), (0, 0), (450, 450), key='_GRAPH_', change_submits=True, drag_submits=False, - background_color='lightblue') + self.graph = sg.Graph((600, 600), (0, 0), (450, 450), key='_GRAPH_', change_submits=True, drag_submits=False, background_color='lightblue') layout = [ [sg.Text('Game of Life ', font='ANY 15'), sg.Text('', key='_OUTPUT_', size=(30,1), font='ANY 15')], [self.graph], [sg.Button('Go!', key='_DONE_'), - sg.Text(' Delay (ms)') , sg.Slider([0,400], orientation='h', key='_SLIDER_'), - sg.Text(' Number Generations'), sg.Slider([0, 1000],default_value=200, orientation='h', key='_SLIDER2_')] + sg.Text(' Delay (ms)') , sg.Slider([0,400], orientation='h', key='_SLIDER_', size=(15,15)), + sg.Text(' Num Generations'), sg.Slider([0, 1000],default_value=200, orientation='h',size=(15,15), key='_SLIDER2_')] ] self.window = sg.Window('Window Title', ).Layout(layout).Finalize()