Module:Sokoban
Documentation for this module may be created at Module:Sokoban/doc
local p = {}
local getArgs = require('Module:Arguments').getArgs
function p.make_board_css( frame )
local args = getArgs(frame)
local w = tonumber(args[1])
local h = tonumber(args[2])
local board = args[3]
-- read board data
local objects = p.get_objects(w,h,board)
local walls = objects.walls
local boxes = objects.boxes
local strOut = ''
-- create css
for x = 1, w do strOut = strOut .. p.get_multitarget_css('h' .. (x-1)) end
for y = 1, h do strOut = strOut .. p.get_multitarget_css('v' .. (y-1)) end
for i = 1, #boxes do
for x = 1, w do strOut = strOut .. p.get_multitarget_css('b' .. (i-1) .. 'h' .. (x-1)) end
for y = 1, h do strOut = strOut .. p.get_multitarget_css('b' .. (i-1) .. 'v' .. (y-1)) end
end
return strOut
end
function p.make_board( frame )
local args = getArgs(frame)
local w = tonumber(args[1])
local h = tonumber(args[2])
local board = args[3]
-- read board data
local objects = p.get_objects(w,h,board)
local walls = objects.walls
local boxes = objects.boxes
local ends = objects.ends
local player = objects.player
-- create html
local strOut = ''
-- multitarget html
for x = 1, w do strOut = strOut .. p.get_multitarget_html('h' .. (x-1), x < w - player.x) end
for y = 1, h do strOut = strOut .. p.get_multitarget_html('v' .. (y-1), y < h - player.y) end
for i = 1, #boxes do
for x = 1, w do strOut = strOut .. p.get_multitarget_html('b' .. (i-1) .. 'h' .. (x-1), x < w - boxes[i].x) end
for y = 1, h do strOut = strOut .. p.get_multitarget_html('b' .. (i-1) .. 'v' .. (y-1), y < h - boxes[i].y) end
end
-- player
strOut = strOut .. '<div id=game><div id=board><div class=spacer-col>'
for y = 1, h-1 do strOut = strOut .. '<div class="spacer mw-customcollapsible-v' .. (y - 1) .. '"></div>' end
strOut = strOut .. '<div class=spacer-row>'
for x = 1, w-1 do strOut = strOut .. '<div class="spacer mw-customcollapsible-h' .. (x - 1) .. '"></div>' end
strOut = strOut .. '<div id=player></div></div></div>'
-- boxes
for i = 1, #boxes do
strOut = strOut .. '<div class=spacer-col>'
for y = 1, h-1 do strOut = strOut .. '<div class="spacer mw-customcollapsible-b' .. (i - 1) .. 'v' .. (y - 1) .. '"></div>' end
strOut = strOut .. '<div class=spacer-row>'
for x = 1, w-1 do strOut = strOut .. '<div class="spacer mw-customcollapsible-b' .. (i - 1) .. 'h' .. (x - 1) .. '"></div>' end
strOut = strOut .. '<div class=box></div></div></div>'
end
-- walls
for i = 1, #walls do strOut = strOut .. '<div style="--x:' .. walls[i].x .. ';--y:' .. walls[i].y .. '" class=wall></div>' end
-- ends
for i = 1, #ends do strOut = strOut .. '<div style="--x:' .. ends[i].x .. ';--y:' .. ends[i].y .. '" class="wall end"></div>' end
strOut = strOut .. '</div>'
-- dpad
strOut = strOut .. '<div id=dpad><div id="visual-dpad"><div style="--x:1;--y:0">⬆️</div><div style="--x:1;--y:2">⬇️</div><div style="--x:0;--y:1">⬅️</div><div style="--x:2;--y:1">➡️</div></div><div class="move-h">'
for x = 1, w-1 do strOut = strOut .. '<div class="spacer wide mw-customcollapsible-h' .. (x - 1) .. '"></div>' end
for x = 1, w-1 do strOut = strOut .. '<div class="key wide"><div class="key mw-customtoggle-h' .. (x - 1) .. '"></div></div>' end
strOut = strOut .. '</div><div class="move-v">'
for y = 1, h-1 do strOut = strOut .. '<div class="spacer tall mw-customcollapsible-v' .. (y - 1) .. '"></div>' end
for y = 1, h-1 do strOut = strOut .. '<div class="key tall"><div class="key mw-customtoggle-v' .. (y - 1) .. '"></div></div>' end
-- dapd wall spacers
strOut = strOut .. '</div><div class=zerozero><div class=wall-move-h>'
for x = 1, w-1 do strOut = strOut .. '<div class="spacer wide mw-customcollapsible-h' .. (x - 1) .. '"></div>' end
strOut = strOut .. '<div class=relative><div class=wall-move-v>'
for y = 1, h-1 do strOut = strOut .. '<div class="spacer tall mw-customcollapsible-v' .. (y - 1) .. '"></div>' end
strOut = strOut .. '<div class=relative>'
-- dapd walls
for i = 1, #walls do strOut = strOut .. '<div style="--x:' .. walls[i].x .. ';--y:' .. walls[i].y .. '" class=wall></div>' end
-- boxes
for i = 1, #boxes do
strOut = strOut .. '<div class=spacer-col-0w>'
for y = 1, h-1 do strOut = strOut .. '<div class="spacer tall mw-customcollapsible-b' .. (i - 1) .. 'v' .. (y - 1) .. '"></div>' end
strOut = strOut .. '<div class=spacer-row>'
for x = 1, w-1 do strOut = strOut .. '<div class="spacer wide mw-customcollapsible-b' .. (i - 1) .. 'h' .. (x - 1) .. '"></div>' end
-- box dpad
strOut = strOut .. '<div class=box><div class=box-move-h>'
for x = 1, w-1 do strOut = strOut .. '<div class="spacer wide mw-customcollapsible-b' .. (i - 1) .. 'h' .. (x - 1) .. '"></div>' end
for x = 1, w-1 do
strOut = strOut .. '<div class="key wide box-key">'
if x < w-1 and x > 1 then strOut = strOut .. '<div class="key mw-customtoggle-b' .. (i - 1) .. 'h' .. (x - 1) .. ' mw-customtoggle-h' .. (x - 2) .. ' mw-customcollapsible-b' .. (i - 1) .. 'h' .. (x - 1) .. '"></div>' end
strOut = strOut .. '<div class="key mw-customtoggle-b' .. (i - 1) .. 'h' .. (x - 1) .. ' mw-customtoggle-h' .. ((x == w-1) and (x - 2) or x) .. '"></div></div>'
end
strOut = strOut .. '</div><div class=box-move-v>'
for y = 1, h-1 do strOut = strOut .. '<div class="spacer tall mw-customcollapsible-b' .. (i - 1) .. 'v' .. (y - 1) .. '"></div>' end
for y = 1, h-1 do
strOut = strOut .. '<div class="key tall box-key">'
if y < h-1 and y > 1 then strOut = strOut .. '<div class="key mw-customtoggle-b' .. (i - 1) .. 'v' .. (y - 1) .. ' mw-customtoggle-v' .. (y - 2) .. ' mw-customcollapsible-b' .. (i - 1) .. 'v' .. (y - 1) .. '"></div>' end
strOut = strOut .. '<div class="key mw-customtoggle-b' .. (i - 1) .. 'v' .. (y - 1) .. ' mw-customtoggle-v' .. ((y == h-1) and (y - 2) or y) .. '"></div></div>'
end
-- box dapd wall spacers
strOut = strOut .. '</div><div class=zerozero><div class=box-wall-move-h>'
for x = 1, w-1 do strOut = strOut .. '<div class="spacer wide mw-customcollapsible-b' .. (i - 1) .. 'h' .. (x - 1) .. '"></div>' end
strOut = strOut .. '<div class=relative><div class=box-wall-move-v>'
for y = 1, h-1 do strOut = strOut .. '<div class="spacer tall mw-customcollapsible-b' .. (i - 1) .. 'v' .. (y - 1) .. '"></div>' end
strOut = strOut .. '<div class=relative>'
-- box dapd walls
for i = 1, #walls do strOut = strOut .. '<div style="--x:' .. walls[i].x .. ';--y:' .. walls[i].y .. '" class=wall></div>' end
-- box dapd boxes
for j = 1, #boxes do
if j ~= i then
strOut = strOut .. '<div class=spacer-col-r-0w>'
for y = 1, h-1 do strOut = strOut .. '<div class="spacer tall mw-customcollapsible-b' .. (j - 1) .. 'v' .. (y - 1) .. '"></div>' end
strOut = strOut .. '<div class=spacer-row-r>'
for x = 1, w-1 do strOut = strOut .. '<div class="spacer wide mw-customcollapsible-b' .. (j - 1) .. 'h' .. (x - 1) .. '"></div>' end
strOut = strOut .. '<div class=box></div></div></div>'
end
end
strOut = strOut .. '</div></div></div></div></div></div></div></div>'
end
strOut = strOut .. '</div></div></div></div></div></div></div>'
return strOut
end
function p.get_objects( w, h, board )
local walls = {}
local boxes = {}
local ends = {}
local player = {}
local i = 0
for c in board:gmatch"." do
local x = i % w
local y = math.floor(i / w)
if c == '/' then
-- wall
table.insert(walls, {x=x,y=y})
elseif c == 'x' then
-- box
table.insert(boxes, {x=x,y=y})
elseif c == '*' then
-- ends
table.insert(ends, {x=x,y=y})
elseif c == 'u' then
player = {x=x,y=y}
end
if c ~= '\n' then
i = i + 1
end
end
return { walls=walls, boxes=boxes, ends=ends, player=player }
end
function p.get_multitarget_css( id )
return '#mw-customcollapsible-' .. id .. '.mw-collapsed ~ * .mw-customcollapsible-' .. id .. ',#mw-customcollapsible-' .. id .. '.mw-collapsed ~ .mw-customcollapsible-' .. id .. '{display:none;} '
end
function p.get_multitarget_html( id, collapsed )
return '<div class="mw-collapsible ' .. (collapsed and 'mw-collapsed' or '') .. '" id="mw-customcollapsible-' .. id .. '"></div>'
end
return p