Created
August 30, 2014 12:29
-
-
Save HugoGuiroux/52e0c640d4d8a82dcd79 to your computer and use it in GitHub Desktop.
Successive generations of a celular automaton using rule 30.
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
| #!/usr/bin/python2 | |
| # Author: Hugo Guiroux: http://hugoguiroux.blogspot.fr/ | |
| import sys | |
| from PIL import Image | |
| import random | |
| # The output image (bmp) | |
| img_name = "wolf.bmp" | |
| # Number of generation | |
| if len(sys.argv) < 2: | |
| print "Usage: %s number_of_generation [random_fault]"%(sys.argv[0]) | |
| exit(0) | |
| generation = int(sys.argv[1]) | |
| width = generation * 2 + 1 | |
| randomize = True | |
| if len(sys.argv) > 2: | |
| randomize = int(sys.argv[2]) == 1 | |
| # Information for user | |
| print "Doing %d generation (length = %d)"%(generation, width) | |
| if not randomize: print "Non", | |
| print "Randomized first generation, generating %s"%img_name | |
| # For now use array | |
| cur_gen = [0 for k in range(width)] | |
| next_gen = [0 for k in range(width)] | |
| # Mark the center one | |
| middle = int(width / 2) | |
| # First generation | |
| if randomize: | |
| for i in range(random.randint(0, width - 1)): | |
| cur_gen[random.randint(0, width - 1)] = 1 | |
| else: | |
| cur_gen[middle] = 1 | |
| # Declare rule: 0 = white, 1 = black | |
| rules = {} | |
| # Rule 30 | |
| rules[(0, 0, 0)] = 0 | |
| rules[(0, 0, 1)] = 1 | |
| rules[(0, 1, 0)] = 1 | |
| rules[(0, 1, 1)] = 1 | |
| rules[(1, 0, 0)] = 1 | |
| rules[(1, 0, 1)] = 0 | |
| rules[(1, 1, 0)] = 0 | |
| rules[(1, 1, 1)] = 0 | |
| # Create image | |
| img = Image.new('1', (width, generation + 1), 'white') | |
| def print_gen(gen, img, y): | |
| global generation, width | |
| for k in range(width): | |
| if generation < 50: | |
| print gen[k], | |
| # Print only black pixel, img.putpixel is CPU time consuming | |
| if gen[k] == 1: | |
| img.putpixel((k, y), 1 - gen[k]) | |
| if generation < 50: print | |
| # Generate and print | |
| for cur in range(generation): | |
| # Print current line | |
| print_gen(cur_gen, img, cur) | |
| # Big automata, show progress | |
| if generation >= 50: | |
| print "%s%d/%d"%("\r"*20, cur+1, generation), | |
| # Shift for first row | |
| cur += 1 | |
| # Compute next line | |
| for pos in range(width): #if non randomize, | |
| # xrange(middle - cur, middle + cur + 1) is suffisant | |
| prev_cell = 0 if pos == 0 else cur_gen[pos - 1] | |
| next_cell = 0 if pos == width - 1 else cur_gen[pos + 1] | |
| next_gen[pos] = rules[(prev_cell, cur_gen[pos], next_cell)] | |
| # Switch gen | |
| cur_gen = next_gen[:] | |
| # Print last generation | |
| print_gen(cur_gen, img, generation) | |
| img.save(img_name, "BMP") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment