
# cellular.py
# elementary cellular automaton
# https://en.wikipedia.org/wiki/Elementary_cellular_automaton

import random, time

LEN = 64
rules = [3, 18, 30, 90, 106, 110, 158, 154, 184] 
#  https://ipython-books.github.io/122-simulating-an-elementary-cellular-automaton/


def printLine(ca):
  print("".join( ["*" if (cell ==1) else " " for cell in ca]))


def step(ca):
  caNext = []
  for i in range(LEN):
    # get left, center, right as a 3-bit binary string
    binStr = str(ca[(i-1)%LEN]) + str(ca[i]) + str(ca[(i+1)%LEN])
    # convert to rule index
    idx = 7 - int(binStr,2)
    # update element
    caNext.append(int(ruleB[idx]))

  return caNext



rule = random.choice(rules)
print("Using rule no.:", rule)
# binary representation of the rule  
ruleB = f"{rule:08b}"

# Random initial state  
ca = [random.choice([0,1]) for i in range(LEN)]
printLine(ca)
while True:
  ca = step(ca)
  printLine(ca)
  time.sleep(0.25)
