summaryrefslogtreecommitdiff
path: root/automata.lua
diff options
context:
space:
mode:
Diffstat (limited to 'automata.lua')
-rw-r--r--automata.lua253
1 files changed, 253 insertions, 0 deletions
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), <megas.kapaneus@gmail.com>
+-- 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