From 2e2ea4b49f9f3101b4e09b77cd33fefc93c9c3cf Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 15 Aug 2010 01:39:09 +0200 Subject: drawing Wolfram automata (inefficient) --- automata.lua | 253 +++++++++++++++++++++++++++++++++++++++++++ automatarc-global.lua | 61 +++++++++++ automatarc.lua | 53 +++++++++ eca.lua | 109 +++++++++++++++++++ life.lua | 2 +- mplife.lua | 238 ---------------------------------------- mpliferc-global.lua | 59 ---------- mpliferc.lua | 51 --------- run.lua | 60 +++++++--- simpleslides-s-Automaton.tex | 48 ++++++-- 10 files changed, 559 insertions(+), 375 deletions(-) create mode 100644 automata.lua create mode 100644 automatarc-global.lua create mode 100644 automatarc.lua create mode 100644 eca.lua delete mode 100644 mplife.lua delete mode 100644 mpliferc-global.lua delete mode 100644 mpliferc.lua diff --git a/automata.lua b/automata.lua new file mode 100644 index 0000000..a765f2c --- /dev/null +++ b/automata.lua @@ -0,0 +1,253 @@ +-- +-------------------------------------------------------------------------------- +-- FILE: automata.lua +-- USAGE: use with ConTeXt MkIV +-- DESCRIPTION: Metapost output for Conway's Game of Life +-- AUTHOR: Philipp Gesang (Phg), +-- COMPANY: +-- VERSION: 1.0 +-- CREATED: 06/08/10 12:28:35 CEST +-------------------------------------------------------------------------------- +-- + +--require "run" +require "life" + +local C, Cs, Ct, P, R, S, match = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.match + +mplife = {} + +mplife.setup = mplife.setup or {} + +if context then + environment.loadluafile "automatarc-global" + environment.loadluafile "automatarc" +else -- assuming we're staying in pwd + require "automatarc" +end + +mplife.setup.current = {} + + +do + local g, r, c = mplife.setup.global, mplife.setup.rc, mplife.setup.current + for key,_ in pairs(g) do + --print(key, ">>>", tostring(r[key]) .. " or " .. tostring(g[key])) + c[key] = r[key] or g[key] -- prefer local settings + end + mplife.setup.current = c +end + +mplife.format = { + + nl = "\n", space = " ", + + opar = "(", cpar = ")", + + hyphen = "-", comma = ",", + scolon = ";", path = "--", + + filldraw = "fill", -- "draw", + draw = "draw", + cycle = "cycle", + + p = function (x,y) + return string.format("(%s,%s)", x, y) + end, +} + +function mplife.runcode (mpcode) + --context.startMPcode() + context(mpcode) + --context.stopMPcode() + --context.MPdrawing(mpcode) -- comes with next beta! +end + +function mplife.draw_grid(grid, settings) + local h = gol.helpers + local c = mplife.setup.current + local pat = "" + if type(grid) == "string" then + grid = h.split(grid, "\n") -- may leave an empty string as last item + if grid[#grid] == "" then grid[#grid] = nil end + end + + local max = {} + max.x, max.y = grid[1]:len(), #grid + + local n = 0 + while grid[#grid-n] ~= nil do + + local row = grid[#grid-n] + local pos = 1 + + local cell = Cs(R("09") + P("D")) / function (char) + --repeat + local opacity = c.opacity + local p = { x = pos-1, y = n} + + local fill, fade_level = true + --fill = true + + if fill and c.fade then + fade_level = tonumber(char) + end + + if not fade_level then -- no number --> cell once dead (marked "D") + fade_level = 9.3 + end + + if fade_level ~= 0 then -- skip dead cells + if fade_level == 1 then + pat = pat .. string.format("%s %s shifted (%s,%s) withcolor transparent (1,%s,%s);\n", + "draw", c.gestalt, p.x, p.y, opacity*2, settings.color) + else + opacity = opacity - (fade_level * opacity * .1) + end + pat = pat .. string.format("%s %s scaled .9 shifted (%s+.05,%s+.05) withcolor transparent (1,%s,%s);\n", + "filldraw", c.gestalt, p.x, p.y, opacity, settings.color) + end + pos = pos + 1 + end + + local line = cell * ((1-cell) + cell)^0 + line:match(row) + pat = pat .. "\n" + n = n + 1 + end + + pat = pat .. string.format([[ +path border; +border = (0,0)--(%s,0)--(%s,%s)--(0,%s)--cycle; +setbounds currentpicture to boundingbox border ; +]], max.x, max.x, max.y, max.y) + +--fill border withcolor transparent (1,.75, white) ; +--fill border withcolor transparent (1,.3,1white) ; + --print("Pic\n", pat) + mplife.runcode(pat) + return true +end + +--- testing section + +function mplife.checker(n) + local squares = "" + local cnt = 0 + for y=1, n, 1 do + for x=1, n, 1 do + local fill + if cnt % 2 == 0 then fill = true end + local p = { x = x, y = y } + squares = squares .. mplife.p_square( p, fill ) + cnt = cnt + 1 + end + if n % 2 == 0 then cnt = cnt + 1 end -- needed for even column numbers + end + --print (squares) + return squares +end + +function mplife.rand_pattern(n, digits) + local pat = "" + for y=1, n, 1 do + for x=1, n, 1 do + pat = pat .. math.random(0,digits) + end + pat = pat .. "\n" + end + return pat +end + +--- interfacing with life.lua + +function mplife.life_frame (frame) + --local c = mplife.setup.current + + mplife.draw_grid(frame) + + return true +end + +function mplife.life_movie (frames, next_page) + local c = mplife.setup.current + for i, frame in ipairs(frames) do + context(c.before_frame) + mplife.life_frame(frame) + context(c.after_frame) + end +end + +function mplife.life_frames () + local c = mplife.setup.current + + + local frames = gol.frames( c.init, c.rule, c.frames, c.firstframe ) + mplife.life_movie( frames, false ) + return true +end + +function mplife.gol_successive () + local c = mplife.setup.current + local settings = {} + if mplife.slides then + settings.color = "\\MPcolor{simpleslides:contrastcolor}" + else + context.definecolor({ "automaton:color" }, c.color) + settings.color = "\\MPcolor{automaton:color}" + end + context(c.before_frame) + mplife.draw_grid(c.last, settings) + context(c.after_frame) + mplife.setup.current.last = gol.next_frame( c.last, c.rule ) + return true +end + +function mplife.eca_successive () + local c = mplife.setup.current + local settings = {} + + if mplife.slides then + settings.color = "\\MPcolor{simpleslides:contrastcolor}" + else + context.definecolor({ "automaton:color" }, c.color) + settings.color = "\\MPcolor{automaton:color}" + end + + local thisframe + + mplife.setup.current.init, thisframe = eca.gen_frame(c.init, c.framesize, c.rule) + context(c.before_frame) + mplife.draw_grid(thisframe, settings) + context(c.after_frame) + return true +end + +function mplife.main () + local c = mplife.setup.current + + if context then + context.definecolor({ "lifesquare" }, c.color) + end + --mplife.successive() + --context(c.preamble) -- only once + --context.starttext() + + --mplife.runcode (mplife.checker(20)) + + --mplife.draw_grid(mplife.rand_pattern(10,6)) + + --mplife.life_frames() + + --for i=1,10,1 do + --context("\\input knuth") + --context.page() + --end + --context.stoptext() + return 0 +end + + +if not mplife.slides then -- standalone + return mplife.main() +end diff --git a/automatarc-global.lua b/automatarc-global.lua new file mode 100644 index 0000000..95225d9 --- /dev/null +++ b/automatarc-global.lua @@ -0,0 +1,61 @@ +-- +-------------------------------------------------------------------------------- +-- FILE: automatarc-global.lua +-- USAGE: with ConTeXt +-- DESCRIPTION: default settings for the automaton module +-- AUTHOR: Philipp Gesang (Phg), +-- VERSION: 1.0 +-- CREATED: 13/08/10 10:35:46 CEST +-------------------------------------------------------------------------------- +-- + +if not mplife then return 1 end + +mplife.setup.global = {} + +do + local c = {} + + c.file = "examples/sships.gol" + c.rule = gol.parse_rule("B3/S23") -- default Conway + --c.init = gol.parse_file(c.file) + c.last = c.init -- for successive mode + + c.aspect = 3/4 -- actually 1/(x/y), for eca mode + + c.extendx = 0 + c.extendy = 0 + + c.pensize = .1 + c.color = { r = .6, g = .6, b = .8 } + c.opacity = 1/3 + c.fade = true + c.gestalt = "unitsquare" -- try "unitcircle" + + c.firstframe = 1 + c.frames = 5 + + c.preamble = [[ +\setupcolors[state=start] +\setupbackgrounds[state=start] +\setuppapersize[S6][S6] + +\setuppagenumbering[state=stop,location=] + +\defineoverlay[back][\ctxlua{mplife.successive()}] + +\setupbackgrounds [page] [background=back] +]] + c.before_frame = [[ +\startMPcode +pickup pencircle xyscaled (.25*]] .. c.pensize .. [[pt, ]] .. c.pensize .. [[pt) rotated 45; +]] + c.after_frame = [[ +currentpicture := currentpicture xysized (\the\paperwidth, \the\paperheight); +\stopMPcode +]] + + mplife.setup.global = c +end + +return mplife.setup.global diff --git a/automatarc.lua b/automatarc.lua new file mode 100644 index 0000000..506b7f5 --- /dev/null +++ b/automatarc.lua @@ -0,0 +1,53 @@ +if not mplife then return 1 end + +mplife.setup.rc = {} + +do + local c = {} + + --c.file = "examples/10x10_glider.gol" + --c.file = "examples/gliders.gol" + c.file = "examples/ggun.gol" + --c.file = "examples/sships.gol" + c.rule = gol.parse_rule("B3/S23") -- default Conway + --c.init = gol.parse_file(c.file) + c.last = c.init -- for successive mode + + c.aspect = 3/4 + + c.extendx = 0 + c.extendy = 0 + + c.pensize = .1 + c.color = { r = .6, g = .6, b = .8 } + c.opacity = 1/3 + c.fade = true + c.gestalt = "unitsquare" -- try "unitcircle" + + c.firstframe = 1 + c.frames = 5 + + c.preamble = [[ +\setupcolors[state=start] +\setupbackgrounds[state=start] +\setuppapersize[S6][S6] + +\setuppagenumbering[state=stop,location=] + +\defineoverlay[back][\ctxlua{mplife.successive()}] + +\setupbackgrounds [page] [background=back] +]] + c.before_frame = [[ +\startMPcode +pickup pencircle xyscaled (.25*]] .. c.pensize .. [[pt, ]] .. c.pensize .. [[pt) rotated 45; +]] + c.after_frame = [[ +currentpicture := currentpicture xysized (\the\paperwidth, \the\paperheight); +\stopMPcode +]] + + mplife.setup.rc = c +end + +return mplife.setup.rc 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), +-- 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 diff --git a/life.lua b/life.lua index 41e2912..af0cb6e 100644 --- a/life.lua +++ b/life.lua @@ -233,6 +233,7 @@ function gol.parse_file (fname) local p_fn = (1-p_suf)^1 * C(p_suf) local suffix = p_fn:match(fname) or ".gol" -- assume .gol format as default + print("HERE!!!!!!!!!"..suffix) local tmp = gol.formats[suffix] ( fname ) if mplife and mplife.setup.current and ( mplife.setup.current.extendx > 0 or @@ -424,4 +425,3 @@ function gol.pre_movie (frames, section) end return gol - diff --git a/mplife.lua b/mplife.lua deleted file mode 100644 index 7c67719..0000000 --- a/mplife.lua +++ /dev/null @@ -1,238 +0,0 @@ --- --------------------------------------------------------------------------------- --- FILE: mplife.cld --- USAGE: ./mplife.cld --- DESCRIPTION: Metapost output for Conway's Game of Life --- OPTIONS: --- --- REQUIREMENTS: --- --- BUGS: --- --- NOTES: --- --- AUTHOR: Philipp Gesang (Phg), --- COMPANY: --- VERSION: 1.0 --- CREATED: 06/08/10 12:28:35 CEST --- REVISION: --- --------------------------------------------------------------------------------- --- - -require "run" - -local C, Cs, Ct, P, R, S, match = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.match - -mplife = {} - -mplife.setup = mplife.setup or {} - -if context then - environment.loadluafile "mpliferc-global" - environment.loadluafile "mpliferc" -else -- assuming we're staying in pwd - require "mpliferc" -end - -mplife.setup.current = {} - - -do - local g, r, c = mplife.setup.global, mplife.setup.rc, mplife.setup.current - for key,_ in pairs(g) do - --print(key, ">>>", tostring(r[key]) .. " or " .. tostring(g[key])) - c[key] = r[key] or g[key] -- prefer local settings - end - mplife.setup.current = c -end - -mplife.format = { - - nl = "\n", space = " ", - - opar = "(", cpar = ")", - - hyphen = "-", comma = ",", - scolon = ";", path = "--", - - filldraw = "fill", -- "draw", - draw = "draw", - cycle = "cycle", - - p = function (x,y) - return string.format("(%s,%s)", x, y) - end, -} - -function mplife.runcode (mpcode) - --context.startMPcode() - context(mpcode) - --context.stopMPcode() - --context.MPdrawing(mpcode) -- comes with next beta! -end - -function mplife.draw_grid(grid, settings) - local h = gol.helpers - local c = mplife.setup.current - local pat = "" - if type(grid) == "string" then - grid = h.split(grid, "\n") -- may leave an empty string as last item - if grid[#grid] == "" then grid[#grid] = nil end - end - - local max = {} - max.x, max.y = grid[1]:len(), #grid - - local n = 0 - while grid[#grid-n] ~= nil do - - local row = grid[#grid-n] - local pos = 1 - - local cell = Cs(R("09") + P("D")) / function (char) - --repeat - local opacity = c.opacity - local p = { x = pos-1, y = n} - - local fill, fade_level = true - --fill = true - - if fill and c.fade then - fade_level = tonumber(char) - end - - if not fade_level then -- no number --> cell once dead (marked "D") - fade_level = 9.3 - end - - if fade_level ~= 0 then -- skip dead cells - if fade_level == 1 then - pat = pat .. string.format("%s %s shifted (%s,%s) withcolor transparent (1,%s,%s);\n", - "draw", c.gestalt, p.x, p.y, opacity*2, settings.color) - else - opacity = opacity - (fade_level * opacity * .1) - end - pat = pat .. string.format("%s %s scaled .9 shifted (%s+.05,%s+.05) withcolor transparent (1,%s,%s);\n", - "filldraw", c.gestalt, p.x, p.y, opacity, settings.color) - end - pos = pos + 1 - end - - local line = cell * ((1-cell) + cell)^0 - line:match(row) - pat = pat .. "\n" - n = n + 1 - end - - pat = pat .. string.format([[ -path border; -border = (0,0)--(%s,0)--(%s,%s)--(0,%s)--cycle; -setbounds currentpicture to boundingbox border ; -]], max.x, max.x, max.y, max.y) - ---fill border withcolor transparent (1,.75, white) ; ---fill border withcolor transparent (1,.3,1white) ; - --print("Pic\n", pat) - mplife.runcode(pat) - return true -end - ---- testing section - -function mplife.checker(n) - local squares = "" - local cnt = 0 - for y=1, n, 1 do - for x=1, n, 1 do - local fill - if cnt % 2 == 0 then fill = true end - local p = { x = x, y = y } - squares = squares .. mplife.p_square( p, fill ) - cnt = cnt + 1 - end - if n % 2 == 0 then cnt = cnt + 1 end -- needed for even column numbers - end - --print (squares) - return squares -end - -function mplife.rand_pattern(n, digits) - local pat = "" - for y=1, n, 1 do - for x=1, n, 1 do - pat = pat .. math.random(0,digits) - end - pat = pat .. "\n" - end - return pat -end - ---- interfacing with life.lua - -function mplife.life_frame (frame) - --local c = mplife.setup.current - - mplife.draw_grid(frame) - - return true -end - -function mplife.life_movie (frames, next_page) - local c = mplife.setup.current - for i, frame in ipairs(frames) do - context(c.before_frame) - mplife.life_frame(frame) - context(c.after_frame) - end -end - -function mplife.life_frames () - local c = mplife.setup.current - - - local frames = gol.frames( c.init, c.rule, c.frames, c.firstframe ) - mplife.life_movie( frames, false ) - return true -end - -function mplife.successive () - local c = mplife.setup.current - local settings = {} - if mplife.slides then - settings.color = "\\MPcolor{simpleslides:contrastcolor}" - else - context.definecolor({ "automaton:color" }, c.color) - settings.color = "\\MPcolor{automaton:color}" - end - context(c.before_frame) - mplife.draw_grid(c.last, settings) - context(c.after_frame) - mplife.setup.current.last = gol.next_frame( c.last, c.rule ) - return true -end - - -function mplife.main () - local c = mplife.setup.current - - if context then - context.definecolor({ "lifesquare" }, c.color) - end - --mplife.successive() - --context(c.preamble) -- only once - --context.starttext() - - --mplife.runcode (mplife.checker(20)) - - --mplife.draw_grid(mplife.rand_pattern(10,6)) - - --mplife.life_frames() - - --for i=1,10,1 do - --context("\\input knuth") - --context.page() - --end - --context.stoptext() - return 0 -end - - -if not mplife.slides then -- standalone - return mplife.main() -end diff --git a/mpliferc-global.lua b/mpliferc-global.lua deleted file mode 100644 index 3c735ed..0000000 --- a/mpliferc-global.lua +++ /dev/null @@ -1,59 +0,0 @@ --- --------------------------------------------------------------------------------- --- FILE: mpliferc-global.lua --- USAGE: with ConTeXt --- DESCRIPTION: default settings for the automaton module --- AUTHOR: Philipp Gesang (Phg), --- VERSION: 1.0 --- CREATED: 13/08/10 10:35:46 CEST --------------------------------------------------------------------------------- --- - -if not mplife then return 1 end - -mplife.setup.global = {} - -do - local c = {} - - c.file = "examples/sships.gol" - c.rule = gol.parse_rule("B3/S23") -- default Conway - c.init = gol.parse_file(c.file) - c.last = c.init -- for successive mode - - c.extendx = 0 - c.extendy = 0 - - c.pensize = .1 - c.color = { r = .6, g = .6, b = .8 } - c.opacity = 1/3 - c.fade = true - c.gestalt = "unitsquare" -- try "unitcircle" - - c.firstframe = 1 - c.frames = 5 - - c.preamble = [[ -\setupcolors[state=start] -\setupbackgrounds[state=start] -\setuppapersize[S6][S6] - -\setuppagenumbering[state=stop,location=] - -\defineoverlay[back][\ctxlua{mplife.successive()}] - -\setupbackgrounds [page] [background=back] -]] - c.before_frame = [[ -\startMPcode -pickup pencircle xyscaled (.25*]] .. c.pensize .. [[pt, ]] .. c.pensize .. [[pt) rotated 45; -]] - c.after_frame = [[ -currentpicture := currentpicture xysized (\the\paperwidth, \the\paperheight); -\stopMPcode -]] - - mplife.setup.global = c -end - -return mplife.setup.global diff --git a/mpliferc.lua b/mpliferc.lua deleted file mode 100644 index 518ed21..0000000 --- a/mpliferc.lua +++ /dev/null @@ -1,51 +0,0 @@ -if not mplife then return 1 end - -mplife.setup.rc = {} - -do - local c = {} - - --c.file = "examples/10x10_glider.gol" - --c.file = "examples/gliders.gol" - c.file = "examples/ggun.gol" - --c.file = "examples/sships.gol" - c.rule = gol.parse_rule("B3/S23") -- default Conway - c.init = gol.parse_file(c.file) - c.last = c.init -- for successive mode - - c.extendx = 0 - c.extendy = 0 - - c.pensize = .1 - c.color = { r = .6, g = .6, b = .8 } - c.opacity = 1/3 - c.fade = true - c.gestalt = "unitsquare" -- try "unitcircle" - - c.firstframe = 1 - c.frames = 5 - - c.preamble = [[ -\setupcolors[state=start] -\setupbackgrounds[state=start] -\setuppapersize[S6][S6] - -\setuppagenumbering[state=stop,location=] - -\defineoverlay[back][\ctxlua{mplife.successive()}] - -\setupbackgrounds [page] [background=back] -]] - c.before_frame = [[ -\startMPcode -pickup pencircle xyscaled (.25*]] .. c.pensize .. [[pt, ]] .. c.pensize .. [[pt) rotated 45; -]] - c.after_frame = [[ -currentpicture := currentpicture xysized (\the\paperwidth, \the\paperheight); -\stopMPcode -]] - - mplife.setup.rc = c -end - -return mplife.setup.rc diff --git a/run.lua b/run.lua index d8c18ad..357f350 100644 --- a/run.lua +++ b/run.lua @@ -31,12 +31,13 @@ end require "life" +local C, Cs, Ct, P, R, S, match = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.match + local help = gol.helpers -life = {} -life.debug = 1 +debug = 1 -function life.get_args () +function get_args () gol.arg = arg if gol.arg[-1] == "texlua" then gol.machine = gol.arg[-1] @@ -59,10 +60,9 @@ function life.get_args () return kv_args() end -function main () - local current = {} - current.kv_args = life.get_args() - current.file = current.kv_args.file or "10x10_glider.gol" +function life (current) + -- how many frames should we draw? + current.n = current.kv_args.n or 40 -- sustaining dead cells current.sustain = current.kv_args.sustain or 0 -- TODO @@ -70,9 +70,9 @@ function main () -- check for debug flag if tonumber(current.kv_args.debug) == 0 then - life.debug = false + debug = false else - life.debug = current.kv_args.debug or life.debug + debug = current.kv_args.debug or debug end @@ -83,8 +83,8 @@ function main () current.rule = gol.parse_rule ("B3/S23") -- Conway's rule end - if life.debug then for n, a in pairs(current.kv_args) do print(n, a) end end - if life.debug then for i, j in pairs(current.rule) do print(i, #j) end end + if debug then for n, a in pairs(current.kv_args) do print(n, a) end end + if debug then for i, j in pairs(current.rule) do print(i, #j) end end -- read the initial state (get an array of strings) if current.file then @@ -94,22 +94,50 @@ function main () end if current.init then - if life.debug then + if debug then gol.pre_frame(current.init) end - local many = gol.frames( current.init, current.rule, 40 ) + local many = gol.frames( current.init, current.rule, current.n ) gol.pre_movie (many, true) - --local lots = gol.frames( current.init, current.rule, 200 ) - --gol.pre_movie (lots, true) else io.write"\nCheck your input file for consistency, please.\n" return 1 end + return 0 +end - +function eca(current) + local eca = require "eca" + -- how many lines to draw + current.n = tonumber(current.kv_args.n) or 30 + current.aspect = tonumber(current.kv_args.aspect) or 3/4 + current.rule = eca.gen_rule(tonumber(current.kv_args.rule) or 110) + current.from = eca.parse_file(current.kv_args.file) + current.framesize = math.floor(current.aspect * current.from:len()) + + for n=1,current.n,1 do + gol.pre_section(current.from:len(), n) + eca.successive(current) + end return 0 end +function main () + local current = {} + current.kv_args = get_args() + current.file = current.kv_args.file or "10x10_glider.gol" + + local p_suf = P"." * (1-P".")^3 * -P(1) + local p_fn = (1-p_suf)^1 * C(p_suf) + local suffix = p_fn:match(current.file) or ".gol" -- assume .gol format as default + + if suffix == ".eca" then + return eca(current) + else + return life(current) + end +end + if not context then return main() end diff --git a/simpleslides-s-Automaton.tex b/simpleslides-s-Automaton.tex index c1e3181..1fb4e08 100644 --- a/simpleslides-s-Automaton.tex +++ b/simpleslides-s-Automaton.tex @@ -19,9 +19,9 @@ \startmodule[simpleslides-s-Automaton] -\setupmodule[file=,rule=,extendxy=] % using defaults from lua config +\setupmodule[mode=,file=,rule=,extendxy=] % using defaults from lua config -\ctxlua{environment.loadluafile( "mplife" )} +\ctxlua{environment.loadluafile( "automata" )} \ctxlua{mplife.slides = true} \unprotect @@ -94,7 +94,21 @@ \setupcolors[textcolor={simpleslides:textcolor}] -%D Set the initial Game of Life snapshot (from file) and the rule, if given. +%D Set the initial snapshot (from file) and the rule, if given. + +\doifsomethingelse{\moduleparameter{simpleslides}{mode}} +{\ctxlua{ +mplife.setup.current.mode = "\luaescapestring{\moduleparameter{simpleslides}{mode}}" +if mplife.setup.current.mode == "life" then + mplife.successive = mplife.gol_successive +else + environment.loadluafile("eca") + mplife.successive = mplife.eca_successive +end}} +{\ctxlua{mplife.successive = mplife.gol_successive}} + +%D The number of dead cells to add left and right / before and after +%D the initial frame. \doifsomething{\moduleparameter{simpleslides}{extendxy}}{\ctxlua {mplife.setup.current.extendx = tonumber("\luaescapestring{\moduleparameter{simpleslides}{extendxy}}") @@ -106,13 +120,27 @@ \doifsomething{\moduleparameter{simpleslides}{extendy}}{\ctxlua {mplife.setup.current.extendy = tonumber("\luaescapestring{\moduleparameter{simpleslides}{extendy}}") }} -\doifsomething{\moduleparameter{simpleslides}{file}}{\ctxlua - {mplife.setup.current.file = "\luaescapestring{\moduleparameter{simpleslides}{file}}" - mplife.setup.current.init = gol.parse_file(mplife.setup.current.file) - mplife.setup.current.last = mplife.setup.current.init }} - -\doifsomething{\moduleparameter{simpleslides}{rule}}{\ctxlua - {mplife.setup.current.rule = gol.parse_rule("\luaescapestring{\moduleparameter{simpleslides}{rule}}") }} +\doifsomething{\moduleparameter{simpleslides}{file}}{\ctxlua{ +mplife.setup.current.file = "\luaescapestring{\moduleparameter{simpleslides}{file}}" +}} + +\startluacode +if mplife.setup.current.mode == "life" then + mplife.setup.current.init = gol.parse_file(mplife.setup.current.file) + mplife.setup.current.last = mplife.setup.current.init +else + mplife.setup.current.init = eca.parse_file(mplife.setup.current.file) + mplife.setup.current.framesize = math.floor(mplife.setup.current.aspect * mplife.setup.current.init:len()) +end +\stopluacode + +\doifsomething{\moduleparameter{simpleslides}{rule}}{\ctxlua{ +if mplife.setup.current.mode == "life" then + mplife.setup.current.rule = gol.parse_rule("\luaescapestring{\moduleparameter{simpleslides}{rule}}") +else + mplife.setup.current.rule = eca.gen_rule(tonumber("\luaescapestring{\moduleparameter{simpleslides}{rule}}")) +end +}} %D We also use \METAPOST\ to draw the horizontal and vertical page backgrounds. %D Backgrounds will be of solid color, the ornament gets the transparency. -- cgit v1.2.3