Skip to content

Instantly share code, notes, and snippets.

@bancek
Created December 8, 2012 16:42
Show Gist options
  • Save bancek/4240950 to your computer and use it in GitHub Desktop.
Save bancek/4240950 to your computer and use it in GitHub Desktop.
Conway python
import sys
import os
import time
from collections import namedtuple
Cell = namedtuple('Cell', ['x', 'y'])
class World:
def __init__(self, cells):
self.cells = set(cells)
def generate_neighbours(self, cell):
for y in range(cell.y - 1, cell.y + 2):
for x in range(cell.x - 1, cell.x + 2):
if not (x == cell.x and y == cell.y):
yield Cell(x, y)
def find_alive_neighbours(self, cell):
for neighbour in self.generate_neighbours(cell):
if neighbour in self.cells:
yield neighbour
def mutate(self):
new_cells = set()
candidates = set()
for cell in self.cells:
candidates.add(cell)
candidates |= set(self.generate_neighbours(cell))
for candidate in candidates:
if self.evaluate(candidate):
new_cells.add(candidate)
self.cells = new_cells
def evaluate(self, cell):
alive_neighbours = set(self.find_alive_neighbours(cell))
count = len(alive_neighbours)
alive = cell in self.cells
if count < 2:
return False
if count > 3:
return False
if count in (2, 3) and alive:
return True
if count == 3 and not alive:
return True
def render(self):
xs = [cell.x for cell in self.cells]
ys = [cell.y for cell in self.cells]
min_x = min(xs) - 2
max_x = min(max(xs) + 2, 35)
min_y = min(ys) - 2
max_y = min(max(ys) + 2, 15)
for y in range(min_y, max_y + 1):
for x in range(min_x, max_x + 1):
if Cell(x, y) in self.cells:
sys.stdout.write('X ')
else:
sys.stdout.write(' ')
print
if __name__ == '__main__':
grid = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]
cells = set()
for y in range(len(grid)):
for x in range(len(grid[y])):
if grid[y][x]:
cells.add(Cell(x, y))
world = World(cells)
while True:
os.system('clear')
world.render()
world.mutate()
time.sleep(0.1)
from nose.tools import *
from gol import *
def test_generate_neighbours():
world = World([
Cell(1, 2),
Cell(2, 2),
Cell(3, 2)
])
cell = Cell(1, 2)
eq_(len(set(world.generate_neighbours(cell))), 8)
def test_find_alive_neighbours():
world = World([
Cell(1, 2),
Cell(2, 2),
Cell(3, 2)
])
eq_(len(set(world.find_alive_neighbours(Cell(1, 2)))), 1)
eq_(len(set(world.find_alive_neighbours(Cell(0, 2)))), 1)
eq_(len(set(world.find_alive_neighbours(Cell(2, 1)))), 3)
eq_(len(set(world.find_alive_neighbours(Cell(2, 2)))), 2)
def test_evaluate():
world = World([
Cell(1, 2),
Cell(2, 2),
Cell(3, 2)
])
ok_(not world.evaluate(Cell(1, 2)))
ok_(not world.evaluate(Cell(1, 1)))
ok_(not world.evaluate(Cell(3, 2)))
ok_(world.evaluate(Cell(2, 1)))
ok_(world.evaluate(Cell(2, 3)))
def test_mutate():
world = World([
Cell(1, 2),
Cell(2, 2),
Cell(3, 2)
])
world.mutate()
ok_(Cell(2, 1) in world.cells)
ok_(Cell(2, 2) in world.cells)
ok_(Cell(2, 3) in world.cells)
eq_(len(world.cells), 3)
def test_render():
world = World([
Cell(1, 2),
Cell(2, 2),
Cell(3, 2)
])
world.render()
world.mutate()
world.render()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment