All projects Clinch · Write-up

Playoff labels without guessworkPlayoff-Labels ohne Rätselraten

Clinch shows the NFL standings and the playoff picture on one screen. Its one rule: a team is only called in or out once the arithmetic settles it.Clinch zeigt die NFL-Tabellen und das Playoff-Bild auf einem Bildschirm. Die eine Regel: Ein Team gilt erst als drin oder raus, wenn die Rechnung es entscheidet.

clinch.ewolution.cloud Source

Type
Web appWeb-App
Stack
React · TypeScript · Express
Year
2026
Code
Public on GitHubÖffentlich auf GitHub

The question on a Sunday evening

The NFL doesn’t have one table. Its 32 teams sit in two conferences of four divisions each. In each conference the four division winners make the playoffs whatever their record, three wild cards make it because of theirs, and all seven are seeded one to seven. The question on a Sunday evening is simple: who is in, who is chasing, who is out. The data to answer it is spread across standings pages, and most apps answer it with a percentage.

Clinch answers it with labels, and it only shows a label it can prove.

Floors and ceilings

Every label is settled arithmetic. A win counts 1 and a tie counts ½, so ties stop being a special case. A team’s floor is the record it ends on if it loses every remaining game; its ceiling is the record if it wins them all.

EliminatedIts ceiling is below the current 7th seed’s floor. Seven teams are already at or above that mark, and none of them can drop.
Clinched berthIts floor is above the ceiling of all nine teams outside the cut. At worst it finishes as the 7 seed.
Clinched divisionIts floor is above the ceilings of its three division rivals.
Clinched byeDivision clinched, and its floor is above every other ceiling in the conference.
Four teams as ranges from floor to ceiling. The first seed’s floor is past the best ceiling outside the cut; the 13th team’s ceiling ends before the 7th seed’s floor. 46810121416 wins · a tie counts ½ Seed 1Seed 79th13th clinched berthholds the 7 seedin the hunteliminated 7th seed’s floor best ceiling outside the cut
Fig. 1Each bar runs from a team’s floor to its ceiling. The 1 seed’s floor is past every ceiling outside the cut, so it’s in. The 13th team’s ceiling doesn’t reach the 7th seed’s floor, so it’s out.

These are sufficient conditions, not exhaustive ones. Some eliminations only show up in a full analysis of the remaining schedule, and Clinch doesn’t attempt one. The trade is deliberate: it can be a week late to call a team out, and it never calls one out wrongly.

What comes from ESPN, and what doesn’t

Scores, schedule and standings come from ESPN’s public endpoints. The conference seed arrives with the NFL’s full tiebreaker chain already applied (head-to-head, common games, strength of victory), and Clinch takes it as given rather than reimplementing rules it would get subtly wrong.

Two things aren’t taken at face value. ESPN lists a division’s teams in its own order, which isn’t the standings order, so divisions are sorted by seed. And before a team has played, its seed comes back as 0, which would sort it above the entire conference. Those teams are slotted in by win differential and the conference is renumbered.

A bracket that never assumes

Only two things ever place a team in the bracket: a game that was played, and a pick you made yourself. There is no “higher seed advances” filling the tree to the Super Bowl with results nobody played. During the regular season the tree shows the wild card matchups today’s seeding produces, and every later slot says where its team will come from: lowest remaining seed, winner of game 4, AFC champion.

A pick re-runs everything below it, including the NFL’s reseeding. After an upset the 1 seed draws the lowest seed left, which may not be the team the drawn line points at. When that happens, the round says so.

Live scores, in the browser

While games are being played, one switch counts every game in progress as if it had just ended, and the table, the seeds and the labels move with the score. That calculation runs in the browser, for a measured reason: the conference tables are 70 kB of a 75 kB snapshot, and the server pushes a snapshot every 25 seconds. A second, adjusted copy would nearly double every push, on a phone, for hours.

So the clinch arithmetic exists twice, once on the server and once in the client. A test keeps the two honest: it applies the client’s calculation to games in progress, has the server build the same games as final results, and asserts that both tables are identical.

Small numbers

590 kB → 3 kBOne game’s detail from ESPN, trimmed on the server to what the dialog shows.
1 requestPer polling cycle. Every visitor is served from one copy, and finished weeks are never fetched again.
0.3 sFor the whole test suite: node --test, fixtures saved from the live sources, no network.

The app is one container. Express serves the built React frontend and the API, with no database and no state on disk, and updates reach the page over server-sent events.

Die Frage am Sonntagabend

Die NFL hat keine einzelne Tabelle. Ihre 32 Teams verteilen sich auf zwei Conferences mit je vier Divisions. Pro Conference erreichen die vier Divisionssieger die Playoffs unabhängig von ihrer Bilanz, drei Wild Cards wegen ihrer Bilanz, und alle sieben werden von eins bis sieben gesetzt. Die Frage am Sonntagabend ist einfach: Wer ist drin, wer jagt noch, wer ist raus? Die Daten dafür liegen über mehrere Tabellenseiten verstreut, und die meisten Apps antworten mit einer Prozentzahl.

Clinch antwortet mit Labels und zeigt nur Labels, die sich beweisen lassen.

Minimum und Maximum

Jedes Label ist abgeschlossene Arithmetik. Ein Sieg zählt 1, ein Unentschieden ½, damit ist das Unentschieden kein Sonderfall mehr. Das Minimum eines Teams ist die Bilanz, mit der es endet, wenn es alle restlichen Spiele verliert; das Maximum die Bilanz, wenn es alle gewinnt.

AusgeschiedenSein Maximum liegt unter dem Minimum des aktuellen 7. Seeds. Sieben Teams stehen schon mindestens dort, und keines davon kann zurückfallen.
Playoffs sicherSein Minimum liegt über dem Maximum aller neun Teams hinter der Grenze. Schlimmstenfalls wird es der 7. Seed.
Division sicherSein Minimum liegt über den Maxima seiner drei Divisionsrivalen.
Bye sicherDie Division ist sicher, und sein Minimum liegt über jedem anderen Maximum der Conference.
Vier Teams als Spanne von Minimum bis Maximum. Das Minimum des 1. Seeds liegt jenseits des besten Maximums hinter der Grenze; das Maximum des 13. endet vor dem Minimum des 7. Seeds. 46810121416 Siege · Unentschieden zählt ½ Seed 1Seed 7Platz 9Platz 13 Playoffs sicherhält den 7. Seednoch im Rennenausgeschieden Minimum des 7. Seeds bestes Maximum hinter der Grenze
Abb. 1Jeder Balken reicht vom Minimum eines Teams bis zu seinem Maximum. Das Minimum des 1. Seeds liegt über jedem Maximum hinter der Grenze, also ist er drin. Das Maximum des 13. erreicht das Minimum des 7. Seeds nicht mehr, also ist er raus.

Das sind hinreichende Bedingungen, keine vollständigen. Manches Ausscheiden zeigt sich erst in einer Analyse des gesamten Restspielplans, und die versucht Clinch nicht. Der Tausch ist gewollt: Clinch erklärt ein Team womöglich eine Woche zu spät für ausgeschieden, aber nie fälschlich.

Was von ESPN kommt und was nicht

Ergebnisse, Spielplan und Tabellen kommen von ESPNs öffentlichen Endpunkten. Der Conference-Seed kommt mit der vollständigen Tiebreaker-Kette der NFL (direkter Vergleich, gemeinsame Gegner, Strength of Victory), und Clinch übernimmt ihn, statt Regeln nachzubauen, die es im Detail falsch machen würde.

Zwei Dinge werden nicht einfach übernommen. ESPN listet die Teams einer Division in eigener Reihenfolge, die nicht der Tabelle entspricht, deshalb werden Divisions nach Seed sortiert. Und bevor ein Team gespielt hat, kommt sein Seed als 0 zurück, was es über die ganze Conference sortieren würde. Solche Teams werden nach Siegdifferenz eingeordnet, und die Conference wird neu durchnummeriert.

Ein Turnierbaum, der nichts annimmt

Nur zwei Dinge setzen ein Team in den Turnierbaum: ein Spiel, das gespielt wurde, und ein Tipp, den du selbst abgibst. Es gibt kein „der höhere Seed kommt weiter“, das den Baum bis zum Super Bowl mit Ergebnissen füllt, die niemand gespielt hat. In der regulären Saison zeigt der Baum die Wild-Card-Paarungen der heutigen Setzliste, und jeder spätere Platz sagt, woher sein Team kommen wird: niedrigster verbliebener Seed, Sieger von Spiel 4, AFC-Champion.

Ein Tipp rechnet alles darunter neu, einschließlich des Reseedings der NFL. Nach einer Überraschung trifft der 1. Seed auf den niedrigsten verbliebenen Seed, und das ist nicht unbedingt das Team, auf das die gezeichnete Linie zeigt. Dann sagt die Runde das auch.

Live-Ergebnisse im Browser

Während Spiele laufen, zählt ein Schalter jedes laufende Spiel so, als wäre es gerade zu Ende gegangen, und Tabelle, Seeds und Labels bewegen sich mit dem Spielstand. Diese Rechnung läuft im Browser, aus einem gemessenen Grund: Die Conference-Tabellen machen 70 kB eines 75-kB-Snapshots aus, und der Server schickt alle 25 Sekunden einen Snapshot. Eine zweite, angepasste Kopie würde jeden Push fast verdoppeln, stundenlang, auf dem Handy.

Deshalb gibt es die Clinch-Arithmetik zweimal, auf dem Server und im Client. Ein Test hält beide ehrlich: Er wendet die Rechnung des Clients auf laufende Spiele an, lässt den Server dieselben Spiele als Endergebnisse verarbeiten und prüft, dass beide Tabellen identisch sind.

Kleine Zahlen

590 kB → 3 kBDie Details eines Spiels von ESPN, auf dem Server gekürzt auf das, was der Dialog zeigt.
1 AnfragePro Abfragezyklus. Alle Besucher bekommen dieselbe Kopie, beendete Wochen werden nie wieder geladen.
0,3 sFür die ganze Testsuite: node --test, Fixtures aus echten Antworten, kein Netzwerk.

Die App ist ein einziger Container. Express liefert das gebaute React-Frontend und die API aus, ohne Datenbank und ohne Zustand auf der Platte, und Updates erreichen die Seite per Server-Sent Events.