Created
November 20, 2013 04:47
-
-
Save cdarringer/7557881 to your computer and use it in GitHub Desktop.
This is your life (according to Conway)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""This is your life (according to Conway) | |
Conway's Game of Life http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life | |
involved a grid of cells, some alive and some dead, and a set of rules that | |
determine whether a given cell "lives" to the next generation or dies. | |
This was my first real experiment with python, and exercised some of the | |
basic control functions, data structures, and features of the language. | |
The user can either select a random grid of cells or grid of cells | |
composed of the characters in their name. | |
author: Chris Darringer | |
""" | |
import random | |
GRID_WIDTH = 60 | |
GRID_HEIGHT = 12 | |
GENERATION_COUNT = 200; | |
def main(): | |
""" create a grid randomly or from user provided string, then enter | |
the generations loop """ | |
name = raw_input('Enter your name or return for a random grid: ') | |
if name == '': | |
grid = buildRandomGrid() | |
else: | |
grid = buildNameGrid(name) | |
for i in range(GENERATION_COUNT): | |
print 'Generation: ', i | |
prettyPrintGrid(grid) | |
grid = transform(grid) | |
raw_input('Press any key to continue...') | |
def transform(grid): | |
""" apply the rules of life to the current grid, and return the results | |
in a new grid, representing the next generation """ | |
def getLeftNeighbor(grid, x, y): | |
return 0 if (x == 0) else grid[y][x-1] | |
def getRightNeighbor(grid, x, y): | |
return 0 if (x == (GRID_WIDTH - 1)) else grid[y][x+1] | |
def getUpperNeighbor(grid, x, y): | |
return 0 if (y == 0) else grid[y-1][x] | |
def getUpperLeftNeighbor(grid, x, y): | |
return 0 if ((x == 0) or (y == 0)) else grid[y-1][x-1] | |
def getUpperRightNeighbor(grid, x, y): | |
return 0 if ((x == (GRID_WIDTH - 1)) or (y == 0)) else grid[y-1][x+1] | |
def getLowerNeighbor(grid, x, y): | |
return 0 if (y == (GRID_HEIGHT - 1)) else grid[y+1][x] | |
def getLowerLeftNeighbor(grid, x, y): | |
return 0 if ((x == 0) or (y == (GRID_HEIGHT - 1))) else grid[y+1][x-1] | |
def getLowerRightNeighbor(grid, x, y): | |
return 0 if ((x == (GRID_WIDTH - 1)) or (y == (GRID_HEIGHT - 1))) else grid[y+1][x+1] | |
def countNeighbors(grid, x, y): | |
count = 0 | |
count += getLeftNeighbor(grid, x, y) | |
count += getRightNeighbor(grid, x, y) | |
count += getUpperNeighbor(grid, x, y) | |
count += getUpperLeftNeighbor(grid, x, y) | |
count += getUpperRightNeighbor(grid, x, y) | |
count += getLowerNeighbor(grid, x, y) | |
count += getLowerLeftNeighbor(grid, x, y) | |
count += getLowerRightNeighbor(grid, x, y) | |
return count | |
def liveOrDie(state, neighborCount): | |
if (state == 1): | |
if (neighborCount < 2): return 0 | |
if (neighborCount > 3): return 0 | |
else: | |
if (neighborCount == 3): return 1 | |
return state | |
newgrid = [[liveOrDie(grid[y][x], countNeighbors(grid, x, y)) for x in range(GRID_WIDTH)] for y in range(GRID_HEIGHT)] | |
return newgrid | |
def buildRandomGrid(): | |
""" create a grid with random living cells """ | |
random.seed() | |
return [[random.randint(0, 1) for x in range(0, GRID_WIDTH)] for y in range(0, GRID_HEIGHT)] | |
def buildNameGrid(name): | |
""" create a grid with cells in the form of a given name string. | |
we store character representations in an alphabet map. the first | |
sequence item in the map value is the width of the character, the | |
second sequence item is a set of points that make up that | |
character """ | |
alphabet = { | |
'A':(4, set([(2,1),(1,2),(3,2),(1,3),(2,3),(3,3),(1,4),(3,4),(1,5),(3,5)])), | |
'B':(4, set([(1,1),(2,1),(1,2),(3,2),(1,3),(2,3),(1,4),(3,4),(1,5),(2,5)])), | |
'C':(4, set([(2,1),(1,2),(3,2),(1,3),(1,4),(3,4),(2,5)])), | |
'D':(4, set([(1,1),(2,1),(1,2),(3,2),(1,3),(3,3),(1,4),(3,4),(1,5),(2,5)])), | |
'E':(4, set([(1,1),(2,1),(3,1),(1,2),(1,3),(2,3),(1,4),(1,5),(2,5),(3,5)])), | |
'F':(4, set([(1,1),(2,1),(3,1),(1,2),(1,3),(2,3),(1,4),(1,5)])), | |
'G':(5, set([(2,1),(3,1),(1,2),(4,2),(1,3),(1,4),(3,4),(4,4),(2,5),(3,5),(4,5)])), | |
'H':(4, set([(1,1),(1,2),(1,3),(1,4),(1,5),(2,3),(3,1),(3,2),(3,3),(3,4),(3,5)])), | |
'I':(4, set([(2,1),(2,2),(2,3),(2,4),(2,5)])), | |
'J':(4, set([(3,1),(3,2),(3,3),(1,4),(3,4),(2,5)])), | |
'K':(4, set([(1,1),(3,1),(1,2),(2,2),(1,3),(1,4),(2,4),(1,5),(3,5)])), | |
'L':(4, set([(1,1),(1,2),(1,3),(1,4),(1,5),(2,5),(3,5)])), | |
'M':(6, set([(1,1),(5,1),(1,2),(2,2),(4,2),(5,2),(1,3),(3,3),(5,3),(1,4),(5,4),(1,5),(5,5)])), | |
'N':(5, set([(1,1),(4,1),(1,2),(2,2),(4,2),(1,3),(3,3),(4,3),(1,4),(4,4),(1,5),(4,5)])), | |
'O':(4, set([(2,1),(1,2),(3,2),(1,3),(3,3),(1,4),(3,4),(2,5)])), | |
'P':(4, set([(1,1),(2,1),(1,2),(3,2),(1,3),(2,3),(1,4),(1,5)])), | |
'Q':(5, set([(2,1),(3,1),(1,2),(4,2),(1,3),(4,3),(1,4),(3,4),(4,4),(2,5),(3,5),(4,5)])), | |
'R':(4, set([(1,1),(2,1),(1,2),(3,2),(1,3),(2,3),(1,4),(3,4),(1,5),(3,5)])), | |
'S':(4, set([(2,1),(3,1),(1,2),(2,3),(3,4),(2,5),(1,5)])), | |
'T':(4, set([(1,1),(2,1),(3,1),(2,2),(2,3),(2,4),(2,5)])), | |
'U':(4, set([(1,1),(3,1),(1,2),(3,2),(1,3),(3,3),(1,4),(3,4),(2,5)])), | |
'V':(6, set([(1,1),(5,1),(1,2),(5,2),(1,3),(5,3),(2,4),(4,4),(3,5)])), | |
'W':(6, set([(1,1),(5,1),(1,2),(5,2),(1,3),(3,3),(5,3),(1,4),(2,4),(4,4),(5,4),(1,5),(5,5)])), | |
'X':(6, set([(1,1),(5,1),(2,2),(4,2),(3,3),(2,4),(4,4),(1,5),(5,5)])), | |
'Y':(6, set([(1,1),(5,1),(2,2),(4,2),(3,3),(3,4),(3,5)])), | |
'Z':(6, set([(1,1),(2,1),(3,1),(4,1),(5,1),(4,2),(3,3),(2,4),(1,5),(2,5),(3,5),(4,5),(5,5)])) | |
} | |
def setLetter(xOff, yOff, character, grid): | |
""" set the cells at the points of the given letter to be living """ | |
for p in (alphabet[character])[1]: | |
grid[p[1] + yOff][p[0] + xOff] = 1 | |
name = name[:9].upper() # we only have enough room for 9 characters | |
xOffset = 1 | |
grid = [[0 for x in range(0, GRID_WIDTH)] for y in range(0, GRID_HEIGHT)] | |
for i in range(len(name)): | |
setLetter(xOffset, 1, name[i], grid) | |
xOffset += (alphabet[name[i]])[0] | |
return grid | |
def prettyPrintGrid(grid): | |
""" print grid with dead cells as blanks and living cells as *s """ | |
for y in range(GRID_HEIGHT): | |
output = '' | |
for x in range(GRID_WIDTH): | |
output += ('*' if (grid[y][x] == 1) else ' ') | |
print output | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment