#!/usr/bin/env python # life.py ''' Conway's Game of Life ''' import random import pygame # Set Up pygame.init() colors = pygame.color.THECOLORS ON, OFF = 1, 0 # The Plan: # Put the cells in a dict from {relative location : cell} # That way neighbors can be looked-up easily in a flat list. # # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! class Cell (object): def __init__ (self, **kwargs): self.size = (25, 25) self.oncolor = colors['green'] self.offcolor = colors['black'] self.state = OFF # absolute topleft pixel position. # IE: (25,0), (50,0), (75,0), ... self.position = None # relative position in grid. # IE: (0,0), (1,0), (2,0), ... self.relpos = None # unpack kwargs for k in kwargs: setattr(self, k, kwargs[k]) self._init_default_config() @property def width (self): return self.size[0] @property def height (self): return self.size[1] def _init_default_config (self): self.image = pygame.Surface(self.size) self.image.set_alpha(0) self.rect = self.image.get_rect() if self.state: self.image.fill(self.oncolor) else: self.image.fill(self.offcolor) if hasattr(self, 'position'): self.rect.topleft = self.position def update (self): if self.state: self.image.fill(self.oncolor) self.image.set_alpha(40) else: self.image.fill(self.offcolor) def __repr__ (self): return "" #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! class Grid (object): def __init__ (self, gridsize, cellsize): self.w, self.h = gridsize # grid w, h self.cw, self.ch = cellsize # cell w, h self.n = self.w * self.h # n cells self.cells = {} # relpos:cell look-up ##### Initial Configuration ##### relx = rely = 0 # relative (x,y) coordinates absx = absy = 0 # absolute pixel coordinates # populate grid, setting positions for i in xrange(self.n): cell = Cell( size=(self.cw, self.ch), position=(absx, absy), relpos=(relx, rely), state = random.choice([ON,OFF]) ) # stores previous state cell.history = cell.state # {relpos:cell} self.cells[(relx, rely)] = cell absx += cell.width rely += 1 # wraps coordinate counts to new row if (i + 1) % self.w == 0 and i != 0: absx = 0 relx += 1 absy += cell.height rely = 0 def update (self): for cell in self.cells.itervalues(): cell.history = cell.state # stores previous state cell.update() # sets cell state color x, y = cell.relpos # relative position in grid # Cases for cells on grid boundaries. Wrap around nhood. if x not in (0, self.w-1) and y not in (0, self.h-1): neighbors = [(x-1,y), (x+1,y), (x,y-1), (x,y+1)] elif x == 0 and y == 0: neighbors = [(self.w-1,y), (x+1,y), (x,self.h-1), (x,y+1)] elif x == self.w-1 and y == 0: neighbors = [(x-1,y), (0,y), (x,self.h-1), (x,y+1)] elif x == 0 and y == self.w-1: neighbors = [(x,y-1), (x,0), (self.w-1,y), (x+1, y)] elif x == self.w-1 and y == self.h-1: neighbors = [(x,y-1), (x,0), (x-1,y), (0, y)] elif (x>0 and x0 and x0 and y0 and y 1: cell.state = ON else: cell.state = OFF # draw to screen screen.blit(cell.image, cell.position) def randcolor(self, lower=180, upper=240, alpha=255): cvals = range(lower, upper) r, g, b = [random.choice(cvals) for i in range(3)] return pygame.Color(r, g, b, alpha) # //////////////////////// if __name__ == '__main__': grid = Grid((50, 50), (14,14)) screen = pygame.display.set_mode((grid.w*grid.cw, grid.h*grid.ch)) bg = pygame.Surface(screen.get_size()) clock = pygame.time.Clock() running = True bg.fill((0,0,0)) bg.set_alpha(10) while running: clock.tick(30) for e in pygame.event.get(): if not hasattr(e, 'key'): continue if e.key == pygame.K_q or e.key == pygame.K_ESCAPE: running = False #screen.blit(bg, (0,0)) grid.update() #updaterects = [cell.rect for cell in grid.array if cell.state] #pygame.display.update(updaterects) pygame.display.flip()