欢迎来到《魔法使的约定》中文WIKI - 当前用户未登录
WIKI建设交流群:578085100;日服游戏交流群:821895698;中文服游戏交流群:790127155
全站通知:
模块:DailyOssm
刷
历
编
跳到导航
跳到搜索
此模块的文档可以在模块:DailyOssm/doc创建
local p = {}
-- 获取今天距 2019-12-16 的天数
local function get_days_since()
local today = os.date("*t")
local now = os.time{year=today.year, month=today.month, day=today.day}
local start = os.time{year=2019, month=12, day=16}
return math.floor((now - start) / 86400)
end
-- Note: 伪随机仍然会出现相隔不久但多次出现同一数值的情况,已弃用
-- 伪随机: 线性同余发生器 (LCG)
-- local function lcg(n, mod)
-- local a = 1664525
-- local c = 1013904223
-- local m = 2^32
-- return (a * n + c) % m % mod + 1
-- end
-- 使用乘法置换代替普通 LCG:若乘数 a 与模数 m 互质,则 f(x) = a·x mod m
-- 原理:当 $a$ 与模数 $m$ 互素时,映射 $f(x) = a \cdot x \bmod m$ 构成 $\mathbb{Z}_m$ 上的一个置换(全排列)。
-- 效果:对 [0, m−1] 构成一个全排列(即不重复地打乱所有值),用于更均匀分布遍历。
-- 如果感觉不爽了可以从这堆素数里换种子:907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499
local function permuted_index(n, total)
local a = 1283 -- 固定大素数,保证伪随机 + 遍历性
-- Note: 前提是我们认为total不会超过几百
return (a * n) % total + 1
end
-- 上述方法的测试; 在调试控制台运行=p.test_100_day_cycle()即可模拟
function p.test_100_day_cycle()
local total = 100
local a = 1009
local base = 2020 -- 从今天起的天数(当前真实n)
local seen = {}
local values = {}
for i = 0, total - 1 do
local n = base + i
local r = (a * n) % total + 1
values[i + 1] = r
seen[r] = true
end
-- 检查是否覆盖全部 1~100
local missing = {}
for i = 1, total do
if not seen[i] then
table.insert(missing, i)
end
end
mw.logObject(values)
if #missing == 0 then
mw.log('✅ 所有 1~100 的编号都被覆盖,分布完整')
else
mw.log('❌ 有遗漏的编号:')
mw.logObject(missing)
end
return '测试完成'
end
-- 获取分类下的页面数量
local function get_category_size(frame, cat)
local title = mw.title.makeTitle('Category', cat)
local pages = title:getContent() -- getContent 获取不到分类成员,只能走invoke
local count = mw.site.stats.pagesInCategory(cat, 'pages')
return count or 0
end
-- 主函数
function p.main(frame)
local n = get_days_since()
local a = get_category_size(frame, '料理') - 3
local b = get_category_size(frame, '活动料理') - 1
local c = get_category_size(frame, '生日料理') - 1
-- 向控制台输出分类数量
mw.log('分类数量:料理 = ' .. a .. ',活动料理 = ' .. b .. ',生日料理 = ' .. c)
a = a - b - c
local total = a + b
if total <= 0 then
return '<div>料理数据为空</div>'
end
local r = permuted_index(n, total)
local id
if r <= a then
id = 10000 + r
else
id = 20000 + r - a
end
local foodPage = 'Food_' .. id
local foodTitle = mw.title.new(foodPage)
if not foodTitle or not foodTitle.exists then
return string.format('<div class="bili-list-order">找不到推荐料理编号:%d</div>', id)
end
local content = foodTitle:getContent()
-- 提取两个字段
local name_zh = mw.ustring.match(content or '', '|%s*料理译名%s*=%s*([^\n|]+)')
local name_jp = mw.ustring.match(content or '', '|%s*料理名%s*=%s*([^\n|]+)')
-- 容错处理
name_zh = name_zh or ('料理 ' .. id)
name_jp = name_jp or name_zh -- 如果没有日文名就用译名代替
-- 构建 HTML 输出
local html = mw.html.create('div')
:addClass('bili-list-order')
:css('padding-bottom', '5px')
:tag('span')
:addClass('list-order-content')
:wikitext(string.format('今日推荐:%s', name_zh))
:done()
:wikitext(string.format(' [[文件:%s.png|30px|link=%s]]', name_jp, foodPage))
return string.format('今日推荐:%s', name_zh) .. string.format(' [[文件:%s.png|30px|link=%s]]', name_jp, foodPage);
end
return p

沪公网安备 31011002002714 号