မေႃႇၵျူး:games/data
Appearance
Documentation for this module may be created at မေႃႇၵျူး:games/data/doc
local fun = require "Module:fun"
local function matches_to_array(text, pattern)
if not text then
return nil
end
local t = {}
local i = 0
for match in text:gmatch(pattern) do
i = i + 1
t[i] = match
end
return t
end
local function split(text, char)
if not text then
return nil
end
if #char ~= 1 then
error(char .. " is not a single character.")
end
return matches_to_array(text, "[^" .. char .. "]+")
end
local function grab_games(page)
local games = {}
local i = 0
local j, _, equals
repeat
i = i + 1
_, j, equals, games[i] = page:find("(===*)%s*Game " .. i .. "[^=]*%s*%1\n(.-)\n*==", j)
if not j then -- match to end of page
_, j, equals, games[i] = page:find("(===*)%s*Game " .. i .. "[^=]*%s*%1(.+)\n*$", j)
end
if j then
j = j - #equals - 1
end
until not j
if not games[1] then
error("No games found!")
end
return games
end
local days_in_month = {
January = 31, February = 28, March = 31, April = 30, May = 31, June = 30,
July = 31, August = 31, September = 30, October = 31, November = 30, December = 31,
}
local months = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December",
}
local function month_and_day_to_day_in_year(month, day)
local day_in_year = 0
for _, month_name in ipairs(months) do
if month_name == month then
break
end
day_in_year = day_in_year + days_in_month[month_name]
end
return day_in_year + day
end
local memo = {}
setmetatable(
memo,
{
__index = function(self, key)
local val = {}
self[key] = val
return val
end
})
-- Memoize.
local function get_day_in_year(month, day)
local day_in_year = memo[month][day]
if not day_in_year then
day_in_year = month_and_day_to_day_in_year(month, day)
memo[month][day] = day_in_year
end
return day_in_year
end
-- Change this if game goes into January.
local minutes_in_day = 24 * 60
local start_date = get_day_in_year("December", 1)
local function get_time_in_days(date)
local hour, minute, day, month, last_two_of_year =
date:match("(%d%d):(%d%d), (%d+) (%a+) %d%d(%d%d)")
return 365 * (tonumber(last_two_of_year) - 17)
+ get_day_in_year(month, tonumber(day)) - start_date
+ tonumber(hour) / 24
+ tonumber(minute) / minutes_in_day
end
local function round(decimals)
local power = 10 ^ decimals
return function(number)
return math.floor(number * power) / power
end
end
local round4 = round(4)
local function get_day_difference(date1, date2)
return round4(math.abs(get_time_in_days(date1) - get_time_in_days(date2)))
end
local function parse_games(games)
local parsed_games = {}
local function word_param_filter(word)
return not word:find("^lang%d*=") and not word:find("^tr%d*=")
end
for i, game in ipairs(games) do
local parsed_game = {}
parsed_games[i] = parsed_game
local j = 0
local to_be_ignored, prev_date
for game_entry, first_character in game:gmatch("\n%*%s+(([%[{])[^\n]+)") do
local interposing_words
if first_character == "{" then
if game_entry:find("ignore rules=", 1, true) then
to_be_ignored = true
else
interposing_words = split(game_entry:match("{{game entry|([^}]+)}}"), "|")
-- Remove |lang=, |langN=, |tr=, |trN=.
interposing_words = fun.filter(
word_param_filter,
interposing_words)
end
else
local wordlist = game_entry:match("%b[]%s+%b()%s+%b[]")
if wordlist:find("{{", 1, true) then
local words_by_position = {}
local _, endpos, word
-- Grab any words in a link template.
while true do
_, endpos, word = wordlist:find("{{[lm]|[^|]+|([^|]+)[^}]*}", endpos)
if not endpos then break end
words_by_position[endpos] = word
end
-- Grab bare links.
endpos = 1
while true do
_, endpos, word = wordlist:find("%[%[([^%]]+)%]%]", endpos)
if not endpos then break end
words_by_position[endpos] = word
end
interposing_words = require("Module:table").compressSparseArray(words_by_position)
else
-- Grab bare links.
interposing_words = matches_to_array(wordlist, "%[%[([^%]]+)%]%]")
end
end
if interposing_words then
local preceding = table.remove(interposing_words, 1)
local length = #interposing_words
local following = table.remove(interposing_words, length)
interposing_words.count = length - 1
-- Change this if game goes into January.
local date = game_entry:match("%d%d:%d%d, %d%d? %a+ %d%d%d%d")
local day_difference
if not date then
mw.log("No date found in the game entry " .. game_entry .. ".")
elseif prev_date then
day_difference = get_day_difference(date, prev_date)
end
j = j + 1
prev_date = date
parsed_game[j] = {
preceding = preceding,
following = following,
interposing = interposing_words,
username = game_entry:match("User:([^%]|]+)")
or mw.log("No username found in the game entry " .. game_entry .. "."),
date = date,
day_difference = day_difference,
}
elseif not to_be_ignored then
mw.log("The game entry " .. game_entry .. " could not be parsed!")
end
end
end
return parsed_games
end
--[[
local Wonderfool_page = "User:AryamanA/Wonderfool"
local function get_Wonderfool_names()
local list = mw.title.new(Wonderfool_page):getContent():match("==List==\n*(.-)\n*==")
local names = {}
for name in list:gmatch("{{user|([^}]+)}}") do
names[name] = true
end
return names
end
--]]
local function count_points(games)
local users = {}
--[[
local conditional_logObject
if fullpagename == "Wiktionary:Christmas Competition 2017" then
function conditional_logObject() end
else
function conditional_logObject(...)
return mw.logObject(...)
end
end
--]]
for _, game in ipairs(games) do
local prev
for i, entry in ipairs(game) do
local user = entry.username
-- user = is_Wonderfool[user] and "Wonderfool" or user
-- 10 points for each successful extension of the chain.
local points = 10
-- 5 points for each additional interposing word.
points = points + (entry.interposing.count - 1) * 5
-- 25 points if last extension to chain was 3 days or more ago.
local day_difference = entry.day_difference
if day_difference and day_difference > 3 then
-- conditional_logObject{ prev, entry, difference = day_difference }
points = points + 25
end
-- 10 points to the last user to extend each chain.
if not game[i + 1] then
points = points + 10
end
entry.points = points
-- prev = entry
end
end
return games
end
return count_points(parse_games(grab_games(mw.title.new("Wiktionary:Christmas Competition 2017"):getContent())))