Skip to content

Instantly share code, notes, and snippets.

@otykhonruk
Created July 21, 2021 13:33
Show Gist options
  • Save otykhonruk/bbc34fcc9ce96e7e5525fb1636719e35 to your computer and use it in GitHub Desktop.
Save otykhonruk/bbc34fcc9ce96e7e5525fb1636719e35 to your computer and use it in GitHub Desktop.
# Cellular automata
# https://natureofcode.com/book/chapter-7-cellular-automata/
def ca(rule, ncells):
def _next_cell(a, b, c):
a <<= 1
a |= b
a <<= 1
a |= c
return (rule & (1 << a)) >> a
# seed row
ra = [0] * ncells
ra[ncells // 2] = 1
rb = ra[:]
while True:
yield ra
for i in range(ncells - 2):
rb[i+1] = _next_cell(*ra[i:i+3])
ra, rb = rb, ra
if __name__ == '__main__':
from argparse import ArgumentParser
from PIL import Image
parser = ArgumentParser()
parser.add_argument('rule', type=int)
parser.add_argument('cells', type=int, default=512)
parser.add_argument('generations', type=int, default=256)
parser.add_argument('--ppc', help='pixels per cell', type=int, default=2)
parser.add_argument('--out')
args = parser.parse_args()
ppc = args.ppc
image = Image.new('1', (args.cells * ppc, args.generations * ppc))
a = ca(args.rule, args.cells)
for y in range(args.generations):
for x, p in enumerate(next(a)):
# draw cell
oy, ox = y * ppc, x * ppc
for py in range(ppc):
for px in range(ppc):
image.putpixel((ox + px, oy + py), p)
if args.out:
image.save(args.out)
else:
image.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment