Module:Sokoban

From The Wiki Camp 2
Jump to navigation Jump to search

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