From 04593730a456e280d00d7ee551c67e6c0b9e2ffa Mon Sep 17 00:00:00 2001 From: Sanky Date: Wed, 17 Oct 2012 08:52:18 +0200 Subject: [PATCH 1/3] cellular.py: a simple 2D cellular automata implementation --- host_python/cellular.py | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 host_python/cellular.py diff --git a/host_python/cellular.py b/host_python/cellular.py new file mode 100644 index 0000000..3fa2802 --- /dev/null +++ b/host_python/cellular.py @@ -0,0 +1,44 @@ +#!/usr/bin/python + +import sys + +from ledbar import Ledbar + +PIXELS = 20 + +rules = {(1,1,1): 0, + (1,1,0): 0, + (1,0,1): 0, + (1,0,0): 1, + (0,1,1): 1, + (0,1,0): 1, + (0,0,1): 1, + (0,0,0): 0} + +iteration = [0]*PIXELS +iteration[PIXELS/2] = 1 + +def iterate(iteration): + new = [] + for i in range(len(iteration)): + if 0 < i < PIXELS-1: + top = (iteration[i-1], iteration[i], iteration[i+1]) + new.append(rules[top]) + else: + new.append(0) + return new + +def update(i): + return (iteration[i], iteration[i], iteration[i]) + +l = Ledbar(PIXELS) +work = True +t = 0 +while work: + for i in xrange(PIXELS): + c = update(i) + l.set_pixel(i, c[0], c[1], c[2]) + work = l.update() + t += 1 + if not (t % 50): + iteration = iterate(iteration) From b09031acafaf651b6517f167c9a2f5a3e9c33340 Mon Sep 17 00:00:00 2001 From: Sanky Date: Wed, 17 Oct 2012 09:53:08 +0200 Subject: [PATCH 2/3] cellular.py: Colors, starting conditions, any rule number --- host_python/cellular.py | 58 ++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/host_python/cellular.py b/host_python/cellular.py index 3fa2802..33b2269 100644 --- a/host_python/cellular.py +++ b/host_python/cellular.py @@ -1,27 +1,55 @@ #!/usr/bin/python +""" +An elementary 2D celluar autonoma implementation for the ledbar in brmlab. +For some fun rules, try: + 30: near-random behavior + 22: gives a symmetric triangle pattern. It just looks like splitting cells and gets +empty quickly, though. + 142: neat waves + 73: provides a downwards pattern with some fixed columns. + 51: likes to blink. + +The color mode encodes individual bits into, well, colors. Not too exciting, +but sure more colorful. + +You can choose between a single pixel or a random starting row. + +Possible fun stuff: Automatically pick new rules, detect patterns and restart. +Also, implement grayscare totalistic autonoma. +""" + import sys +import random from ledbar import Ledbar PIXELS = 20 +PIXEL_MODE = ('bw', 'color')[0] +START = ('single', 'random')[0] +RULE = 30 -rules = {(1,1,1): 0, - (1,1,0): 0, - (1,0,1): 0, - (1,0,0): 1, - (0,1,1): 1, - (0,1,0): 1, - (0,0,1): 1, - (0,0,0): 0} +WIDTH = PIXELS +if PIXEL_MODE == 'color': WIDTH *= 3 -iteration = [0]*PIXELS -iteration[PIXELS/2] = 1 +def bits(num, align=8): + for i in range(align)[::-1]: + yield bool(num & (1 << i)) + +rules = dict(zip(((1,1,1), (1,1,0), (1,0,1), (1,0,0), (0,1,1), (0,1,0), (0,0,1), (0,0,0)), bits(RULE))) + +iteration = [0]*WIDTH +if START == 'single': + iteration[WIDTH//2] = 1 +elif START == 'random': + iteration = list(random.randint(0, 1) for i in iteration) def iterate(iteration): new = [] - for i in range(len(iteration)): - if 0 < i < PIXELS-1: + iteration.insert(0, 0) + iteration.append(0) + for i in xrange(len(iteration)): + if 0 < i < len(iteration)-1: top = (iteration[i-1], iteration[i], iteration[i+1]) new.append(rules[top]) else: @@ -29,7 +57,11 @@ def iterate(iteration): return new def update(i): - return (iteration[i], iteration[i], iteration[i]) + visible = iteration[(len(iteration)//2)-(WIDTH//2):(len(iteration)//2)+(WIDTH//2)] + if PIXEL_MODE == 'bw': + return (visible[i], visible[i], visible[i]) + elif PIXEL_MODE == 'color': + return (visible[3*i], visible[3*i+1], visible[3*i+2]) l = Ledbar(PIXELS) work = True From 64051c397e7233e1bf651bc44852ef82fb46d12c Mon Sep 17 00:00:00 2001 From: Sanky Date: Tue, 30 Oct 2012 15:23:19 +0100 Subject: [PATCH 3/3] cellular.py: Implement totalistic celluar automata. --- host_python/cellular.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/host_python/cellular.py b/host_python/cellular.py index 33b2269..0795b3e 100644 --- a/host_python/cellular.py +++ b/host_python/cellular.py @@ -1,6 +1,6 @@ #!/usr/bin/python """ -An elementary 2D celluar autonoma implementation for the ledbar in brmlab. +An elementary 2D celluar automata implementation for the ledbar in brmlab. For some fun rules, try: 30: near-random behavior 22: gives a symmetric triangle pattern. It just looks like splitting cells and gets @@ -14,8 +14,15 @@ but sure more colorful. You can choose between a single pixel or a random starting row. +By setting TOTALISTIC to True and adding proper rules, you get continuous +totalistic 1D celluar automata. The basic rule mostly just fades out and +in again: it looks like triangles on a plane. But tell me if you find some +more interesting rule! +The RULE format for totalistic automta is a dictionaries of functions which get +passed the sum of the above three pixels. The keys are conditions, if one +returns true, the value is executed. (Thus they shouldn't overlap.) + Possible fun stuff: Automatically pick new rules, detect patterns and restart. -Also, implement grayscare totalistic autonoma. """ @@ -26,8 +33,11 @@ from ledbar import Ledbar PIXELS = 20 PIXEL_MODE = ('bw', 'color')[0] -START = ('single', 'random')[0] -RULE = 30 +START = ('single', 'random')[1] +TOTALISTIC = True +#RULE = 30 +RULE = {(lambda t: True): (lambda t: (t+0.9) % 1)} +SLEEP = 25 WIDTH = PIXELS if PIXEL_MODE == 'color': WIDTH *= 3 @@ -36,13 +46,15 @@ def bits(num, align=8): for i in range(align)[::-1]: yield bool(num & (1 << i)) -rules = dict(zip(((1,1,1), (1,1,0), (1,0,1), (1,0,0), (0,1,1), (0,1,0), (0,0,1), (0,0,0)), bits(RULE))) +if not TOTALISTIC: + rules = dict(zip(((1,1,1), (1,1,0), (1,0,1), (1,0,0), (0,1,1), (0,1,0), (0,0,1), (0,0,0)), bits(RULE))) + iteration = [0]*WIDTH if START == 'single': iteration[WIDTH//2] = 1 elif START == 'random': - iteration = list(random.randint(0, 1) for i in iteration) + iteration = list((random.randint(0, 1) if not TOTALISTIC else random.random()) for i in iteration) def iterate(iteration): new = [] @@ -51,7 +63,12 @@ def iterate(iteration): for i in xrange(len(iteration)): if 0 < i < len(iteration)-1: top = (iteration[i-1], iteration[i], iteration[i+1]) - new.append(rules[top]) + if not TOTALISTIC: + new.append(rules[top]) + else: + for rule, func in RULE.items(): + if rule(sum(top)/3): + new.append(func(sum(top)/3)) else: new.append(0) return new @@ -72,5 +89,5 @@ while work: l.set_pixel(i, c[0], c[1], c[2]) work = l.update() t += 1 - if not (t % 50): + if not (t % SLEEP): iteration = iterate(iteration)