I've adapted the following code to make mazes in LuaLaTeX and ConTeXt:
https://www.rosettacode.org/wiki/Maze_generation#Lua

I defined a modified version to make content visible to TeX and I saved in
a file named maze.lua:

function make_maze_tex(w, h, m)
  w = w or 16
  h = h or 8

  local map = initialize_grid(w*2+1, h*2+1)

  function walk(x, y)
    map[y][x] = false

    local d = { 1, 2, 3, 4 }
    shuffle(d)
    for i, dirnum in ipairs(d) do
      local xx = x + dirs[dirnum].x
      local yy = y + dirs[dirnum].y
      if map[yy] and map[yy][xx] then
        map[avg(y, yy)][avg(x, xx)] = false
        walk(xx, yy)
      end
    end
  end

  walk(math.random(1, w)*2, math.random(1, h)*2)

 tex.print([[\bgroup]])
 tex.print([[\baselineskip ]]..m)
  local s = {}
  for i = 1, h*2+1 do
    --table.insert(s, [[\hbox{]])
    tex.print([[\hbox{]])
    for j = 1, w*2+1 do
     -- table.insert(s, [[\hbox{]])
      if (j == 1 and i == 2) or (j == 2*w + 1 and i == 2*h) then
        tex.print([[\hskip ]]..m)
      elseif map[i][j] then
        --table.insert(s, [[\vrule width ]]..m..[[ height ]]..m)
        tex.print([[\vrule width ]]..m..[[ height ]]..m)
      else
        --table.insert(s, [[\hskip ]]..m)
        tex.print([[\hskip ]]..m)
      end
    --  table.insert(s, [[}]].."\n")
    end
    --table.insert(s, [[}]])
  tex.print([[}]])
  end
 --tex.print(table.concat(s))
 tex.print([[\egroup]])
end

And I executed the folowing in LuaLaTeX and ConTeXt:

%\documentclass{article}
%\usepackage{luacode}
%\begin{document}
\starttext
%\begin{luacode*}
\startluacode
mz = dofile("maze.lua")
local count = 0
for i=10,109 do
count = count + 1
tex.print([[\subject{Laberinto ]]..count..[[}]])
mz.make_maze_tex(i, i, [[\dimexpr\textwidth/]]..(2*i+1)..[[\relax]])
tex.print([[\pagebreak]])
end
%\end{luacode*}
\stopluacode
%\end{document}
\stoptext

Whereas it works very fast in LuaLaTeX it crashes on ConTeXt and outputs
the following:

token call, execute:
...ext/tex/texmf-context/tex/context/base/mkiv/supp-ran.lua:30: C stack
overflow


Why does it happen? I guess it has something to do with math.randomseed,
but I don't know how to avoid this error message.
local mazegen = {}

math.randomseed( os.time() )
 
-- Fisher-Yates shuffle from http://santos.nfshost.com/shuffling.html
local function shuffle(t)
  for i = 1, #t - 1 do
    local r = math.random(i, #t)
    t[i], t[r] = t[r], t[i]
  end
end

mazegen.shuffle = shuffle 
-- builds a width-by-height grid of trues
local function initialize_grid(w, h)
  local a = {}
  for i = 1, h do
    table.insert(a, {})
    for j = 1, w do
      table.insert(a[i], true)
    end
  end
  return a
end
 
mazegen.initialize_grid = initialize_grid
-- average of a and b
local function avg(a, b)
  return (a + b) / 2
end
 
 
local dirs = {
  {x = 0, y = -2}, -- north
  {x = 2, y = 0}, -- east
  {x = -2, y = 0}, -- west
  {x = 0, y = 2}, -- south
}
 
local function make_maze(w, h)
  w = w or 16
  h = h or 8
 
  local map = initialize_grid(w*2+1, h*2+1)
 
  function walk(x, y)
    map[y][x] = false
 
    local d = { 1, 2, 3, 4 }
    shuffle(d)
    for i, dirnum in ipairs(d) do
      local xx = x + dirs[dirnum].x
      local yy = y + dirs[dirnum].y
      if map[yy] and map[yy][xx] then
        map[avg(y, yy)][avg(x, xx)] = false
        walk(xx, yy)
      end
    end
  end
 
  walk(math.random(1, w)*2, math.random(1, h)*2)
 
  local s = {}
  for i = 1, h*2+1 do
    for j = 1, w*2+1 do
      if map[i][j] then
        table.insert(s, '#')
      else
        table.insert(s, ' ')
      end
    end
    table.insert(s, '\n')
  end
  return table.concat(s)
end

mazegen.make_maze = make_maze

function make_maze_tex(w, h, m)
  w = w or 16
  h = h or 8
 
  local map = initialize_grid(w*2+1, h*2+1)
 
  function walk(x, y)
    map[y][x] = false
 
    local d = { 1, 2, 3, 4 }
    shuffle(d)
    for i, dirnum in ipairs(d) do
      local xx = x + dirs[dirnum].x
      local yy = y + dirs[dirnum].y
      if map[yy] and map[yy][xx] then
        map[avg(y, yy)][avg(x, xx)] = false
        walk(xx, yy)
      end
    end
  end
 
  walk(math.random(1, w)*2, math.random(1, h)*2)
 
 tex.print([[\bgroup]])
 tex.print([[\baselineskip ]]..m)
  local s = {}
  for i = 1, h*2+1 do
    --table.insert(s, [[\hbox{]])
    tex.print([[\hbox{]])
    for j = 1, w*2+1 do
     -- table.insert(s, [[\hbox{]])
      if (j == 1 and i == 2) or (j == 2*w + 1 and i == 2*h) then 
        tex.print([[\hskip ]]..m)
      elseif map[i][j] then
        --table.insert(s, [[\vrule width ]]..m..[[ height ]]..m)
        tex.print([[\vrule width ]]..m..[[ height ]]..m)
      else
        --table.insert(s, [[\hskip ]]..m)
        tex.print([[\hskip ]]..m)
      end
    --  table.insert(s, [[}]].."\n")
    end
    --table.insert(s, [[}]])
  tex.print([[}]])
  end
 --tex.print(table.concat(s))
 tex.print([[\egroup]])
end

mazegen.make_maze_tex = make_maze_tex

return mazegen
 
\starttext
\startluacode
mz = dofile("maze.lua")
local count = 0
for i=10,109 do
count = count + 1
tex.print([[\subject{Laberinto ]]..count..[[}]])
mz.make_maze_tex(i, i, [[\dimexpr\textwidth/]]..(2*i+1)..[[\relax]])
tex.print([[\pagebreak]])
end 
\stopluacode  
\stoptext 
___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the 
Wiki!

maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
webpage  : http://www.pragma-ade.nl / http://context.aanhet.net
archive  : https://bitbucket.org/phg/context-mirror/commits/
wiki     : http://contextgarden.net
___________________________________________________________________________________

Reply via email to