From 89e68c30336f55a922e02d21737b111b7632f004 Mon Sep 17 00:00:00 2001 From: Razmig Sarkissian Date: Mon, 22 Sep 2025 16:14:16 +0200 Subject: [PATCH] Fix double butterfly match positioning in quarterfinals Adjust match positioning logic for uneven matches in double butterfly mode, ensuring correct spacing and display of matches when some quarterfinal matches are missing. --- tournaments/models/round.py | 38 ++++++++++++++++++- .../tournaments/js/tournament_bracket.js | 14 ++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/tournaments/models/round.py b/tournaments/models/round.py index 195e9e3..e776592 100644 --- a/tournaments/models/round.py +++ b/tournaments/models/round.py @@ -154,7 +154,43 @@ class Round(TournamentSubModel): if matches: if len(matches) > 1 and double_butterfly_mode: - midpoint = int(len(matches) / 2) + if len(matches) % 2 == 1: + # Calculate expected index range for this round + if self.index == 0: + # Final: only index 0 + expected_indices = [0] + else: + # For round n: 2^n matches, starting at index (2^n - 1) + expected_count = 2 ** self.index + start_index = (2 ** self.index) - 1 + expected_indices = list(range(start_index, start_index + expected_count)) + + # Get actual match indices + actual_indices = [match.index for match in matches] + missing_indices = [idx for idx in expected_indices if idx not in actual_indices] + + if missing_indices and len(expected_indices) > 1: + # Split the expected range in half + midpoint_index = len(expected_indices) // 2 + first_half_expected = expected_indices[:midpoint_index] + second_half_expected = expected_indices[midpoint_index:] + + # Count actual matches in each theoretical half + first_half_actual = sum(1 for idx in actual_indices if idx in first_half_expected) + second_half_actual = sum(1 for idx in actual_indices if idx in second_half_expected) + + # Give more display space to the half with more actual matches + if first_half_actual > second_half_actual: + midpoint = (len(matches) + 1) // 2 # More to first half + else: + midpoint = len(matches) // 2 # More to second half + else: + # No missing indices or only one expected match, split normally + midpoint = len(matches) // 2 + else: + # Even number of matches: split evenly + midpoint = len(matches) // 2 + first_half_matches = matches[:midpoint] if secondHalf: first_half_matches = matches[midpoint:] diff --git a/tournaments/static/tournaments/js/tournament_bracket.js b/tournaments/static/tournaments/js/tournament_bracket.js index 2b75b47..98516ca 100644 --- a/tournaments/static/tournaments/js/tournament_bracket.js +++ b/tournaments/static/tournaments/js/tournament_bracket.js @@ -318,13 +318,23 @@ function renderBracket(options) { parentMatch2 != undefined && parentMatch2.dataset.disabled == "false" ) { - nextMatchDistance = 0; + if (realRoundIndex == 1 && doubleButterflyMode) { + //if missing match in quarterfinals in double butterfly mode + nextMatchDistance = baseDistance; + } else { + nextMatchDistance = 0; + } matchPositions[roundIndex + 1][parentIndex2] = top; } else if ( parentMatch1 != undefined && parentMatch1.dataset.disabled == "false" ) { - nextMatchDistance = 0; + if (realRoundIndex == 1 && doubleButterflyMode) { + //if missing match in quarterfinals in double butterfly mode + nextMatchDistance = baseDistance; + } else { + nextMatchDistance = 0; + } matchPositions[roundIndex + 1][parentIndex1] = top; } else { isOutgoingLineIsDisabled = true;