Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- #coding=utf8
- """An implementation of John Conway's "Game of Life".
- The universe of the Game of Life is a two-dimensional grid of cells, each
- of which is in one of two states: dead or alive. The state of a cell at
- a discrete time step (tick) is determined through interaction with adjacent
- cells (neighbours).
- At each tick, the following transitions occur:
- 1) If a cell has fewer than two alive neighbours, it dies.
- 2) If a cell has two or three alive neighbours, it lives on into the next generation.
- 3) If a cell has more than three neighbours, it dies.
- 4) If a dead cell has exactly three neighbours, it becomes alive.
- See Wikipedia for more information:
- http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
- """
- #__name__ = "pygol"
- __version__ = '0.0.1'
- __date__ = '2014-05-11'
- # Not really necessary, but I wanted to try out creating my own decorators.
- def _overrides(cls):
- def overrider(method):
- assert(method.__name__ in dir(cls))
- return method
- return overrider
- class grid(object):
- @_overrides(object)
- def __init__(self, width, height):
- self._dim = (width, height)
- self._grid = [ [ False for y in xrange(0, height) ] for x in xrange(0, width) ]
- @property
- def width(self):
- return self._dim[0]
- @property
- def height(self):
- return self._dim[1]
- def __setitem__(self, cell, alive):
- try:
- x, y = int(cell[0]), int(cell[1])
- except (TypeError, AttributeError):
- raise TypeError("Invalid coordinate")
- try:
- self._grid[x][y] = bool(alive)
- except IndexError:
- raise TypeError("Out of bounds")
- except (TypeError, ValueError):
- raise TypeError("Value must be boolean")
- def __getitem__(self, cell):
- try:
- x, y = int(cell[0]), int(cell[1])
- except (TypeError, AttributeError):
- raise TypeError("Invalid coordinate")
- try:
- return self._grid[x][y]
- except IndexError:
- raise TypeError("Out of bounds")
- @_overrides(object)
- def __str__(self):
- return "\n".join( [ "".join( [ "*" if self[(x, y)] else " " for y in xrange(0, self.height) ] ) for x in xrange(0, self.width) ] )
- def tick(self):
- width, height = self.width, self.height
- # Count living neighbours
- def count_living(x, y):
- x_min, y_min = max(0, x-1), max(0, y-1)
- x_max, y_max = min(width-1, x+1), min(height-1, y+1)
- alive = 0
- for i in xrange(x_min, x_max+1):
- for j in xrange(y_min, y_max+1):
- if not (i == x and j == y):
- alive += self._grid[i][j]
- return alive
- # Determine the cells' state for the next generation
- new_grid = [ [ False for y in xrange(0, height) ] for x in xrange(0, width) ]
- # 1. any living cell with fewer than two live neighbours dies
- # 2. any living cell with two or three live neighbours lives on to the next generation
- # 3. any living cell with more than three live neighbours dies
- # 4. any dead cell with exactly three live neighbours becomes alive
- for x in xrange(0, width):
- for y in xrange(0, height):
- alive = self._grid[x][y]
- count = count_living(x,y)
- if alive and count < 2:
- new_grid[x][y] = False
- elif alive and (count == 2 or count == 3):
- new_grid[x][y] = True
- elif alive and count > 3:
- new_grid[x][y] = False
- elif not alive and count == 3:
- new_grid[x][y] = True
- # Transition into next generation
- changes = 0
- for x in xrange(0, width):
- for y in xrange(0, height):
- changes += self._grid[x][y] != new_grid[x][y]
- self._grid = new_grid
- return changes
- def seed(grid, seed):
- import random
- random.seed(seed)
- for x in xrange(0, grid.width):
- for y in xrange(0, grid.height):
- grid[(x, y)] = random.randint(0, 1)
- if __name__ == '__main__':
- g = grid(32, 32)
- seed(g, 16)
- changes = 1
- while changes > 0:
- raw_input()
- print g
- changes = g.tick()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement