Hellerick_Ferlibay

Conway's Game of Life.py

Jan 11th, 2017
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.94 KB | None | 0 0
  1. import re
  2.  
  3. my_colony = """
  4. *  **   *   *
  5. * *   * * * **
  6. *   *   *   *
  7. * *   * * *  *
  8. *  **   *  ***
  9. """
  10.  
  11.  
  12. def check_borders(colony):
  13.     size = [len(colony), len(colony[0])]
  14.     try:
  15.         crop = [
  16.             min([i for i in range(size[0]) if any(colony[i])]),
  17.             max([i for i in range(size[0]) if any(colony[i])]),
  18.             min([j for j in range(size[1]) if any([c[j] for c in colony])]),
  19.             max([j for j in range(size[1]) if any([c[j] for c in colony])]),
  20.             ]
  21.     except ValueError:
  22.         crop = [0,0,0,0]
  23.     colony = [[colony[i][j] for j in range(crop[2], crop[3]+1)] for i in range(crop[0],crop[1]+1)]
  24.     colony = [[0]*len(colony[0])] + colony + [[0]*len(colony[0])]
  25.     colony = [[0]+c+[0] for c in colony]
  26.     return colony
  27.  
  28.  
  29. def from_string(string):
  30.     colony = [s for s in string.split('\n') if s!='']
  31.     colony = [[0 if c == ' ' else 1 for c in g] for g in colony]
  32.     longest_line = len(max(colony, key = len))
  33.     colony = [[g[i] if i<len(g) else 0 for i in range(longest_line)] for g in colony]
  34.     return check_borders(colony)
  35.  
  36.  
  37. def from_RLE(RLE):
  38.     # described here:
  39.     # http://www.conwaylife.com/wiki/Run_Length_Encoded
  40.     print(RLE)
  41.     string = re.sub(
  42.         r'(\d+)([ob$])',
  43.         lambda x: int(x.group(0)[:-1])*x.group(0)[-1],
  44.         RLE)
  45.     print(string)
  46.     string = re.sub('b', ' ', string)
  47.     string = re.sub(r'\$', ' \n', string)
  48.     return from_string(string)
  49.  
  50.  
  51. def progress(colony):
  52.     neighborings = [
  53.             [-1,-1], [-1,0], [-1,+1],
  54.             [ 0,-1],         [ 0,+1],
  55.             [+1,-1], [+1,0], [+1,+1],
  56.         ]
  57.     size = [len(colony), len(colony[0])]
  58.     new_colony = [i.copy() for i in colony]
  59.     for i in range(size[0]):
  60.         for j in range(size[1]):
  61.             neighbors = 0
  62.             for n in neighborings:
  63.                 if all([
  64.                         0 <= i+n[0] < size[0],
  65.                         0 <= j+n[1] < size[1],
  66.                     ]):
  67.                     if colony[i+n[0]][j+n[1]]:
  68.                         neighbors += 1
  69.             if neighbors < 2: new_colony[i][j] = 0
  70.             if neighbors > 3: new_colony[i][j] = 0
  71.             if neighbors == 3: new_colony[i][j] = 1
  72.     return check_borders(new_colony)
  73.  
  74.  
  75. def show(colony):
  76.     for g in colony:
  77.         print(''.join([' ' + ('o' if c else '·') for c in g]))
  78.  
  79.  
  80. if __name__ == '__main__':
  81.     colony = from_string(my_colony)
  82.     ## colony = from_RLE('4b2o$3b4o2$2b6o$3b4o2$2b2o2b2o$2obo2bob2o$3bo2bo3$4b2o$4b2o')
  83.     alive = True
  84.     phases = set()
  85.     generation = 0
  86.     while alive:
  87.         cells_no = sum([sum(i) for i in colony])
  88.         print('Generation {}, {} cells:'.format(generation, cells_no))
  89.         show(colony)
  90.         colony = progress(colony)
  91.         generation += 1
  92.         fingerprint = hash(repr(colony))
  93.         if fingerprint in phases:
  94.             alive = False
  95.         else:
  96.             phases |= {fingerprint}
Advertisement
Add Comment
Please, Sign In to add comment