Module:Aichan:修订间差异

来自Arcaea中文维基
(大概不需要换行)
(lasteternity 已修复(已测试游戏本体行为))
 
(未显示2个用户的3个中间版本)
第1行: 第1行:
local getArgs = require('Module:Arguments').getArgs
local getArgs = require 'Module:Arguments'.getArgs
local songlist = mw.text.jsonDecode(mw.getCurrentFrame():expandTemplate{ title = 'Songlist.json' } ).songs
local mad = require 'Module:AnotherData'
local mad = require 'Module:AnotherData'
local p={}
local songlist = mad.listOf 'songs'
local randomizer={}
local p = {}


function initRandomizer(seed)
function initRandomizer(seed)
randomizer.x=seed
local x, y, z = seed, seed, seed
randomizer.y=seed
return function()
randomizer.z=seed
x, y, z = (171 * x) % 30269, (172 * y) % 30307, (170 * z) % 30323
return (x / 30269 + y / 30307 + z / 30323) % 1
end
end
 
function isAvailable(song)
return not song.deleted and song.id ~= 'lasteternity'
-- 禁用删除曲和 lasteternity (已经测试为游戏本体当前行为)
end
end


function getNext()
function isFree(song)
randomizer.x=(171*randomizer.x)%30269
return song.set=='base' or song.id=='innocence'
randomizer.y=(172*randomizer.y)%30307
randomizer.z=(170*randomizer.z)%30323
return ((randomizer.x/30269+randomizer.y/30307+randomizer.z/30323)%1)
end
end


第35行: 第38行:
--     优先级: time > date > 读取当前时间
--     优先级: time > date > 读取当前时间
--   delay: 在得到的时间基础上再往后若干天
--   delay: 在得到的时间基础上再往后若干天
--   建议用time={#timel函数}代替,例如:
--   time={{#timel:U|@1713172637+12hours}}
--   -- |time=1713172637
--   time={{#timel:U|2023-05-16+57days 12hours}}
--   -- |date=2023/05/16|delay=57
--   limit: 假设songlist只保留前limit项(用于模拟过去)
--   limit: 假设songlist只保留前limit项(用于模拟过去)
--   change: 显示“这一天的结果将在更新x首歌后变化”
local time = args['time'] or dateStringToTime(args['date']) or os.time()
local time = args['time'] or dateStringToTime(args['date']) or os.time()
time=time+86400*(args['delay'] or 0)
time=time+86400*(args['delay'] or 0)
local seed = math.floor((time-144e2)/864e2)
local rand = initRandomizer(math.floor((time-144e2)/864e2))
initRandomizer(seed)


local length=5000
local length=5000
第48行: 第55行:
end
end
for i=length-1,1,-1 do
for i=length-1,1,-1 do
local r=getNext()
local r=rand()
local swapPos=math.floor(r*i)
local swapPos=math.floor(r*i)
local temp=arr[i]
arr[i],arr[swapPos] = arr[swapPos],arr[i]
arr[i]=arr[swapPos]
arr[swapPos]=temp
end
end
第59行: 第64行:
local resultPaid={}
local resultPaid={}
local currentPaidCount=0
local currentPaidCount=0
local songSize=tonumber(args['limit']) or table.getn(songlist)
local songSize=tonumber(args['limit']) or #songlist
local next=length
local next=length
for i=0,length-1,1 do
for i=0,length-1,1 do
第66行: 第71行:
if value<songSize then
if value<songSize then
local info=songlist[value+1]
local info=songlist[value+1]
if info.set=='base' or info.id=='innocence' then
if isAvailable(info) then
if currentFreeCount<1 then
if isFree(info) then
currentFreeCount=currentFreeCount+1
if currentFreeCount<1 then
resultFree[currentFreeCount]=info
currentFreeCount=currentFreeCount+1
end
resultFree[currentFreeCount]=info
else
end
if currentPaidCount<2 then
else
currentPaidCount=currentPaidCount+1
if currentPaidCount<2 then
resultPaid[currentPaidCount]=info
currentPaidCount=currentPaidCount+1
resultPaid[currentPaidCount]=info
end
end
end
end
end
else
next=math.min(next,value)
end
end
end
end
第98行: 第103行:
end
end
text = text:wikitext(frame:expandTemplate {title = '组排列-end'}):done()
text = text:wikitext(frame:expandTemplate {title = '组排列-end'}):done()
if args['change'] then
if next==length then
text=text:wikitext('这一天的结果不再会随更新变化')
else
text=text:wikitext(string.format('这一天的结果将在更新%d首歌后变化',next-songSize+1))
end
end


return text
return text

2024年10月11日 (五) 15:15的最新版本

可在Module:Aichan/doc创建此模块的帮助文档

local getArgs = require 'Module:Arguments'.getArgs
local mad = require 'Module:AnotherData'
local songlist = mad.listOf 'songs'
local p = {}

function initRandomizer(seed)
	local x, y, z = seed, seed, seed
	return function()
		x, y, z = (171 * x) % 30269, (172 * y) % 30307, (170 * z) % 30323
		return (x / 30269 + y / 30307 + z / 30323) % 1
	end
end

function isAvailable(song)
	return not song.deleted and song.id ~= 'lasteternity'
	-- 禁用删除曲和 lasteternity (已经测试为游戏本体当前行为)
end

function isFree(song)
	return song.set=='base' or song.id=='innocence'
end

function dateStringToTime(date)
	if date==nil then return nil end
	local y,m,d = string.match(date, "([^/]+)/([^/]+)/([^/]+)")
	return os.time({year=y,month=m,day=d,hour=12,min=30});
end

function p.main(frame)
    local args = getArgs(frame)
    return p._main(args)
end

function p._main(args)
	-- args:
	--     time: unix时间戳
	--     date: YYYY/MM/DD格式的时间, 按这一天的北京时间12:30算
	--         优先级: time > date > 读取当前时间
	--     delay: 在得到的时间基础上再往后若干天
	--     建议用time={#timel函数}代替,例如:
	--     time={{#timel:U|@1713172637+12hours}}
	--     -- |time=1713172637
	--     time={{#timel:U|2023-05-16+57days 12hours}}
	--     -- |date=2023/05/16|delay=57

	--     limit: 假设songlist只保留前limit项(用于模拟过去)
	local time = args['time'] or dateStringToTime(args['date']) or os.time()
	time=time+86400*(args['delay'] or 0)
	local rand = initRandomizer(math.floor((time-144e2)/864e2))

	local length=5000
	local arr={}
	for i=0,length-1,1 do
		arr[i]=i
	end
	for i=length-1,1,-1 do
		local r=rand()
		local swapPos=math.floor(r*i)
		arr[i],arr[swapPos] = arr[swapPos],arr[i]
	end
	
	local resultFree={}
	local currentFreeCount=0
	local resultPaid={}
	local currentPaidCount=0
	local songSize=tonumber(args['limit']) or #songlist
	local next=length
	for i=0,length-1,1 do
		if currentFreeCount+currentPaidCount>=3 then break end
		local value=arr[i]
		if value<songSize then
			local info=songlist[value+1]
			if isAvailable(info) then
				if isFree(info) then
					if currentFreeCount<1 then
						currentFreeCount=currentFreeCount+1
						resultFree[currentFreeCount]=info
					end
				else
					if currentPaidCount<2 then
						currentPaidCount=currentPaidCount+1
						resultPaid[currentPaidCount]=info
					end
				end
			end
		end
	end
	local result
	if resultPaid[1].date<resultPaid[2].date then
		result={resultFree[1],resultPaid[1],resultPaid[2]}
	else
		result={resultFree[1],resultPaid[2],resultPaid[1]}
	end

	local frame = mw.getCurrentFrame()
	local text = mw.html.create 'div'
	text=text:wikitext(frame:expandTemplate {title = '组排列', args = {height = 'auto'}})
	for i=1,3,1 do
		local id=result[i].id
		local title=result[i].title_localized.en
		local link=mad.linkName(result[i]) or title
		text:wikitext(frame:expandTemplate {title = '组排单元', args = {title,id,link=link}})
	end
	text = text:wikitext(frame:expandTemplate {title = '组排列-end'}):done()

	return text
end

return p