Przejdź do zawartości

Moduł:Build bracket/StateChecks

Z Wikipedii, wolnej encyklopedii
To jest najnowsza wersja artykułu Moduł:Build bracket/StateChecks edytowana 07:30, 18 sie 2025 przez Quri.inka (dyskusja | edycje).
(różn.) ← poprzednia wersja | przejdź do aktualnej wersji (różn.) | następna wersja → (różn.)
 Dokumentacja modułu[stwórz] • [odśwież]
local StateChecks = {}

-- =========================
-- 1) MODULE BINDINGS
-- =========================
-- Bound at runtime
local state, config, Helpers

-- Local aliases (filled in bind; with fallbacks)
local isempty, notempty

function StateChecks.bind(_state, _config, _Helpers)
    state, config, Helpers = _state, _config, _Helpers
    isempty  = (Helpers and Helpers.isempty)  or function(v) return v == nil or v == "" end
    notempty = (Helpers and Helpers.notempty) or function(v) return v ~= nil and v ~= "" end
end

-- =========================
-- 2) CONTENT CHECKS
-- =========================
-- True when the entry at (col,row) is empty for rendering purposes.
-- For 'team' → check team text; for 'text' → check text; everything else counts as blank.
function StateChecks.isBlankEntry(col, row)
    local colEntries = state.entries and state.entries[col]
    if not colEntries then return true end

    local e = colEntries[row]
    if not e then return true end

    local ct = e.ctype
    if ct == "team" then
        return isempty(e.team)
    elseif ct == "text" then
        return isempty(e.text)
    end
    -- headers/lines/blanks or anything else are non-content here
    return true
end

-- =========================
-- 3) SEED VISIBILITY
-- =========================
-- Show seeds when forced, when this team has a seed, or when any teammate in the same match has a seed.
function StateChecks.showSeeds(j, i)
    local col = state.entries and state.entries[j]
    if not col then return false end

    local e = col[i]
    if not e or e.ctype ~= "team" then return false end

    if config.forceseeds or notempty(e.seed) then
        return true
    end

    local group = e.group
    local tpm   = state.teamsPerMatch[j] or 2
    if tpm <= 1 then return false end

    -- Teams are laid out every 2 rows per match.
    local step  = 2
    local R     = config.r

    local function neighborHasSeed(idx)
        local n = col[idx]
        return n and n.ctype == "team" and n.group == group and notempty(n.seed)
    end

    -- Check teammates forward/back within the match block
    for k = 1, tpm - 1 do
        local plus  = i + step * k
        local minus = i - step * k
        if plus  <= R and neighborHasSeed(plus)  then return true end
        if minus >= 1 and neighborHasSeed(minus) then return true end
    end

    return false
end

-- =========================
-- 4) ROUND VISIBILITY (HIDE)
-- =========================
-- Mutates state.hide[j][hidx] to false when content is found under a header (keeps legacy semantics).

function StateChecks.teamLegs(j, i)
    local col          = state.entries and state.entries[j]
    local roundDefault = (state.rlegs and state.rlegs[j]) or 1
    if not col then return roundDefault end

    local e = col[i]
    if not e or e.ctype ~= "team" then return roundDefault end

    local legs = roundDefault
    if notempty(e.legs) then
        legs = tonumber(e.legs) or legs
    end

    -- Treat nil/'' and strings containing 'nbsp' as blank
    local function isScoreBlank(v)
        if isempty(v) then return true end
        return type(v) == "string" and v:find("nbsp", 1, true) ~= nil
    end

    if config.autolegs and e.score then
        local l = 1
        while not isScoreBlank(e.score[l]) do
            l = l + 1
        end
        local inferred = l - 1
        if inferred > 0 then
            legs = inferred
        end
    end

    return legs
end

-- =========================
-- 6) ROUND CONTENT CHECK
-- =========================
-- Used for 'byes' detection: true when there is no content until the next header (or end).
function StateChecks.roundIsEmpty(j, i)
    local col = state.entries and state.entries[j]
    if not col then return true end

    local row, R = i + 1, config.r
    while row <= R do
        local e = col[row]
        if e and e.ctype == "header" then break end
        if not StateChecks.isBlankEntry(j, row) then
            return false
        end
        row = row + 1
    end
    return true
end

-- =========================
-- 7) DEFAULT HEADER TEXT
-- =========================
-- Default header text when none provided (keeps legacy strings).
function StateChecks.defaultHeaderText(j, headerindex)
    if headerindex ~= 1 then
        return "Lower round " .. tostring(j)
    end

    local base    = config.base or 0
    local orig_j  = j + base
    local total   = config.c_total or (config.c + base)
    local rem     = total - orig_j

    if rem == 0 then
        return "Final"
    elseif rem == 1 then
        return "Semifinals"
    elseif rem == 2 then
        return "Quarterfinals"
    else
        return "Round " .. tostring(orig_j)
    end
end

-- =========================
-- 8) PATH PRESENCE CHECK
-- =========================
-- True when the path block between j → j+1 at row i has no visible lines at all.
function StateChecks.noPaths(j, i)
    local hasCross = state.hascross and state.hascross[j]
    local cols     = hasCross and 3 or 2

    -- Path cells: any nonzero border means a path
    local pcj = state.pathCell and state.pathCell[j]
    local pci = pcj and pcj[i]
    if pci then
        for k = 1, cols do
            local edges = pci[k] and pci[k][1]
            if edges and (
                (edges[1] and edges[1] ~= 0) or
                (edges[2] and edges[2] ~= 0) or
                (edges[3] and edges[3] ~= 0) or
                (edges[4] and edges[4] ~= 0)
            ) then
                return false
            end
        end
    end

    -- Cross cells: left/right flag at index 1 means a cross path
    if hasCross then
        local ccj = state.crossCell and state.crossCell[j]
        local cci = ccj and ccj[i]
        if cci then
            local left, right = cci.left, cci.right
            if (left and left[1] == 1) or (right and right[1] == 1) then
                return false
            end
        end
    end

    return true
end

return StateChecks