#!/usr/bin/python '''Conway's Game of Life placed in the public domain by jc@unternet.net 2011-06-11 ''' import sys, os, Tkinter, random, time, Image, ImageTk WIDTH, HEIGHT = 50, 50 # of game board CELLSIZE = 10 # width and height of a single cell CHANCE = .15 # chance of random cell being alive at start TICKTIME = 500 # time in milliseconds between ticks IMAGE = Image.new('RGBA', (CELLSIZE, CELLSIZE), (255, 255, 255, 0)) class Cell(Tkinter.Label, object): 'a cell is the basic unit of Life' def __init__(self, master, image, alive = 'random'): 'cell constructor' super(Cell, self).__init__(master, image = image) self.alive, self.board = alive, master if alive == 'random': self.alive = [False, True][(random.random() < CHANCE)] self.tick[1](self) def phase_1(self): "set this cell's state; don't update its representation until phase 2" surrounded_by = self.live_neighbors() if surrounded_by < 2 or surrounded_by > 3: # rules 1 and 3 self.alive = False elif surrounded_by == 3: # rule 4; rule 2 is covered by default self.alive = True def phase_2(self): "based on the decisions made in phase 1, update this cell's state" self.config({'background': ['white', 'green'][self.alive]}) def live_neighbors(self): 'determine living neighbors based on their color' grid_info = self.grid_info() row, column, living = int(grid_info['row']), int(grid_info['column']), 0 for r in row - 1, row, row + 1: for c in column - 1, column, column + 1: try: cell = self.master.grid_slaves(row = r, column = c)[0] living += cell.cget('background') == 'green' except: pass # presumed to be a nonexistent cell on the border living -= (self.cget('background') == 'green') # don't count myself return living tick = [phase_1, phase_2] class Board(Tkinter.Tk, object): "the 'game board' of Life" def __init__(self): 'set up the game board' super(Board, self).__init__(None) self.title("Conway's Game of Life") self.IMAGE = ImageTk.PhotoImage(IMAGE) # now create the cells for row in range(HEIGHT): for column in range(WIDTH): Cell(self, self.IMAGE).grid(row = row, column = column) self.after(TICKTIME, self.tick) def tick(self): 'run one "generation", or "tick"' for cell in self.children.values(): cell.tick[0](cell) for cell in self.children.values(): cell.tick[1](cell) self.after(TICKTIME, self.tick) if __name__ == '__main__': # run program, not import or pydoc life = Board() life.mainloop()