# Paste: game of life v3

Author: Daniel Gabriele python Sun, 7 Jun 2009 01:58:14
Plain Text |
```#!/usr/bin/env python
# life.py
'''
Conway's Game of Life '''

import random
import itertools
import pygame

# Set Up
pygame.init()
colors = pygame.color.THECOLORS
ON, OFF = 1, 0

# The Plan:
# Put the cells in a dict from {cell : neighbor vectors}
# That way neighbors can be looked-up easily in a flat list.
#
#
# Helper Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
def randcolor (lower=40, upper=200):
cvals = range(lower, upper)
r, g, b = [random.choice(cvals) for i in range(3)]
return pygame.Color(r, g, b)

def randgreen (lower=90, upper=250):
cvals = range(lower, upper)
g = random.choice(cvals)
return pygame.Color(g-lower, g, 0)

def randred (lower=90, upper=250):
cvals = range(lower, upper)
r = random.choice(cvals)
return pygame.Color(r, r-lower, 0)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
class Cell (object):

def __init__ (self, **kwargs):

# defaults
self.size = (25, 25)
self.alpha = 90
self.oncolor = randgreen()
self.offcolor = colors['black']
self.state = OFF

# absolute topleft pixel position.
self.position = 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(self.alpha)
else:
self.image.set_alpha(90)
self.image.fill(self.offcolor)

def scale_alpha(self, inc):
next_step = self.alpha + inc
if next_step < 255 and next_step > 0:
self.alpha = next_step

def __repr__ (self):
return "<cell>"

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
class Grid (object):

def __init__ (self, gridsize, cellsize):
self.cell_w, self.cell_h = cellsize   # cell w, h
self.w, self.h = gridsize             # grid w, h
self.n = self.w * self.h              # n cells
self.cells = []       		          # a 2D array

# Initial Configuration
self._do_init_config()

def _do_init_config (self):
absx = absy = 0
for i in xrange(self.h):
row = []
for j in xrange(self.w):
if i % random.randint(2,8) == 0:
initstate = random.choice([ON,OFF])
else:
initstate = OFF

nhood = self._get_neighbors(i, j)
cell = Cell( nhood = [n for n in nhood],
size=(self.cell_w, self.cell_h),
position=(absx, absy),
state=initstate,
past=initstate )

row.append(cell)
absx += cell.width

self.cells.append(row)
absy += cell.height
absx = 0

def update (self, surface):
newcolor = randgreen()
for row in self.cells:
for cell in row:

cell.past = cell.state    # stores previous state
cell.update()             # sets cell state color

states = [1 for (i,j) in cell.nhood if self.cells[i][j].past]
score = sum( states )

# set new cell state
if score < 4 and score > 1 and cell.past:
cell.oncolor = randred()
cell.state = ON
elif score == 3 and not cell.past:
cell.state = ON
cell.oncolor = newcolor
else:
cell.state = OFF

# draw to screen
surface.blit(cell.image, cell.position)

def _get_neighbors (self, x, y):
for point in itertools.product(range(-1,2), range(-1,2)):
_x, _y = point[0]+x, point[1]+y
if (x, y) == (_x, _y): continue
_x %= self.w
_y %= self.h
yield (_x, _y)

def __getitem__ (self, i):
i, j = divmod(i, self.w)
return self.cells[i][j]

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
class Automaton (object):

def __init__ (self, grid_size, cell_size):
self.grid = Grid(grid_size, cell_size)
self.grid_size = grid_size
self.cell_size = cell_size
self.clock = pygame.time.Clock()
self.running = False

def seed (self):
self.scrsize = [self.grid_size[i] * self.cell_size[i] for i in [0,1]]
self.screen = pygame.display.set_mode(self.scrsize)
self.running = True

while self.running:
self.clock.tick(36)
for e in pygame.event.get():
if hasattr(e, 'pos') and e.type == pygame.MOUSEBUTTONDOWN:
self._mouse_handler(e)
elif hasattr(e, 'key') and e.type == pygame.KEYDOWN:
self._key_handler(e)

self.grid.update(self.screen)
pygame.display.flip()

def _mouse_handler (self, e):
for cell in self.grid: # OH MY GOD
if e.pos[0] > cell.rect.left and e.pos[0] < cell.rect.right and \
e.pos[1] > cell.rect.top and e.pos[1] < cell.rect.bottom:
for pos in cell.nhood:
self.grid.cells[pos[0]][pos[1]].state = ON

def _key_handler (self, e):
if e.key == pygame.K_q or e.key == pygame.K_ESCAPE:
self.running = False
elif e.key == pygame.K_UP:
for cell in self.grid:
cell.scale_alpha(10)
elif e.key == pygame.K_DOWN:
for cell in self.grid:
cell.scale_alpha(-10)

# ///////////////////////!
if __name__ == '__main__':
grid_size = (60, 60)  # grid and cell sizes must be squares
cell_size = (8, 8)
automaton = Automaton( grid_size, cell_size )
automaton.seed()
```

## New Annotation

Summary: actionscriptada95antlrapacheconfapdlapplescriptaspaspect-jassembly-m68kassembly-macro32assembly-parrotassembly-r2000assembly-x86awkbbatchbbjbcelbeanshellbibtexcc#c++chillcilclipscobolcoldfusioncsscsvcudacvs-commitddjangodoxygendsssleiffelembperlerlangfactorfhtmlforthfortranfoxprofreemarkergettextgnuplotgroovyhaskellhexhlslhtaccesshtmli4gliconidlinforminiinno-setupinterlisiojavajavaccjavascriptjcljhtmljmkjsplatexlilypondlispliterate-haskelllotosluamailmakefilemaplemlmodula3moinmqscmyghtymysqlnetrexxnqcnsis2objective-cobjectrexxoccamomnimarkpascalpatchperlphppikepl-sqlpl1pop11postscriptpovraypowerdynamoprogressprologpropertiespspptlpvwavepyrexpythonrcprdrebolredcoderelax-ng-compactrenderman-ribrestrfcrhtmlrpm-specrtfrubyrviews#s+sasschemesdl/prsgmlshellscriptshtmlslatesmalltalksmi-mibsql-loadersqrsquidconfsvn-commitswigtcltemplate-toolkittextexinfotexttpltransact-sqltwikityposcriptuscriptvbscriptvelocityverilogvhdlxmlxqxslzpt