Paste: game of life v3
Author: | Daniel Gabriele |
Mode: | factor |
Date: | Sat, 6 Jun 2009 19:38:11 |
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 {relative location : cell}
# That way neighbors can be looked-up easily in a flat list.
#
#
# Helper Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def randcolor (lower=40, upper=230):
cvals = range(lower, upper)
r, g, b = [random.choice(cvals) for i in range(3)]
return pygame.Color(r, g, b)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Cell (object):
def __init__ (self, **kwargs):
# defaults
self.size = (25, 25)
self.oncolor = colors['green']
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(70)
else:
self.image.fill(self.offcolor)
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 = []
# 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):
initstate = random.choice([ON,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,
history=initstate )
row.append(cell)
absx += cell.width
self.cells.append(row)
absy += cell.height
absx = 0
def update (self):
newcolor = randcolor()
for row in self.cells:
for cell in row:
cell.history = cell.state # stores previous state
cell.update() # sets cell state color
states = [ON for (i,j) in cell.nhood if self.cells[i][j].history]
score = sum( states )
# set new cell state
if score < 4 and score > 1 and cell.history:
cell.state = ON
elif score == 3 and not cell.history:
cell.state = ON
cell.oncolor = newcolor
else:
cell.state = OFF
# draw to screen
screen.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]
# ///////////////////////!
if __name__ == '__main__':
grid = Grid((120, 120), (2,2))
screen = pygame.display.set_mode((grid.w*grid.cell_w, grid.h*grid.cell_h))
clock = pygame.time.Clock()
running = True
while running:
clock.tick(36)
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
grid.update()
#pygame.display.update([cell.rect for cell in grid if cell.state])
pygame.display.flip()
New Annotation