Модуль:StatEngine/RatingBuilder/TournamentPoints

Материал из ЧТМ
Версия от 23:53, 2 июня 2026; Туалетный король (обсуждение | вклад) (словарь вынесен в Модуль:Data/RatingCalc)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигации Перейти к поиску

Чтобы получить дефолтный список (только коды и очки) по новой системе:

{{#invoke:StatEngine/RatingBuilder/TournamentPoints|main|ЧТМ|2014}}

Указать старую систему:

{{#invoke:StatEngine/RatingBuilder/TournamentPoints|main|ЧТМ|2014|old}}

Добавить 4-й параметр, чтобы отобразить код ранга (любая строка, например yes):

{{#invoke:StatEngine/RatingBuilder/TournamentPoints|main|ЧТМ|2014|new|yes}}


-- =========================================================================
-- Модуль:StatEngine/RatingBuilder/TournamentPoints
-- Выдаёт список участников заданного турнира в указанном году с их очками
-- =========================================================================

local p = {}

local Builder = require('Модуль:StatEngine/RatingBuilder')
local TeamsDB = require('Модуль:Data/Teams')
local RatingData = require('Модуль:Data/RatingCalc')

-- Проверка, относится ли турнир к региональным
local is_regional = { ["КАм"] = true, ["КАф"] = true, ["КЕв"] = true, ["КОк"] = true }

local old_system = RatingData.old_system
local old_africa_exceptions = RatingData.old_africa_exceptions
local new_system = RatingData.new_system
local new_africa_exceptions = RatingData.new_africa_exceptions

-- =========================================================
-- ТОЧКА ВХОДА
-- =========================================================
function p.main(frame)
    local args = frame.args
    -- Подхватываем параметры как из самого #invoke, так и от родительского шаблона
    if not args[1] then args = frame:getParent().args end

    local prefix = mw.text.trim(args[1] or "")
    local year = tonumber(args[2])
    local sys_type = mw.text.trim(args[3] or "new")
    local show_rank = args[4] and mw.text.trim(args[4]) ~= ""

    if prefix == "" or not year then
        return "Ошибка: необходимо передать префикс турнира и год."
    end

    local db_name = 'Модуль:Data/Tournaments/' .. year
    local success, full_db = pcall(require, db_name)
    if not success then
        return "Ошибка: не удалось загрузить БД за " .. year .. " год (" .. db_name .. ")."
    end

    -- Прогоняем данные этого года через RatingBuilder, чтобы он распределил все ранги
    local all_results = Builder.build_year(year, full_db)

    -- Достаём результаты конкретного турнира
    local tourney_results = all_results[prefix]

    if not tourney_results then
        return "Турнир " .. prefix .. " в " .. year .. " году не найден."
    end

    -- Настраиваемся на указанную систему очков
    local sys_dict = (sys_type == "old") and old_system or new_system
    local exc_dict = (sys_type == "old") and old_africa_exceptions or new_africa_exceptions

    local final_teams = {}

    -- Проходим по каждой команде, игравшей в турнире (как в отборе, так и в финале)
    for team, rank in pairs(tourney_results) do
        local pts = 0
        local t_dict = is_regional[prefix] and sys_dict["Reg"] or sys_dict[prefix]

        if t_dict and t_dict[year] then
            pts = t_dict[year][rank]

            -- Обработка "-no" (неполучение очков) и отсутствия значения в словаре
            if not pts and string.match(rank, "%-no$") then
                pts = 0 
            end
            if not pts then 
                pts = 0 
            end
        end

        -- Применение исключений для Африки
        local team_info = TeamsDB.getTeam(team)
        local is_africa = team_info and team_info.conf == "Африка"
        if prefix == "ЧТМ" and is_africa and exc_dict[year] and exc_dict[year][rank] then
            pts = exc_dict[year][rank]
        end

        -- Коррекция Евразии для новых региональных кубков
        if prefix == "КЕв" and (year == 2048 or year == 2052) and sys_type ~= "old" then
            if rank == "в" then pts = (year == 2048) and 14.4 or 19.2 end
        end

        table.insert(final_teams, {code = team, points = pts, rank = rank})
    end

    -- Сортировка: сначала по очкам (по убыванию), при равенстве - по коду (по алфавиту)
    table.sort(final_teams, function(a, b)
        if a.points ~= b.points then
            return a.points > b.points
        end
        return a.code < b.code
    end)

    -- Формируем итоговый список
    local out = {"<pre>"}
    for _, t in ipairs(final_teams) do
        if show_rank then
            table.insert(out, string.format("%s %s %s", t.code, tostring(t.points), t.rank))
        else
            table.insert(out, string.format("%s %s", t.code, tostring(t.points)))
        end
    end
    table.insert(out, "</pre>")

    return table.concat(out, "\n")
end

return p