模組:沙盒/WhitePhosphorus/randiv
local p = {}
local vacant = {}
local t_width, t_height
local step = 5
local function init(frame)
t_height, t_width = frame["height"] or 600, frame["width"] or 800
t_height, t_width = t_height / step, t_width / step
for i = 1, t_height do
vacant[i] = {}
for j = 1, t_width do
vacant[i][j] = 1
end
end
end
local function largest_block()
local tmp = {vacant[1]}
table.insert(tmp[1], 0)
for i = 2, t_height do
tmp[i] = vacant[i]
for j = 1, t_width do
tmp[i][j] = tmp[i][j] ~= 0 and tmp[i-1][j] + 1 or 0
end
table.insert(tmp[i], 0)
end
local max_area, max_top, max_left, max_height, max_width = 0
for i = 1, t_height do
local stack = {}
for j = 1, t_width+1 do
while next(stack) ~= nil and tmp[i][ stack[#stack] ] > tmp[i][j] do
local s_top = table.remove(stack)
local left = next(stack) == nil and 1 or stack[#stack]+1
local area = (j - left) * tmp[i][s_top]
if area > max_area then
max_area, max_top, max_left, max_height, max_width =
area, i-tmp[i][s_top], left-1, tmp[i][s_top], j-left
end
end
table.insert(stack, j)
end
end
return max_top, max_left, max_height, max_width
end
local function random_block()
max_top, max_left, max_height, max_width = largest_block()
left, top = math.random(0, max_width-1), math.random(0, max_height-1)
width, height = math.random(1, max_width-left), math.random(1, max_height-top)
left, top = left + max_left, top + max_top
for i = top+1, top+height do
for j = left+1, left+width do
vacant[i][j] = 0
end
end
return top * step, left * step, height * step, width * step
end
local function gen_html(id, content, top, left, height, width)
local hidden = mw.html.create('div')
:attr('id', 'mw-customcollapsible-' .. id)
:addClass('mw-collapsible mw-collapsed')
:css({['position'] = 'absolute',
['background-color'] = 'rgba(255,255,255,.8)',
['left'] = '0px', ['top'] = '0px',
['padding'] = '0 10px',
['width'] = t_width * step .. 'px',
['height'] = t_height * step .. 'px',
['z-index'] = '999', ['text-align'] = 'left',
['display'] = 'none', ['overflow'] = 'scroll'})
:node(mw.html.create('span')
:addClass('mw-customtoggle-' .. id)
:css('cursor', 'pointer')
:wikitext("'''×'''\n")
:node(content)
:done())
:done()
local block = mw.html.create('div')
:css({['position'] = 'absolute',
['left'] = left .. 'px', ['top'] = top .. 'px',
['width'] = width .. 'px', ['height'] = height .. 'px'})
:addClass('mw-customtoggle-' .. id)
:done()
return tostring(hidden) .. tostring(block)
end
function p.main(frame)
math.randomseed(os.time())
init(frame)
html_t = {}
for k, v in ipairs(frame.args) do
top, left, height, width = random_block()
table.insert(html_t, gen_html(k, v, top, left, height, width))
end
return table.concat(html_t)
end
return p