Skip to content

Instantly share code, notes, and snippets.

@cdarringer
Created November 20, 2013 04:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cdarringer/7557881 to your computer and use it in GitHub Desktop.
Save cdarringer/7557881 to your computer and use it in GitHub Desktop.
This is your life (according to Conway)
"""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