Modul:Floorballtabelle

Diese Seite ist die Dokumentations-Unterseite von Modul:Floorballtabelle.

Beschreibung

Dieses Modul übernimmt die Berechnung und die serverseitige automatische Sortierung von Floorball- und Unihockeytabellen. Es wird über die Hauptvorlage {{Floorballtabelle}} aufgerufen und rendert die gesamte Tabelle auf Basis der eingegebenen Team-Daten.

Sortierungsreihenfolge

Das Modul sortiert die Zeilen beim Rendern der Seite automatisch nach folgenden Kriterien abwärts:

  1. PpS (Punkte pro Spiel / Punktequotient)
  2. TD (Tordifferenz)
  3. T+ (Erzielte Tore)

Automatische Einfärbung (Playoffs / Playouts)

Das Modul kann Teams automatisch farblich markieren (Grün für Playoffs, Rot für Playouts), sobald deren Teilnahme mathematisch gesichert ist. Hierfür muss lediglich der Parameter Anzahlspiele definiert werden. Das Modul berechnet dann anhand der noch zu vergebenen Punkte, ob ein Team nicht mehr unter den Strich rutschen bzw. diesen nicht mehr erreichen kann. Bei Punktgleichständen, in denen Direktbegegnungen (Tie-Breaker) entscheiden, kann die Markierung über die Parameter playoffX=ja oder playoutX=ja auch manuell erzwungen werden.

Parameter

Allgemeine Einstellungen

  • titel: Optionale Überschrift oberhalb der Tabelle.
  • strich: Zeilen-Index, nach welchem eine dicke schwarze Trennlinie gezogen wird (z. B. 8 für den Playoff-Strich der Top 8). 0 deaktiviert den Strich.
  • Anzahlspiele: Gibt die Gesamtzahl der Spiele pro Team in einer kompletten Saison an (z. B. 22). Wird benötigt, um die Playoff- und Playout-Sicherheit vollautomatisch zu berechnen.
  • playoffs: Anzahl der Teams von oben, die für die Playoffs vorgesehen sind (z. B. 8).
  • playouts: Anzahl der Teams von unten, die für die Playouts vorgesehen sind (z. B. 4).
  • farben: Standardmäßig 0. (Hinweis: Die farbliche Hinterlegung der Zeilen erfolgt mittlerweile dynamisch durch die automatische Berechnung oder manuelle Parameter pro Team).
  • legende: Auf 1 oder ja setzen, um die Legendenbox unter der Tabelle zu aktivieren.
  • playoff_text: (Optional) Text für die Playoff-Legende. Standard: Teilnahme an den Playoffs.
  • playout_text: (Optional) Text für die Playout-Legende. Standard: Teilnahme an den Playouts.
  • zusatz_text: (Optional) Zusätzlicher Text in der Legende (z. B. Erklärungen für (M) Meister, (H) Hauptrundensieger).

Team-Parameter (1 bis X)

Für jedes Team wird eine fortlaufende Nummer (Index) an den Parameter angehängt (z. B. team1, team2, ...). Das Modul unterstützt eine beliebige Anzahl von Teams.

  • teamX: Name des Vereins (ggf. verlinkt).
  • spX: Absolvierte Spiele.
  • sX: Siege (gibt 3 Punkte).
  • snvX: Siege nach Verlängerung/Penaltyschießen (gibt 2 Punkte).
  • nnvX: Niederlagen nach Verlängerung/Penaltyschießen (gibt 1 Punkt).
  • nX: Niederlagen (gibt 0 Punkte).
  • tplusX: Geschossene Tore.
  • tminusX: Kassierte Tore.
  • playoffX: (Optional) Auf 1 oder ja setzen, um ein Team manuell als sicheren Playoff-Teilnehmer zu markieren (für Tie-Breaker).
  • playoutX: (Optional) Auf 1 oder ja setzen, um ein Team manuell als sicheren Playout-Teilnehmer zu markieren (für Tie-Breaker).

Kopiervorlage

Dieser Block kann direkt in den Saisonartikel kopiert werden. Die Nummerierung der Teams dient hierbei nur der Eingabe; das Modul sortiert sie bei der Anzeige automatisch anhand der Parameter richtig.

{{Floorballtabelle
| titel         = 
| strich        = 8
| Anzahlspiele  = 22
| playoffs      = 8
| playouts      = 4
| farben        = 0
| legende       = 1
| playoff_text  = Teilnahme an den Playoffs
| playout_text  = Teilnahme an den Playouts
| zusatz_text   = 

| team1 = | sp1 = 0 | s1 = 0 | snv1 = 0 | nnv1 = 0 | n1 = 0 | tplus1 = 0 | tminus1 = 0
| team2 = | sp2 = 0 | s2 = 0 | snv2 = 0 | nnv2 = 0 | n2 = 0 | tplus2 = 0 | tminus2 = 0
| team3 = | sp3 = 0 | s3 = 0 | snv3 = 0 | nnv3 = 0 | n3 = 0 | tplus3 = 0 | tminus3 = 0
| team4 = | sp4 = 0 | s4 = 0 | snv4 = 0 | nnv4 = 0 | n4 = 0 | tplus4 = 0 | tminus4 = 0
| team5 = | sp5 = 0 | s5 = 0 | snv5 = 0 | nnv5 = 0 | n5 = 0 | tplus5 = 0 | tminus5 = 0
| team6 = | sp6 = 0 | s6 = 0 | snv6 = 0 | nnv6 = 0 | n6 = 0 | tplus6 = 0 | tminus6 = 0
| team7 = | sp7 = 0 | s7 = 0 | snv7 = 0 | nnv7 = 0 | n7 = 0 | tplus7 = 0 | tminus7 = 0
| team8 = | sp8 = 0 | s8 = 0 | snv8 = 0 | nnv8 = 0 | n8 = 0 | tplus8 = 0 | tminus8 = 0
| team9 = | sp9 = 0 | s9 = 0 | snv9 = 0 | nnv9 = 0 | n9 = 0 | tplus9 = 0 | tminus9 = 0
| team10 = | sp10 = 0 | s10 = 0 | snv10 = 0 | nnv10 = 0 | n10 = 0 | tplus10 = 0 | tminus10 = 0
| team11 = | sp11 = 0 | s11 = 0 | snv11 = 0 | nnv11 = 0 | n11 = 0 | tplus11 = 0 | tminus11 = 0
| team12 = | sp12 = 0 | s12 = 0 | snv12 = 0 | nnv12 = 0 | n12 = 0 | tplus12 = 0 | tminus12 = 0
}}

local p = {}

function p.main(frame)
    local args = frame:getParent().args
    local teams = {}
    
    -- Variabler Trennstrich (Standard: Platz 8)
    local strich = tonumber(args['strich']) or 8
    
    -- 1. Daten dynamisch einlesen
    local i = 1
    while args['team' .. i] and args['team' .. i] ~= '' do
        local s = tonumber(args['s' .. i]) or 0
        local snv = tonumber(args['snv' .. i]) or 0
        local nnv = tonumber(args['nnv' .. i]) or 0
        local n = tonumber(args['n' .. i]) or 0
        local sp = tonumber(args['sp' .. i]) or (s + snv + nnv + n)
        local tplus = tonumber(args['tplus' .. i]) or 0
        local tminus = tonumber(args['tminus' .. i]) or 0
        
        -- Status abfragen, ob Teilnahme manuell als sicher markiert wurde
        local playoff_sicher = (args['playoff' .. i] == '1' or args['playoff' .. i] == 'ja')
        local playout_sicher = (args['playout' .. i] == '1' or args['playout' .. i] == 'ja')
        
        local pkt = (s * 3) + (snv * 2) + (nnv * 1)
        local pps = sp > 0 and (pkt / sp) or 0
        local td = tplus - tminus
        
        table.insert(teams, {
            name = args['team' .. i],
            sp = sp,
            s = s,
            snv = snv,
            nnv = nnv,
            n = n,
            tplus = tplus,
            tminus = tminus,
            pkt = pkt,
            pps = pps,
            td = td,
            playoff = playoff_sicher,
            playout = playout_sicher
        })
        i = i + 1
    end
    
    -- 2. Sortierungs-Logik (PpS -> Tordifferenz -> Erzielte Tore)
    table.sort(teams, function(a, b)
        if math.abs(a.pps - b.pps) > 0.000001 then
            return a.pps > b.pps
        elseif a.td ~= b.td then
            return a.td > b.td
        elseif a.tplus ~= b.tplus then
            return a.tplus > b.tplus
        else
            return a.name < b.name
        end
    end)
    
    -- NEU: Automatische Berechnung der Playoff/Playout-Sicherheit
    local anzahl_spiele = tonumber(args['Anzahlspiele']) or 0
    if anzahl_spiele > 0 and #teams > strich then
        
        -- Maximal mögliche Punkte des besten Teams UNTER dem Strich berechnen
        local max_punkte_unter_strich = -1
        for j = strich + 1, #teams do
            local rest_spiele = math.max(0, anzahl_spiele - teams[j].sp)
            local max_pkt = teams[j].pkt + (rest_spiele * 3)
            if max_pkt > max_punkte_unter_strich then
                max_punkte_unter_strich = max_pkt
            end
        end
        
        -- Aktuelle Punkte des Teams GENAU AUF dem Strich ermitteln
        local punkte_auf_strich = teams[strich].pkt
        
        -- Sicherheit für jedes Team prüfen und Flags setzen
        for j, t in ipairs(teams) do
            local rest_spiele = math.max(0, anzahl_spiele - t.sp)
            local max_erreichbare_punkte = t.pkt + (rest_spiele * 3)
            
            -- Playoff sicher: Aktuelle Punkte > max. erreichbare Punkte der Konkurrenz unter dem Strich
            -- (Striker Vergleich (>) schliesst aus, dass bei Gleichstand Tie-Breaker nötig wären)
            if j <= strich and t.pkt > max_punkte_unter_strich then
                t.playoff = true
            end
            
            -- Playout sicher: Max. erreichbare Punkte < aktuelle Punkte des Teams auf dem Strich
            if j > strich and max_erreichbare_punkte < punkte_auf_strich then
                t.playout = true
            end
        end
    end
    
    -- 3. HTML-Tabelle generieren
    local out = {}
    table.insert(out, '{| class="wikitable sortable" style="text-align:center; width:100%;"')
    if args['titel'] and args['titel'] ~= '' then
        table.insert(out, '|+ ' .. args['titel'])
    end
    
    -- Tabellenkopf
    table.insert(out, '|-')
    table.insert(out, '! style="width:30px;" | Rg.')
    table.insert(out, '! style="text-align:left;" | Team')
    table.insert(out, '! style="width:30px;" | Sp')
    table.insert(out, '! style="width:30px;" | S')
    table.insert(out, '! style="width:30px;" | SnV')
    table.insert(out, '! style="width:30px;" | NnV')
    table.insert(out, '! style="width:30px;" | N')
    table.insert(out, '! style="width:50px;" | T')
    table.insert(out, '! style="width:40px;" | TD')
    table.insert(out, '! style="width:40px;" | Pkt.')
    table.insert(out, '! style="width:40px;" | PpS')
    
    -- Zeilen ausgeben
    for rg, t in ipairs(teams) do
        local style = ''
        
        -- Einfärbung durch automatische ODER manuelle Prüfung
        if t.playoff then
            style = 'background-color: rgb(144,238,144); color: black;' -- Playoff-Grün
        elseif t.playout then
            style = 'background-color: rgb(255,204,204); color: black;' -- Playout-Rot
        end
        
        -- Der Trennstrich kommt immer fix nach der definierten Platzierung
        if rg == strich then
            style = style .. ' border-bottom: 4px solid;'
        end
        
        if style ~= '' then
            table.insert(out, '|- style="' .. style .. '"')
        else
            table.insert(out, '|-')
        end
        
        table.insert(out, '| ' .. rg .. '.')
        table.insert(out, '| style="text-align:left;" | ' .. t.name)
        table.insert(out, '| ' .. t.sp)
        table.insert(out, '| ' .. t.s)
        table.insert(out, '| ' .. t.snv)
        table.insert(out, '| ' .. t.nnv)
        table.insert(out, '| ' .. t.n)
        table.insert(out, '| ' .. t.tplus .. ':' .. t.tminus)
        
        local tdStr = t.td > 0 and ('+' .. t.td) or tostring(t.td)
        table.insert(out, '| ' .. tdStr)
        -- Fettschrift ohne überflüssige Backslashes
        table.insert(out, "| '''" .. t.pkt .. "'''")
        
        local ppsStr = string.format("%.2f", t.pps):gsub('%.', ',')
        table.insert(out, '| ' .. ppsStr)
    end
    
    table.insert(out, '|}')
    
    -- 4. Legende anhängen
    if args['legende'] == '1' or args['legende'] == 'ja' then
        local po_text = args['playoff_text'] or 'Teilnahme an den Playoffs'
        local pt_text = args['playout_text'] or 'Teilnahme an den Playouts'
        local zusatz = args['zusatz_text'] or ''
        
        table.insert(out, '\n<div style="font-size:90%; margin-top:5px; text-align:left;">')
        table.insert(out, '<span style="background-color: rgb(144,238,144); border: 1px solid #aaa; padding: 0 8px; margin-right: 5px;">&nbsp;</span> ' .. po_text .. '<br />')
        table.insert(out, '<span style="background-color: rgb(255,204,204); border: 1px solid #aaa; padding: 0 8px; margin-right: 5px;">&nbsp;</span> ' .. pt_text)
        if zusatz ~= '' then
            table.insert(out, '<br />' .. zusatz)
        end
        table.insert(out, '</div>')
    end
    
    return table.concat(out, '\n')
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.