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;