-- -------------------------------------------------------------------------------- -- FILE: eca.lua -- USAGE: ./eca.lua -- DESCRIPTION: drawing elementary cellular automata -- OPTIONS: --- -- REQUIREMENTS: --- -- BUGS: --- -- NOTES: --- -- AUTHOR: Philipp Gesang (Phg), -- 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