M3: Double-Elimination (Winner/Loser-Bracket + Grand Final) - #5
Open
TimGoldbach wants to merge 1 commit into
Open
M3: Double-Elimination (Winner/Loser-Bracket + Grand Final)#5TimGoldbach wants to merge 1 commit into
TimGoldbach wants to merge 1 commit into
Conversation
First slice of M3 (format breadth), built test-driven via a workflow + a 3-lens adversarial review (0 blockers; the review found only test-quality issues, no code bugs). Verified: tsc clean, vitest 22/22. - bracket-generator: real double_elimination generator for power-of-two fields — one stage/one group with sequential rounds (WB 1..k, LB 2(k-1) rounds, single Grand Final, no reset), within-group winner_of/loser_of sources. Matches the canonical N=4 (6 matches) and N=8 (14 matches) structures; 2N-2 in general. Non-power-of-two throws NotImplemented (byes/odd fields are M3.1). - progression: loserAdvancement (mirror of winnerAdvancement for loser_of). - tournaments.service.score(): for elimination, also drop the loser via loserAdvancement (no-op for single-elim; round-robin unchanged). - tests: exact-structure asserts for N=4/N=8, 2N-2 for N=4/8/16, non-pow2 throws, loserAdvancement unit test, and a deterministic full-tournament simulation that plays every match to completion and asserts the Grand Final crowns the undefeated WB finalist while the LB finalist carries exactly one loss (proves the loser-bracket wiring). Deferred (docs/PLAN.md): DE non-pow2/byes + bracket reset (M3.1), groups+KO with cross-stage seeding (M3.2), Swiss + Buchholz (M3.3), and a service-layer DB test for the score()/reseed() DE path once a database is available. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Erste Scheibe von M3 (Format-Breite): Double-Elimination. Test-getrieben über einen Workflow + 3-Perspektiven-Review gebaut. 0 Blocker — das Review fand nur Test-Qualitäts-Punkte, keine Code-Bugs. Verifiziert:
tscgrün, vitest 22/22.Was drin ist
bracket-generator.service.ts): echterdouble_elimination-Generator für Power-of-2-Felder — ein Stage/eine Group mit sequentiellen Runden (WB 1..k, LB 2(k-1) Runden, ein Grand Final, kein Reset), within-groupwinner_of/loser_of-Quellen. Trifft die kanonische N=4 (6 Matches) und N=8 (14 Matches) Struktur exakt; allgemein 2N-2. Nicht-Zweierpotenz wirftNotImplemented(→ M3.1).progression.ts):loserAdvancement(Spiegel vonwinnerAdvancementfürloser_of).tournaments.service.ts): bei Elimination wird zusätzlich der Verlierer vialoserAdvancementins Loser-Bracket gesetzt (No-op für Single-Elim; Round-Robin unverändert).Tests (ausgeführt, grün)
Exakte Struktur-Asserts N=4/N=8, 2N-2 für N=4/8/16, Nicht-Zweierpotenz wirft,
loserAdvancement-Unit-Test — plus eine deterministische Voll-Simulation: spielt jedes Match aus und prüft, dass das Grand Final den ungeschlagenen WB-Finalisten krönt und der LB-Finalist genau eine Niederlage trägt (beweist das Loser-Bracket-Wiring).Review-Fix
Eine tautologische „single champion"-Assertion (Simulator setzt Sieger=opponent1, Test prüfte genau das) durch echte Constraints ersetzt: GF = genau ein Match, Champion hat 0 Niederlagen.
Verschoben (in docs/PLAN.md)
score()/reseed()-Pfad, sobald eine DB verfügbar ist (offline nicht möglich).🤖 Generated with Claude Code