Created
June 14, 2019 04:56
-
-
Save WitherOrNot/d5d48f33fb1686ad6333f3162cf71bbc to your computer and use it in GitHub Desktop.
Elementary Cellular Automaton Image Generator
This file contains 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
from PIL import Image | |
import random | |
raw_input = input | |
rule = int(raw_input("Rule: ")) | |
itn = int(raw_input("Number of rows: ")) | |
w = (2*itn)-1 | |
print("") | |
print("Modes:") | |
print("") | |
print("ic - impulse center (default)") | |
print("il - impulse left") | |
print("ir - impulse right") | |
print("rdq - random, density 25%") | |
print("rdh - random, density 50%") | |
print("rdt - random, density 75%") | |
print("") | |
mode = raw_input("Mode: ") | |
if mode == "": | |
mode = "ic" | |
if mode == "ic": | |
on = ([0]*(itn-1))+[1]+([0]*(itn-1)) | |
elif mode == "il": | |
on = [1]+[0]*(w-1) | |
elif mode == "ir": | |
on = [0]*(w-1)+[1] | |
elif mode == "rdq": | |
on = [0]*(w-(w//4))+[1]*((w//4)) | |
random.shuffle(on) | |
elif mode == "rdh": | |
on = [0]*(w//2)+[1]*(w-(w//2)) | |
random.shuffle(on) | |
elif mode == "rdt": | |
on = [1]*(w-(w//4))+[0]*((w//4)) | |
random.shuffle(on) | |
else: | |
mode = "ic" | |
on = ([0]*(itn-1))+[1]+([0]*(itn-1)) | |
cyl = raw_input("Cylindrical? (y/n): ") | |
if "y" == cyl[0] or "Y" == cyl[0]: | |
cyl = True | |
elif "n" == cyl[0] or "N" == cyl[0]: | |
cyl = False | |
else: | |
cyl = False | |
def iterate(rule, iters, on): | |
rule = bin(rule)[2:] | |
rd = {0: [1,1,1], 1: [1,1,0], 2: [1,0,1], 3: [1,0,0], 4: [0,1,1], 5: [0,1,0], 6: [0,0,1], 7: [0,0,0]} | |
rule = "0"*(8-len(rule))+rule if len(rule) < 8 else rule | |
rmap = {tuple(rd[n]):int(rule[n]) for n in range(8)} | |
u = range((iters*2)-1) | |
non = [] | |
for j in u: | |
if j == 0: | |
offsets = [0,1] | |
r = [j+i for i in offsets] | |
r = [0]+[on[x] for x in r] | |
non += [rmap[tuple(r)]] | |
elif j == len(u)-1: | |
offsets = [-1,0] | |
r = [j+i for i in offsets] | |
r = [on[x] for x in r]+[0] | |
non += [rmap[tuple(r)]] | |
else: | |
offsets = [-1,0,1] | |
r = [j+i for i in offsets] | |
r = [on[x] for x in r] | |
non += [rmap[tuple(r)]] | |
return non | |
def iterate_cyl(rule, iters, on): | |
rule = bin(rule)[2:] | |
rd = {0: [1,1,1], 1: [1,1,0], 2: [1,0,1], 3: [1,0,0], 4: [0,1,1], 5: [0,1,0], 6: [0,0,1], 7: [0,0,0]} | |
rule = "0"*(8-len(rule))+rule if len(rule) < 8 else rule | |
rmap = {tuple(rd[n]):int(rule[n]) for n in range(8)} | |
u = range((iters*2)-1) | |
non = [] | |
for j in u: | |
offsets = [-1,0,1] | |
r = [(j+i)%((iters*2)-1) for i in offsets] | |
r = [on[x] for x in r] | |
non += [rmap[tuple(r)]] | |
return non | |
outd = [] | |
for i in range(itn): | |
outd += [255-(255*x) for x in on] | |
if cyl: | |
on = iterate_cyl(rule, itn, on) | |
else: | |
on = iterate(rule, itn, on) | |
out = Image.new("P", (int(w),int(itn))) | |
out.putdata(outd) | |
if cyl: | |
out.save("eca_"+str(rule)+"_"+mode+"_cyl.png") | |
else: | |
out.save("eca_"+str(rule)+"_"+mode+".png") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment