summaryrefslogtreecommitdiff
path: root/eca.lua
diff options
context:
space:
mode:
Diffstat (limited to 'eca.lua')
-rw-r--r--eca.lua109
1 files changed, 109 insertions, 0 deletions
diff --git a/eca.lua b/eca.lua
new file mode 100644
index 0000000..6c49e8d
--- /dev/null
+++ b/eca.lua
@@ -0,0 +1,109 @@
+--
+--------------------------------------------------------------------------------
+-- FILE: eca.lua
+-- USAGE: ./eca.lua
+-- DESCRIPTION: drawing elementary cellular automata
+-- OPTIONS: ---
+-- REQUIREMENTS: ---
+-- BUGS: ---
+-- NOTES: ---
+-- AUTHOR: Philipp Gesang (Phg), <megas.kapaneus@gmail.com>
+-- COMPANY:
+-- VERSION: 1.0
+-- CREATED: 14/08/10 19:43:35 CEST
+-- REVISION: ---
+--------------------------------------------------------------------------------
+--
+
+require "life"
+
+local help = gol.helpers
+
+local C, Cs, Ct, P, R, S, match = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.match
+
+
+eca = {}
+
+
+function eca.parse_file (fname)
+ local f = assert(io.open(fname, "r"), "No such file: "..fname..".")
+ local init = f:read("*all")
+ f:close()
+
+ return help.strip(init)
+end
+
+function eca.to_base(number, base)
+ local alphabet, result, cnt, remainder = "0123456789abcdef", "", 0
+ while number > 0 do
+ cnt = cnt + 1
+ number, remainder = math.floor(number / base), (number % base) + 1
+ result = string.sub(alphabet, remainder, remainder) .. result
+ end
+ return result
+end
+
+function eca.gen_rule(nr)
+ local rules = {}
+ local states = { "111", "110", "101", "100", "011", "010", "001", "000" }
+
+ nr = string.format("%8s",eca.to_base(nr, 2)):gsub(" ", "0")
+
+ local n = 1
+ while n <= #states do
+ rules[states[n]] = nr:sub(n,n)
+ n = n + 1
+ end
+
+ return rules
+end
+
+function eca.next_line(from, rule)
+ local new = ""
+ from = "0"..from.."0" -- assume dead borders
+ --from = string.format("0%s0", from)
+
+ local cell = C(S"01")
+ local cells= Ct(cell * #(cell * cell)) / function (t)
+ local three = t[1]..t[2]..t[3]
+ new = new .. rule[three]
+ end
+ lpeg.match(cells^1, from)
+ return new
+end
+
+function eca.gen_frame(from, lines, rule)
+ local new = { [1] = from }
+
+ local cnt = 1
+ local tmp
+ repeat
+ --print(cnt)
+ tmp = eca.next_line(from, rule)
+ table.insert( new, tmp )
+ from = tmp
+ cnt = cnt + 1
+ until cnt == lines
+ --for i,j in ipairs(new) do
+ --print (string.format("%3s >> %s",i,j))
+ --end
+ return eca.next_line(tmp, rule), new
+end
+
+function eca.successive (current)
+ --if not current then print("NOPE")return 1 end
+ --local current = current or {}
+
+ local thisframe
+ current.from, thisframe = eca.gen_frame(current.from, current.framesize, current.rule)
+ if not context then -- cli invocation
+ for _,j in ipairs(thisframe) do
+ io.write(j:gsub("0","ยท"):gsub("1","O").."\n")
+ end
+ else
+
+ end
+ return 0
+end
+
+return eca