Last active
August 29, 2015 14:17
-
-
Save justinfay/9392409823ed6d598bb0 to your computer and use it in GitHub Desktop.
Conways game of life
This file contains hidden or 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
| """ | |
| Any live cell with fewer than two live neighbours dies, as if caused by under-population. | |
| Any live cell with two or three live neighbours lives on to the next generation. | |
| Any live cell with more than three live neighbours dies, as if by overcrowding. | |
| Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction. | |
| """ | |
| import random | |
| class World(object): | |
| def __init__(self, width, height): | |
| self.width = width | |
| self.height = height | |
| self._grid = dict(zip([ | |
| (x,y) | |
| for x in range(width) | |
| for y in range(height)], | |
| random_prob(30))) | |
| def tick(self): | |
| new = {} | |
| for coord, cell in self._grid.items(): | |
| new[coord] = cell.action(list(self.neighbours(coord, 1))) | |
| self._grid = new | |
| def __repr__(self): | |
| lines = '' | |
| for x in range(self.height): | |
| for y in range(self.height): | |
| lines += str(self._grid[(x, y)]) | |
| lines += '\n' | |
| return lines | |
| def neighbours(self, coord, range_): | |
| x, y = coord | |
| # General case. | |
| x_range = [x - 1, x, x + 1] | |
| y_range = [y - 1, y, y + 1] | |
| # Case where touching top or left edge. | |
| if x == 0: | |
| x_range = [self.width - 1, x, x + 1] | |
| if y == 0: | |
| y_range = [self.height - 1, y, y + 1] | |
| # Case where touching right or bottom edge. | |
| if x == self.width - 1: | |
| x_range = [x - 1, x, 0] | |
| if y == self.height - 1: | |
| y_range = [y - 1, y, 0] | |
| for x_ in x_range: | |
| for y_ in y_range: | |
| if (x_, y_) != coord: | |
| if (self._grid[(x_, y_)]): | |
| yield self._grid[(x_, y_,)] | |
| class DeadCell(object): | |
| character = ' ' | |
| def action(self, neighbours): | |
| if len(neighbours) == 3: | |
| return LiveCell() | |
| return DeadCell() | |
| def __repr__(self): | |
| return str(self.character) | |
| __str__ = __repr__ | |
| def __nonzero__(self): | |
| return False | |
| __bool__ = __nonzero__ | |
| class LiveCell(DeadCell): | |
| character = 'x' | |
| def action(self, neighbours): | |
| if len(neighbours) in (2, 3): | |
| return self | |
| return DeadCell() | |
| def __nonzero__(self): | |
| return True | |
| def random_prob(prob): | |
| while True: | |
| if random.choice(range(100)) < prob: | |
| yield LiveCell() | |
| yield DeadCell() | |
| infinite_growth = [ | |
| ((0, 0), LiveCell()), | |
| ((0, 1), LiveCell()), | |
| ((0, 2), LiveCell()), | |
| ((0, 3), DeadCell()), | |
| ((0, 4), LiveCell()), | |
| ((1, 0), LiveCell()), | |
| ((1, 1), DeadCell()), | |
| ((1, 2), DeadCell()), | |
| ((1, 3), DeadCell()), | |
| ((1, 4), DeadCell()), | |
| ((2, 0), DeadCell()), | |
| ((2, 1), DeadCell()), | |
| ((2, 2), DeadCell()), | |
| ((2, 3), LiveCell()), | |
| ((2, 4), LiveCell()), | |
| ((3, 0), DeadCell()), | |
| ((3, 1), LiveCell()), | |
| ((3, 2), LiveCell()), | |
| ((3, 3), DeadCell()), | |
| ((3, 4), LiveCell()), | |
| ((4, 0), LiveCell()), | |
| ((4, 1), DeadCell()), | |
| ((4, 2), LiveCell()), | |
| ((4, 3), DeadCell()), | |
| ((4, 4), LiveCell())] | |
| gospel_glider = """ | |
| ........................O........... | |
| ......................O.O........... | |
| ............OO......OO............OO | |
| ...........O...O....OO............OO | |
| OO........O.....O...OO.............. | |
| OO........O...O.OO....O.O........... | |
| ..........O.....O.......O........... | |
| ...........O...O.................... | |
| ............OO...................... | |
| """ | |
| def get_gospel_glider_grid(): | |
| map = [] | |
| for i, line in enumerate(gospel_glider.strip().split('\n')): | |
| for j, cell in enumerate(list(line.strip())): | |
| if cell == '.': | |
| map.append(((i, j), DeadCell())) | |
| else: | |
| map.append(((i, j), LiveCell())) | |
| return map | |
| if __name__ == "__main__": | |
| import os | |
| import time | |
| world = World(40, 40) | |
| new_map = dict([ | |
| (k, DeadCell()) | |
| for k in world._grid.keys()]) | |
| for coord, cell in get_gospel_glider_grid(): | |
| new_map[coord] = cell | |
| world._grid = new_map | |
| while True: | |
| print world | |
| world.tick() | |
| time.sleep(.2) | |
| #break | |
| os.system('clear') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment