Jump to content

Module:Build bracket/StateChecks

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Pbrks (talk | contribs) at 02:18, 13 August 2025 (Created page with 'local StateChecks = {} -- Local mini-helpers (kept internal so we don't depend on Helpers here) local function isempty(s) return s == nil or s == '' end local function notempty(s) return s ~= nil and s ~= '' end -- isBlankEntry: true if no team/text present for a cell function StateChecks.isBlankEntry(state, j, i) local colEntries = state.entries[j] if not colEntries then return true end local e = colEntries[i] if not e then return true e...'). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
local StateChecks = {}

-- Local mini-helpers (kept internal so we don't depend on Helpers here)
local function isempty(s) return s == nil or s == '' end 
local function notempty(s) return s ~= nil and s ~= '' end

-- isBlankEntry: true if no team/text present for a cell
function StateChecks.isBlankEntry(state, j, i)
    local colEntries = state.entries[j]
    if not colEntries then return true end
    local e = colEntries[i]
    if not e then return true end
    return isempty(e.team) and isempty(e.text)
end

-- showSeeds: decide whether to display the seed cell for a team row
function StateChecks.showSeeds(state, config, j, i)
    local row = state.entries[j]
    if not row then return false end
    local e = row[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
    local step  = 2

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

    for k = 1, tpm - 1 do
        local plus  = i + step * k
        local minus = i - step * k
        if plus  <= config.r and neighborHasSeed(plus)  then return true end
        if minus >= 1        and neighborHasSeed(minus) then return true end
    end
    return false
end

-- teamLegs: effective #legs for a team row, honoring per-entry overrides and autolegs
function StateChecks.teamLegs(state, config, j, i)
    local col = state.entries[j]
    if not col then return state.rlegs[j] or 1 end
    local e = col[i]
    if not e or e.ctype ~= 'team' then
        return state.rlegs[j] or 1
    end

    local legs = state.rlegs[j] or 1
    if notempty(e.legs) then
        legs = tonumber(e.legs) or legs
    end

    -- treat nil/'' and values 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

    -- autolegs: count contiguous non-blank leg entries starting at 1
    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

-- roundIsEmpty: scan forward until next header; true if only blanks in that round
function StateChecks.roundIsEmpty(state, config, j, i)
    local col = state.entries[j]
    if not col then return true end

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

-- defaultHeaderText: mirror the built-in naming ("Final", "Semifinals", etc.)
function StateChecks.defaultHeaderText(config, j, headerindex)
    if headerindex ~= 1 then
        return 'Lower round ' .. tostring(j)
    end
    local c = tonumber(config.c) or j
    local rem = c - j
    if rem == 0 then
        return 'Final'
    elseif rem == 1 then
        return 'Semifinals'
    elseif rem == 2 then
        return 'Quarterfinals'
    else
        return 'Round ' .. tostring(j)
    end
end

-- noPaths: true if there are no path segments adjacent to the entry at (j,i)
function StateChecks.noPaths(state, j, i)
    local cols = state.hascross[j] and 3 or 2

    local pcj = state.pathCell[j]
    local pci = pcj and pcj[i]
    if pci then
        for k = 1, cols do
            local ktab = pci[k]
            local dir1 = ktab and ktab[1]
            if dir1 then
                for n = 1, 4 do
                    local v = dir1[n]
                    if v and v ~= 0 then
                        return false
                    end
                end
            end
        end
    end

    if state.hascross[j] then
        local ccj = state.crossCell[j]
        local cci = ccj and ccj[i]
        if cci then
            local left  = cci.left
            local right = 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