Модуль:Призы игрового дня

Материал из ЧТМ
Версия от 04:42, 2 июня 2026; Дача Цанавы (обсуждение | вклад) (Исправление бага с отрисовкой только КПГ в скобочках)
(разн.) ← Предыдущая версия | Текущая версия (разн.) | Следующая версия → (разн.)
Перейти к навигации Перейти к поиску
Документация Документация

Модуль, выводящий табличку призов конкретных игровых дней.

Запрос:

{{#invoke:Призы игрового дня|render|year=|matchday=}}

Пример:

{{#invoke:Призы игрового дня|render|year=2038|matchday=7}}

Результат:

Призы игрового дня 
Приз1-е2-е3-е4-еХудший
MVPГеныч (3)Алишер (1)Лёха (1)
Лучший бомбардирГеныч (6)Лёха (5)Диман (5)Ринат (3)Пумба (0)
Лучший ассистентАлишер (7)Геныч (5)Диман (3)Ринат (3)Лёха (0)
Самый результативный футболистГеныч (11)Алишер (9)Диман (8)Ринат (6)Пумба (0)
Лучший вратарьДиман (9)Лёха (8.5)Геныч (8)Дима Кес. (6.25)
Самый эффективный футболистДиман (12)Геныч (9)Алишер (9)Лёха (6)Пумба (0)
Самый полезный футболистГеныч (+9)Диман (+5)Алишер (+5)Лёха (+4)Пумба (-10)

Этот модуль должен в будущем стать частью более обширного модуля, чтобы не гонять БД несколько раз.


Пожалуйста, добавляйте категории на страницу документации.

-- ==========================================
-- Модуль:MatchdayPrizes
-- ==========================================
local MatchdayPrizes = {}

local Config = require('Module:Config')
local TournamentAwards = require('Module:StatEngine/TournamentAwards')

function MatchdayPrizes.render(frame)
    local args = frame.args
    local year = tonumber(args.year)
    local matchday = tonumber(args.matchday)
    
    if not year or not matchday then
        return '<span class="error">Ошибка: укажите обязательные параметры year (год) и matchday (номер игрового дня).</span>'
    end

    -- 1. Подгружаем базу данных (защищённый вызов на случай ошибки)
    local status, year_db = pcall(mw.loadData, 'Module:Data/' .. year)
    if not status then
        return '<span class="error">Ошибка: база данных за ' .. year .. ' год не найдена.</span>'
    end

    -- 2. Запускаем Инженера! (ОДИН проход по БД, вся статистика и призы уже внутри)
    local prizes = TournamentAwards.evaluateMatchdayPrizes(year_db, matchday)

    -- 3. Начинаем сборку HTML-таблицы
    local html = mw.html.create('table')
        -- Добавляем классы. Используем 'wikitable' как базу, плюс классы сворачивания из конфига
        :addClass('wikitable')
        :addClass(Config.styles.collapsible)
        :addClass(Config.styles.collapsed)

    -- Главная шапка
    html:tag('tr'):tag('th')
        :attr('colspan', '6')
        :wikitext('[[Призы игровых дней|Призы игрового дня]]&nbsp;')

    -- Шапка колонок
    local headerRow = html:tag('tr')
    local columns = {"Приз", "1-е", "2-е", "3-е", "4-е", "Худший"}
    for _, colName in ipairs(columns) do
        headerRow:tag('th')
            :attr('scope', 'col')
            :css('background-color', '#ebf3fe')
            :wikitext(colName)
    end

    -- 4. Конфигурация строк (какую стату откуда берём)
    local rows_config = {
        { id = "mvp",        title = "[[MVP игрового дня|MVP]]", list = prizes.mvp, get_val = function(p) return p.mvp_count end },
        { id = "scorer",     title = "[[Лучший бомбардир игрового дня|Лучший бомбардир]]", list = prizes.scorer, get_val = function(p) return p.goals end },
        { id = "assistant",  title = "[[Лучший ассистент игрового дня|Лучший ассистент]]", list = prizes.assistant, get_val = function(p) return p.assists end },
        { id = "productive", title = "[[Самый результативный футболист игрового дня|Самый результативный футболист]]", list = prizes.productive, get_val = function(p) return p.goals + p.assists end },
        { id = "goalie",     title = "[[Лучший вратарь игрового дня|Лучший вратарь]]", list = prizes.goalie_good, bad_list = prizes.goalie_bad, 
          get_val = function(p) 
              -- ИСПРАВЛЕНО: Выводим итоговые баллы (goalie_score), а не только КПГ (gaa)
              if p.goalie_score == math.floor(p.goalie_score) then return tostring(math.floor(p.goalie_score)) end
              local s = string.format("%.2f", p.goalie_score)
              if s:sub(-1) == "0" then s = s:sub(1, -2) end -- удаляем висячий ноль в конце (напр. 10.50 -> 10.5)
              return s
          end 
        },
        { id = "effective",  title = "[[Самый эффективный футболист игрового дня|Самый эффективный футболист]]", list = prizes.effective, get_val = function(p) return p.points_total end },
        { id = "useful",     title = "[[Самый полезный футболист игрового дня|Самый полезный футболист]]", list = prizes.useful, get_val = function(p) return (p.plus_minus > 0 and "+" or "") .. tostring(p.plus_minus) end }
    }

    -- 5. Генерация строк
    for _, cfg in ipairs(rows_config) do
        local tr = html:tag('tr')
        
        -- Ячейка названия приза
        tr:tag('td')
            :css('white-space', 'nowrap')
            :css('text-align', 'center')
            :wikitext(cfg.title)

        -- Умная функция отрисовки ячейки (для 1-4 мест и Худшего)
        local function render_cell(rank, is_worst)
            local matches = {}
            local target_list = is_worst and (cfg.bad_list or cfg.list) or cfg.list
            
            -- Ищем всех игроков, которые попали на это место
            for _, p in ipairs(target_list) do
                if (is_worst and p.anti_prize) or (not is_worst and p.rank == rank) then
                    table.insert(matches, p)
                end
            end
            
            local td = tr:tag('td')
                :css('white-space', 'nowrap')
                :css('text-align', 'center')
            
            if #matches == 0 then
                td:wikitext('—')
            else
                -- Применяем цвет фона из StatEngine (он уже содержит нужный background-color)
                if matches[1].color and matches[1].color ~= "" then
                    td:cssText(matches[1].color)
                end
                
                local texts = {}
                for _, p in ipairs(matches) do
                    local link = "[[" .. p.name .. "]]"
                    -- Победителей выделяем жирным
                    if rank == 1 and not is_worst then link = "'''" .. link .. "'''" end
                    table.insert(texts, link .. " (" .. cfg.get_val(p) .. ")")
                end
                
                -- Если на одном месте несколько человек, склеиваем их через перенос строки
                td:wikitext(table.concat(texts, "<br>"))
            end
        end

        -- Отрисовываем колонки по порядку
        render_cell(1, false) -- 1-е
        render_cell(2, false) -- 2-е
        render_cell(3, false) -- 3-е
        render_cell(4, false) -- 4-е
        render_cell(nil, true) -- Худший
    end

    return tostring(html)
end

return MatchdayPrizes