local ruleset = {
  {2},
  {1,3},
  {2}
}

local offsets = {
  up = function(grid, cell)
    local x,y = cell.coordinates[1],cell.coordinates[2]
    return grid[x][y-1]
  end,
  down = function(grid, cell)
    local x,y = cell.coordinates[1],cell.coordinates[2]
    return grid[x][y+1]
  end,
  left = function(grid, cell)
    local x,y = cell.coordinates[1],cell.coordinates[2]
    if not grid[x-1] then return end
    return grid[x-1][y]
  end,
  right = function(grid, cell)
    local x,y = cell.coordinates[1],cell.coordinates[2]
    if not grid[x+1] then return end
    return grid[x+1][y]
  end,
}

function getAllModules()
  local modules = {}
  
  for i = 1,#ruleset do
    table.insert(modules, i)
  end
  
  return modules
end

function getNeighbours(grid, cell)
  local neighbours = {}
  
  for _,method in pairs(offsets) do
    local neighbour = method(grid, cell)
    
    if #neighbour.modules > 1 then
      table.insert(neighbours, neighbour)
    end
  end
  
  return neighbours
end

function getAvailableCells(grid)
  local cells = {}
  for i = 1,#grid do
    for j = 1,#grid[1] do
      local cell = grid[i][j]
      
      if #cell.modules == 1 then
        local neighbours = getNeighbours(grid, cell)
        
        if #neighbours > 0 then
          cells[cell] = neighbours
        end
      end
    end
  end
  
  return cells
end

function createGrid(height, width)
  local grid = {}
  for i = 1,height do
    grid[i] = {}
    
    for j = 1,width do
      grid[i][j] = {modules = getAllModules(), coordinates = {i,j}}
    end
  end
  
  return grid
end

function visalizeGrid(grid)
  for i = 1,#grid do
    for j = 1,#grid[1] do
      local cell = grid[i][j]
      
      print(#cell.modules)
    end
  end
end

function findCommonElements(table1, table2)
    local commonElements = {}

    for _, value1 in ipairs(table1) do
        for _, value2 in ipairs(table2) do
            if value1 == value2 then
                table.insert(commonElements, value1)
                break  -- Break out of the inner loop once a common element is found
            end
        end
    end

    return commonElements
end

function getLowestEntropy(cells)
  local lowestEntropy, bestCell = #getAllModules(), nil
  for _,cell in pairs(cells) do
    local domain = #cells.modules
    if domain < lowestEntropy then
      lowestEntropy, bestCell = domain, cell
    end
  end
  
  return bestCell
end

function collapseCells(grid, cells, modules)
  for _,cell in pairs(cells) do
    local options = findCommonElements(cell.modules, modules)
    
    cell.modules = options
  end
end

function getRandomModule(modules)
  local index = math.random(1, #modules)
  
  return modules[index]
end

function waveCollapse(grid)
  local cells = getAvailableCells(grid)
  
  if #cells == 0 then
    print("Collapse completed")
    return
  end
  
  for cell,neighbours in pairs(cells) do
    collapseCells(grid, neighbours, cell.modules)
  end
  
  local neighbours = cells[1]
  
  local bestCell = getLowestEntropy(neighbours)
  
  bestCell.modules = {getRandomModule()}
end

function start(height, width)
  local grid = createGrid(height, width)
  
  grid[5][5].modules = {1}
  
  repeat
    waveCollapse(grid)
  until #getAvailableCells(grid) == 0
  
  visalizeGrid(grid)
end

start(9,9) 

Lua online compiler

Write, Run & Share Lua code online using OneCompiler's Lua online compiler for free. It's one of the robust, feature-rich online compilers for Lua language, running the latest Lua version 5.4. Getting started with the OneCompiler's Lua editor is easy and fast. The editor shows sample boilerplate code when you choose language as Lua and start coding.

Taking inputs (stdin)

OneCompiler's Lua online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Lua program which takes name as input and prints hello message with your name.

name = io.read("*a")
print ("Hello ", name)

About Lua

Lua is a light weight embeddable scripting language which is built on top of C. It is used in almost all kind of applications like games, web applications, mobile applications, image processing etc. It's a very powerful, fast, easy to learn, open-source scripting language.

Syntax help

Variables

  • By default all the variables declared are global variables
  • If the variables are explicitly mentioned as local then they are local variables.
  • Lua is a dynamically typed language and hence only the values will have types not the variables.

Examples

-- global variables
a = 10

-- local variables

local x = 30
Value TypeDescription
numberRepresents numbers
stringRepresents text
nilDifferentiates values whether it has data or not
booleanValue can be either true or false
functionRepresents a sub-routine
userdataRepresents arbitary C data
threadRepresents independent threads of execution.
tableCan hold any value except nil

Loops

1. While:

While is also used to iterate a set of statements based on a condition. Usually while is preferred when number of iterations are not known in advance.

while(condition)
do
--code
end

2. Repeat-Until:

Repeat-Until is also used to iterate a set of statements based on a condition. It is very similar to Do-While, it is mostly used when you need to execute the statements atleast once.

repeat
   --code
until( condition )

3. For:

For loop is used to iterate a set of statements based on a condition.

for init,max/min value, increment
do
   --code
end

Functions

Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increase re-usuability and modularity.

optional_function_scope function function_name( argument1, argument2, argument3........, argumentn)
--code
return params with comma seperated
end