Guest User

Untitled

a guest
Dec 13th, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.99 KB | None | 0 0
  1. maze = maze or {}
  2.  
  3. function newStack()
  4. local meta = {
  5. pop = function( s )
  6. s.size = s.size -1
  7. return s[s.size +1]
  8. end,
  9.  
  10. push = function( s, val )
  11. s.size = s.size +1
  12. s[s.size] = val
  13. end
  14. }
  15.  
  16. meta.__index = meta
  17.  
  18. local stack = { size = 0 }
  19. setmetatable( stack, meta )
  20.  
  21. return stack
  22. end
  23.  
  24. function fillArray( value, sizeY, sizeX )
  25. local res = {}
  26.  
  27. for y = 1, sizeY, 1 do
  28. res[y] = {}
  29.  
  30. for x = 1, sizeX, 1 do
  31. res[y][x] = value
  32. end
  33. end
  34.  
  35. return res
  36. end
  37.  
  38. local dirMod = {
  39. { 1, 0 }, {-1, 0 },
  40. { 0, 1 }, { 0,-1 }
  41. }
  42.  
  43. function maze.generate( sizeX, sizeY )
  44. local visits = fillArray( false, sizeY, sizeX )
  45. local v_walls = fillArray( true, sizeY, sizeX -1 )
  46. local h_walls = fillArray( true, sizeY -1, sizeX )
  47.  
  48. local x, y = 1, 1
  49. local cDir = 0
  50.  
  51. local tValid = false
  52. local tX, tY = 0, 0
  53.  
  54. local stack = newStack()
  55.  
  56. while( true ) do
  57. visits[y][x] = true
  58.  
  59. cDir = (cDir + math.random(3)) % 4 --Choose a random direction eatch time
  60.  
  61. -- Choose a valid direction to travel
  62. tValid = false
  63. for i = 1, 4, 1 do
  64. tX = x + dirMod[cDir +1][1]
  65. tY = y + dirMod[cDir +1][2]
  66.  
  67. if ( 0 < tX && 0 < tY && tX <= sizeX && tY <= sizeY ) then
  68. local isOpen = !visits[tY][tX]
  69.  
  70. if ( isOpen || math.random(8) == 1 ) then -- In rare cases, open already visited tiles, to avoid the 'perfect' maze
  71.  
  72. if ( cDir < 2 ) then
  73. v_walls[y][x - cDir %2] = false
  74. else
  75. h_walls[y - cDir % 2][x] = false
  76. end
  77.  
  78. if ( isOpen ) then -- Only push a tile one time
  79. stack:push( x )
  80. stack:push( y )
  81.  
  82. tValid = true
  83.  
  84. x = tX
  85. y = tY
  86.  
  87. break
  88. end
  89. end
  90. end
  91.  
  92. cDir = ( cDir +1 ) % 4
  93. end
  94.  
  95. if ( !tValid ) then -- Fully enclosed tile, nowhere to step, pop a new one from the stack
  96. if ( stack.size <= 0 ) then
  97. break
  98. else
  99. y = stack:pop()
  100. x = stack:pop()
  101. end
  102. end
  103. end
  104.  
  105. local maze = {
  106. sizeX = sizeX,
  107. sizeY = sizeY,
  108.  
  109. v_walls = v_walls,
  110. h_walls = h_walls
  111. }
  112.  
  113. return maze
  114. end
Add Comment
Please, Sign In to add comment