Skip to content

Instantly share code, notes, and snippets.

@WitherOrNot
Created June 14, 2019 04:56
Show Gist options
  • Save WitherOrNot/d5d48f33fb1686ad6333f3162cf71bbc to your computer and use it in GitHub Desktop.
Save WitherOrNot/d5d48f33fb1686ad6333f3162cf71bbc to your computer and use it in GitHub Desktop.
Elementary Cellular Automaton Image Generator
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