From 6466d97eca431f45534b187496f38e289d923198 Mon Sep 17 00:00:00 2001 From: sidhdhi canopas Date: Mon, 25 Nov 2024 14:53:12 +0530 Subject: [PATCH 1/4] optimize scheduling logic --- .../ui/flow/profile/profile_view_model.dart | 3 +- .../match_selection/match_scheduler.dart | 443 ++++++++++-------- 2 files changed, 238 insertions(+), 208 deletions(-) diff --git a/khelo/lib/ui/flow/profile/profile_view_model.dart b/khelo/lib/ui/flow/profile/profile_view_model.dart index 4764e373..b7610ba9 100644 --- a/khelo/lib/ui/flow/profile/profile_view_model.dart +++ b/khelo/lib/ui/flow/profile/profile_view_model.dart @@ -86,8 +86,7 @@ class ProfileViewNotifier extends StateNotifier { state = state.copyWith(actionError: null); await _userService.updateUserNotificationSettings( - state.currentUser?.id ?? "INVALID ID", state.enableUserNotification); - + state.currentUser?.id ?? "INVALID ID", !state.enableUserNotification); state = state.copyWith( enableUserNotification: !state.enableUserNotification, actionError: null, diff --git a/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart b/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart index a81541d8..96cb3a86 100644 --- a/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart +++ b/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart @@ -1,5 +1,3 @@ -import 'dart:collection'; - import 'package:collection/collection.dart'; import 'package:data/api/match/match_model.dart'; import 'package:data/api/team/team_model.dart'; @@ -50,11 +48,7 @@ class MatchScheduler { GroupedMatchMap scheduleMatchesByType() { switch (matchType) { case TournamentType.knockOut: - return scheduleKnockOutMatchesWithArguments( - scheduledMatches, - teams, - addInitialRound: true, - ); + return scheduleKnockOutMatches(); case TournamentType.miniRobin: return scheduleMiniRoundRobinMatches(); case TournamentType.boxLeague: @@ -68,62 +62,44 @@ class MatchScheduler { } } - GroupedMatchMap scheduleKnockOutMatchesWithArguments( - GroupedMatchMap matches, - List teams, { - bool addInitialRound = false, - }) { - final List teamPool = List.of(teams); - if (addInitialRound && !matches.containsKey(MatchGroup.round)) { - matches.addAll({ - MatchGroup.round: {1: []} - }); - } + GroupedMatchMap scheduleKnockOutMatches() { final GroupedMatchMap additionalScheduledMatches = - SplayTreeMap>>.from( - matches, (a, b) => a.index.compareTo(b.index)); - final GroupedMatchMap tempScheduledMatches = {}; - while (teamPool.length > 1) { - additionalScheduledMatches.forEach((group, groupNumbers) { - groupNumbers.forEach((number, matches) { - removeAlreadyScheduledTeams(matches, teamPool); - - final teamPairs = createKnockoutTeamPairs(teamPool); - addMatches(matches, teamPairs, group, number); - - teamPool.removeWhere((team) => teamPairs - .any((element) => element.length == 2 && element.contains(team))); - - addWinnerTeamsBackToTeam(matches, teamPool); + Map.from(scheduledMatches); + final List teamPool = List.of(teams); - if (teamPool.length <= 1) { - return; - } - final expectedQualifier = matches.length; - if (expectedQualifier > 8) { - addRoundToGroupMap(tempScheduledMatches, number); - } else if (expectedQualifier > 4) { - addNewGroupToGroupMap( - tempScheduledMatches, MatchGroup.quarterfinal); - } else if (expectedQualifier > 2) { - addNewGroupToGroupMap(tempScheduledMatches, MatchGroup.semifinal); - } else if (expectedQualifier == 2) { - addNewGroupToGroupMap(tempScheduledMatches, MatchGroup.finals); - } - }); - }); + var currentGroup = MatchGroup.round; + var currentRound = 1; - additionalScheduledMatches.addAll(tempScheduledMatches); - tempScheduledMatches.clear(); + while (teamPool.length > 1) { + final group = + additionalScheduledMatches.putIfAbsent(currentGroup, () => {1: []}); + final matches = group[currentRound] ?? []; + final expectedQualifier = handleSingleKnockoutPhase( + matches, teamPool, currentGroup, currentRound); + if (expectedQualifier > 8) { + currentRound++; + } else if (expectedQualifier > 4) { + currentRound = 1; + currentGroup = MatchGroup.quarterfinal; + } else if (expectedQualifier > 2) { + currentRound = 1; + currentGroup = MatchGroup.semifinal; + } else if (expectedQualifier == 2) { + currentRound = 1; + currentGroup = MatchGroup.finals; + } } return additionalScheduledMatches; } GroupedMatchMap scheduleMiniRoundRobinMatches() { - final GroupedMatchMap additionalScheduledMatches = scheduledMatches; + final GroupedMatchMap additionalScheduledMatches = + Map.from(scheduledMatches); final List teamPool = List.of(teams); + var currentGroup = MatchGroup.round; + var currentRound = 1; final int totalTeams = teamPool.length; int matchesPerTeam; @@ -135,173 +111,177 @@ class MatchScheduler { matchesPerTeam = 3; } - final rounds = scheduledMatches[MatchGroup.round] ?? {1: []}; - final Map> tempRound = {}; - - List> teamPoints = []; while (teamPool.length > 1) { - rounds.forEach((number, matches) { - removeTeamsThatReachedLimit(matches, teamPool, matchesPerTeam); - - final teamPairs = createRoundRobinTeamPairs( - teamPool, - matchesPerTeam, - matches - .map((element) => element.teams.map((e) => e.team).toList()) - .toList()); - addMatches(matches, teamPairs, MatchGroup.round, number); - - teamPool.removeWhere( - (team) => teamPairs.any((pair) => pair.contains(team))); - }); - - tempRound.forEach((key, value) { - rounds.putIfAbsent(key, () => value); - }); - tempRound.clear(); - } - rounds.forEach((key, matches) { - final teams = - matches.expand((e) => e.teams.map((e) => e.team)).toSet().toList(); + final group = + additionalScheduledMatches.putIfAbsent(currentGroup, () => {1: []}); + final matches = group[currentRound] ?? []; + var expectedQualifiers = 0; - final points = calculateTeamPoints(matches, teams); - teamPoints.add(points); - }); + if (currentGroup == MatchGroup.round) { + handleSingleMiniRobinMatches( + matches, teamPool, matchesPerTeam, currentGroup, currentRound); + group[currentRound] = matches; - teamPoints.sort((a, b) { - if (a.first.points != b.first.points) { - return b.first.points.compareTo(a.first.points); + expectedQualifiers = teams.length; + final List> teamPoints = []; + + additionalScheduledMatches[MatchGroup.round]!.forEach((key, matches) { + final teams = matches + .expand((e) => e.teams.map((e) => e.team)) + .toSet() + .toList(); + + final List points = calculateTeamPoints(matches, teams); + teamPoints.add(points); + }); + + teamPoints.sort((a, b) { + if (a.firstOrNull?.points != b.firstOrNull?.points) { + return (b.firstOrNull?.points ?? 0) + .compareTo(a.firstOrNull?.points ?? 0); + } else { + return (b.firstOrNull?.runRate ?? 0) + .compareTo(a.firstOrNull?.runRate ?? 0); + } + }); + + final List teamsToAdd; + + if (expectedQualifiers > 4) { + teamsToAdd = teamPoints.first.take(8).map((e) => e.team).toList(); + } else if (expectedQualifiers > 2) { + teamsToAdd = teamPoints.first.take(4).map((e) => e.team).toList(); + } else if (expectedQualifiers == 2) { + teamsToAdd = teamPoints.first.take(2).map((e) => e.team).toList(); + } else { + teamsToAdd = []; + } + + teamPool.addAll(teamsToAdd); } else { - return b.first.runRate.compareTo(a.first.runRate); + expectedQualifiers = handleSingleKnockoutPhase( + matches, + teamPool, + currentGroup, + currentRound, + ); + group[currentRound] = matches; } - }); - final expectedQualifier = teams.length; - final List teamsToAdd; - if (expectedQualifier > 4) { - addNewGroupToGroupMap( - additionalScheduledMatches, MatchGroup.quarterfinal); - teamsToAdd = teamPoints.first.take(8).map((e) => e.team).toList(); - } else if (expectedQualifier > 2) { - addNewGroupToGroupMap(additionalScheduledMatches, MatchGroup.semifinal); - teamsToAdd = teamPoints.first.take(4).map((e) => e.team).toList(); - } else if (expectedQualifier == 2) { - addNewGroupToGroupMap(additionalScheduledMatches, MatchGroup.finals); - teamsToAdd = teamPoints.first.take(2).map((e) => e.team).toList(); - } else { - teamsToAdd = []; + if (expectedQualifiers > 4) { + currentRound = 1; + currentGroup = MatchGroup.quarterfinal; + } else if (expectedQualifiers > 2) { + currentRound = 1; + currentGroup = MatchGroup.semifinal; + } else if (expectedQualifiers == 2) { + currentRound = 1; + currentGroup = MatchGroup.finals; + } } - teamPool.addAll(teamsToAdd); - final copyMatches = additionalScheduledMatches; - copyMatches.remove(MatchGroup.round); - final knockOutPhaseMatches = - scheduleKnockOutMatchesWithArguments(copyMatches, teamPool); - - additionalScheduledMatches - .addAll({MatchGroup.round: rounds, ...knockOutPhaseMatches}); - return additionalScheduledMatches; } GroupedMatchMap scheduleBoxLeagueMatches() { - final GroupedMatchMap additionalScheduledMatches = scheduledMatches; - final teamPool = teams; - final int boxSize = 3; + final GroupedMatchMap additionalScheduledMatches = + Map.from(scheduledMatches); + final List teamPool = List.of(teams); - final rounds = scheduledMatches[MatchGroup.round] ?? {1: []}; - final Map> tempRound = {}; + var currentGroup = MatchGroup.round; + var currentRound = 1; + final int boxSize = 3; - List> teamPoints = []; while (teamPool.length > 1) { - rounds.forEach((number, matches) { - final teams = - matches.expand((e) => e.teams.map((e) => e.team)).toSet().toList(); - - int remainingTeam = teamPool.length % boxSize; - removeAlreadyScheduledTeams(matches, teamPool); - if (teams.length < boxSize || remainingTeam > 0) { - teams.addAll(teamPool.take(boxSize - teams.length + 1)); - } + final group = + additionalScheduledMatches.putIfAbsent(currentGroup, () => {1: []}); + final matches = group[currentRound] ?? []; + var expectedQualifiers = 0; - final teamPairs = createRoundRobinTeamPairs( - teams, - teams.length - 1, - matches - .map((element) => element.teams.map((e) => e.team).toList()) - .toList()); + if (currentGroup == MatchGroup.round) { + handleSingleBoxLeague( + additionalScheduledMatches[MatchGroup.round]! + .values + .expand((element) => element) + .toList(), + matches, + teamPool, + currentGroup, + currentRound, + boxSize, + ); + group[currentRound] = matches; + + if (teamPool.length <= 1) { + final List> teamPoints = []; + additionalScheduledMatches[MatchGroup.round]!.forEach((key, matches) { + final teams = matches + .expand((e) => e.teams.map((e) => e.team)) + .toSet() + .toList(); + + final List points = calculateTeamPoints(matches, teams); + teamPoints.add(points); + }); + + teamPoints.sort((a, b) { + if (a.firstOrNull?.points != b.firstOrNull?.points) { + return (b.firstOrNull?.points ?? 0) + .compareTo(a.firstOrNull?.points ?? 0); + } else { + return (b.firstOrNull?.runRate ?? 0) + .compareTo(a.firstOrNull?.runRate ?? 0); + } + }); + + int teamsTobeAdded = + additionalScheduledMatches[MatchGroup.round]?.length ?? 0; + if (teamsTobeAdded > 4) { + expectedQualifiers = 8; + } else if (teamsTobeAdded > 2) { + expectedQualifiers = 4; + } else if (teamsTobeAdded == 2) { + expectedQualifiers = 2; + } - addMatches(matches, teamPairs, MatchGroup.round, number); + int round = 0; + while (teamPool.length < expectedQualifiers) { + final List teamsToAdd = teamPoints + .map((e) => e.elementAtOrNull(round)?.team) + .whereType() + .toList(); + if (teamsToAdd.isEmpty) break; + final remainingSlots = expectedQualifiers - teamPool.length; - teamPool.removeWhere((team) => - teamPairs.any((pair) => pair.length == 2 && pair.contains(team))); + teamPool.addAll(teamsToAdd.take(remainingSlots)); - if (teamPool.length > 1 && !rounds.containsKey(number + 1)) { - tempRound[number + 1] = []; + round++; + } + } else { + currentRound++; } - }); - - tempRound.forEach((key, value) { - rounds.putIfAbsent(key, () => value); - }); - tempRound.clear(); - } - rounds.forEach((key, matches) { - final teams = - matches.expand((e) => e.teams.map((e) => e.team)).toSet().toList(); - - final points = calculateTeamPoints(matches, teams); - teamPoints.add(points); - }); - - teamPoints.sort((a, b) { - if (a.first.points != b.first.points) { - return b.first.points.compareTo(a.first.points); } else { - return b.first.runRate.compareTo(a.first.runRate); + expectedQualifiers = handleSingleKnockoutPhase( + matches, + teamPool, + currentGroup, + currentRound, + ); + group[currentRound] = matches; } - }); - - final expectedQualifier = - additionalScheduledMatches[MatchGroup.round]?.length ?? 0; - int pickTeamNumber = 0; - if (expectedQualifier > 4) { - addNewGroupToGroupMap( - additionalScheduledMatches, MatchGroup.quarterfinal); - pickTeamNumber = 8; - } else if (expectedQualifier > 2) { - addNewGroupToGroupMap(additionalScheduledMatches, MatchGroup.semifinal); - pickTeamNumber = 4; - } else if (expectedQualifier == 2) { - addNewGroupToGroupMap(additionalScheduledMatches, MatchGroup.finals); - pickTeamNumber = 2; - } - - int round = 0; - - while (teamPool.length < pickTeamNumber) { - final teamsToAdd = teamPoints - .map((e) => e.elementAtOrNull(round)?.team) - .whereType() - .toList(); - - if (teamsToAdd.isEmpty) break; - - final remainingSlots = pickTeamNumber - teamPool.length; - - teamPool.addAll(teamsToAdd.take(remainingSlots)); - round++; + if (expectedQualifiers > 4) { + currentRound = 1; + currentGroup = MatchGroup.quarterfinal; + } else if (expectedQualifiers > 2) { + currentRound = 1; + currentGroup = MatchGroup.semifinal; + } else if (expectedQualifiers == 2) { + currentRound = 1; + currentGroup = MatchGroup.finals; + } } - final copyMatches = additionalScheduledMatches; - copyMatches.remove(MatchGroup.round); - final knockOutPhaseMatches = - scheduleKnockOutMatchesWithArguments(copyMatches, teamPool); - - additionalScheduledMatches - .addAll({MatchGroup.round: rounds, ...knockOutPhaseMatches}); - return additionalScheduledMatches; } @@ -574,18 +554,6 @@ class MatchScheduler { teams.addAll(winners); } - void addRoundToGroupMap( - GroupedMatchMap additionalScheduledMatches, int currentRoundNumber) { - if (!additionalScheduledMatches.containsKey(MatchGroup.round)) { - return; - } - if (additionalScheduledMatches[MatchGroup.round]! - .containsKey(currentRoundNumber + 1)) { - return; - } - additionalScheduledMatches[MatchGroup.round]![currentRoundNumber + 1] = []; - } - void addNewGroupToGroupMap( GroupedMatchMap additionalScheduledMatches, MatchGroup newGroup) { if (additionalScheduledMatches.containsKey(newGroup)) { @@ -666,6 +634,69 @@ class MatchScheduler { return allPairs.length; } + void handleSingleMiniRobinMatches( + List matches, + List teamPool, + int matchesPerTeam, + MatchGroup group, + int number) { + removeTeamsThatReachedLimit(matches, teamPool, matchesPerTeam); + + final teamPairs = createRoundRobinTeamPairs( + teamPool, + matchesPerTeam, + matches + .map((element) => element.teams.map((e) => e.team).toList()) + .toList()); + addMatches(matches, teamPairs, group, number); + + teamPool + .removeWhere((team) => teamPairs.any((pair) => pair.contains(team))); + } + + void handleSingleBoxLeague( + List allMatches, + List matches, + List teamPool, + MatchGroup group, + int number, + int boxSize, + ) { + final teams = + matches.expand((e) => e.teams.map((e) => e.team)).toSet().toList(); + + completeTeamSet(allMatches, teamPool, teams, boxSize); + + final teamPairs = createRoundRobinTeamPairs( + teams, + teams.length - 1, + matches + .map((element) => element.teams.map((e) => e.team).toList()) + .toList()); + + addMatches(matches, teamPairs, MatchGroup.round, number); + + teamPool.removeWhere((team) => + teamPairs.any((pair) => pair.length == 2 && pair.contains(team))); + } + + void completeTeamSet( + List allMatches, + List sourceTeams, + List destinationTeams, + int boxSize, + ) { + final teams = sourceTeams.toList(); + int remainingTeam = sourceTeams.length % boxSize; + teams.removeWhere((srcTeam) => allMatches + .any((match) => match.teams.any((team) => team.team_id == srcTeam.id))); + if (destinationTeams.length < boxSize || remainingTeam > 0) { + final pick = + boxSize - destinationTeams.length + (remainingTeam > 0 ? 1 : 0); + destinationTeams.addAll(teams.take(pick)); + } + } + List> getExistingTeamPairs(List matches) { final List> pairs = []; for (var match in matches) { From a7f75d3f984ed276b8b6429e910860c9ad6beb73 Mon Sep 17 00:00:00 2001 From: sidhdhi canopas Date: Mon, 25 Nov 2024 15:02:22 +0530 Subject: [PATCH 2/4] improve null check --- khelo/lib/ui/flow/profile/profile_view_model.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/khelo/lib/ui/flow/profile/profile_view_model.dart b/khelo/lib/ui/flow/profile/profile_view_model.dart index b7610ba9..f308ed3e 100644 --- a/khelo/lib/ui/flow/profile/profile_view_model.dart +++ b/khelo/lib/ui/flow/profile/profile_view_model.dart @@ -82,11 +82,14 @@ class ProfileViewNotifier extends StateNotifier { void onToggleUserNotificationChange() async { try { - if (state.currentUser == null) return; + final userId = state.currentUser?.id; + if (userId == null) return; state = state.copyWith(actionError: null); await _userService.updateUserNotificationSettings( - state.currentUser?.id ?? "INVALID ID", !state.enableUserNotification); + userId, + !state.enableUserNotification, + ); state = state.copyWith( enableUserNotification: !state.enableUserNotification, actionError: null, From df18a8ba2cd753a568ebe864b41914d74024c1f4 Mon Sep 17 00:00:00 2001 From: sidhdhi canopas Date: Tue, 26 Nov 2024 14:42:19 +0530 Subject: [PATCH 3/4] add datatypes --- .../match_selection/match_scheduler.dart | 90 +++++++++++-------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart b/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart index 96cb3a86..e086d281 100644 --- a/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart +++ b/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart @@ -67,8 +67,8 @@ class MatchScheduler { Map.from(scheduledMatches); final List teamPool = List.of(teams); - var currentGroup = MatchGroup.round; - var currentRound = 1; + MatchGroup currentGroup = MatchGroup.round; + int currentRound = 1; while (teamPool.length > 1) { final group = @@ -98,8 +98,8 @@ class MatchScheduler { Map.from(scheduledMatches); final List teamPool = List.of(teams); - var currentGroup = MatchGroup.round; - var currentRound = 1; + MatchGroup currentGroup = MatchGroup.round; + int currentRound = 1; final int totalTeams = teamPool.length; int matchesPerTeam; @@ -115,7 +115,7 @@ class MatchScheduler { final group = additionalScheduledMatches.putIfAbsent(currentGroup, () => {1: []}); final matches = group[currentRound] ?? []; - var expectedQualifiers = 0; + int expectedQualifiers = 0; if (currentGroup == MatchGroup.round) { handleSingleMiniRobinMatches( @@ -188,15 +188,15 @@ class MatchScheduler { Map.from(scheduledMatches); final List teamPool = List.of(teams); - var currentGroup = MatchGroup.round; - var currentRound = 1; + MatchGroup currentGroup = MatchGroup.round; + int currentRound = 1; final int boxSize = 3; while (teamPool.length > 1) { final group = additionalScheduledMatches.putIfAbsent(currentGroup, () => {1: []}); final matches = group[currentRound] ?? []; - var expectedQualifiers = 0; + int expectedQualifiers = 0; if (currentGroup == MatchGroup.round) { handleSingleBoxLeague( @@ -325,14 +325,14 @@ class MatchScheduler { Map.from(scheduledMatches); final List teamPool = List.of(teams); - var currentGroup = MatchGroup.round; - var currentRound = 1; + MatchGroup currentGroup = MatchGroup.round; + int currentRound = 1; while (teamPool.length > 1) { final group = additionalScheduledMatches.putIfAbsent(currentGroup, () => {1: []}); final matches = group[currentRound] ?? []; - var expectedQualifiers = 0; + int expectedQualifiers = 0; if (currentGroup == MatchGroup.round) { expectedQualifiers = handleSingleBestOfThreePhase( @@ -378,18 +378,18 @@ class MatchScheduler { )) .toList(); - for (var match in matches) { + for (final match in matches) { if (match.matchResult == null) { continue; } MatchResult result = match.matchResult!; - var team1Data = match.teams.first; - var team2Data = match.teams.last; + MatchTeamModel team1Data = match.teams.first; + MatchTeamModel team2Data = match.teams.last; - var team1Points = + TeamPoints team1Points = teamPoints.firstWhere((team) => team.team.id == team1Data.team_id); - var team2Points = + TeamPoints team2Points = teamPoints.firstWhere((team) => team.team.id == team2Data.team_id); team1Points.runs += team1Data.run; @@ -402,13 +402,13 @@ class MatchScheduler { switch (result.winType) { case WinnerByType.run: - var winningTeamPoints = + TeamPoints winningTeamPoints = teamPoints.firstWhere((team) => team.team.id == result.teamId); winningTeamPoints.points += 2; break; case WinnerByType.wicket: - var winningTeamPoints = + TeamPoints winningTeamPoints = teamPoints.firstWhere((team) => team.team.id == result.teamId); winningTeamPoints.points += 2; break; @@ -420,7 +420,7 @@ class MatchScheduler { } } - for (var team in teamPoints) { + for (final team in teamPoints) { if (team.oversFaced > 0) { team.runRate = team.runs / team.oversFaced; } @@ -442,11 +442,11 @@ class MatchScheduler { final List> teamPairs = []; // Initialize match count based on the existing scheduled matches - final Map matchCount = {for (var team in teamPool) team: 0}; + final Map matchCount = {for (final team in teamPool) team: 0}; // Update match count based on already scheduled matches - for (var match in scheduledMatches) { - for (var team in match) { + for (final match in scheduledMatches) { + for (final team in match) { if (teamPool.contains(team)) { matchCount[team] = (matchCount[team] ?? 0) + 1; } @@ -490,6 +490,11 @@ class MatchScheduler { int groupNumber, ) { for (final pair in teamPairs) { + if ((group == MatchGroup.quarterfinal && existingMatches.length >= 4) || + (group == MatchGroup.semifinal && existingMatches.length >= 2) || + (group == MatchGroup.finals && existingMatches.isNotEmpty)) { + return; + } if (pair.length == 2) { existingMatches.add(MatchModel( id: '', @@ -606,14 +611,27 @@ class MatchScheduler { removeAlreadyScheduledTeams(matches, teamPool); final teamPairs = createKnockoutTeamPairs(teamPool); - addMatches(matches, teamPairs, group, number); + + if ((group == MatchGroup.quarterfinal && matches.length < 4) || + (group == MatchGroup.semifinal && matches.length < 2) || + (group == MatchGroup.finals && matches.isEmpty)) { + addMatches(matches, teamPairs, group, number); + } teamPool.removeWhere((team) => teamPairs .any((element) => element.length == 2 && element.contains(team))); - - addWinnerTeamsBackToTeam(matches, teamPool); - - return matches.length; + if (group != MatchGroup.finals) { + addWinnerTeamsBackToTeam(matches, teamPool); + } + if (group == MatchGroup.quarterfinal && matches.length >= 4) { + return 4; + } else if (group == MatchGroup.semifinal && matches.length >= 2) { + return 2; + } else if (group == MatchGroup.finals && matches.isNotEmpty) { + return 1; + } else { + return matches.length; + } } int handleSingleBestOfThreePhase( @@ -664,7 +682,6 @@ class MatchScheduler { ) { final teams = matches.expand((e) => e.teams.map((e) => e.team)).toSet().toList(); - completeTeamSet(allMatches, teamPool, teams, boxSize); final teamPairs = createRoundRobinTeamPairs( @@ -673,8 +690,7 @@ class MatchScheduler { matches .map((element) => element.teams.map((e) => e.team).toList()) .toList()); - - addMatches(matches, teamPairs, MatchGroup.round, number); + addMatches(matches, teamPairs, group, number); teamPool.removeWhere((team) => teamPairs.any((pair) => pair.length == 2 && pair.contains(team))); @@ -699,7 +715,7 @@ class MatchScheduler { List> getExistingTeamPairs(List matches) { final List> pairs = []; - for (var match in matches) { + for (final match in matches) { final pair = match.teams.map((e) => e.team).toList(); if (!pairs.map((e) => e.map((e) => e.id)).any((element) => element.contains(pair.first.id) && element.contains(pair.last.id))) { @@ -717,13 +733,11 @@ class MatchScheduler { int number, ) { final List winnerTeams = []; - for (var p in pair) { + for (final p in pair) { final matchesForPair = groupMatches - .where( - (element) => - element.team_ids.contains(p.first.id) && - element.team_ids.contains(p.last.id), - ) + .where((element) => + element.team_ids.contains(p.first.id) && + element.team_ids.contains(p.last.id)) .toList(); if (matchesForPair.isEmpty) { addMatches(groupMatches, [p], group, number); @@ -756,7 +770,7 @@ class MatchScheduler { String teamTwo, ) { Map winner = {teamOne: 0, teamTwo: 0}; - for (var element in matches) { + for (final element in matches) { final result = element.matchResult; if (result == null) continue; From c112ccef455164526aec7a9c5a193f92f2281b6c Mon Sep 17 00:00:00 2001 From: sidhdhi canopas Date: Tue, 26 Nov 2024 15:25:55 +0530 Subject: [PATCH 4/4] fix infinite error in boxLeague --- .../ui/flow/tournament/match_selection/match_scheduler.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart b/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart index e086d281..a24e5f4b 100644 --- a/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart +++ b/khelo/lib/ui/flow/tournament/match_selection/match_scheduler.dart @@ -442,7 +442,9 @@ class MatchScheduler { final List> teamPairs = []; // Initialize match count based on the existing scheduled matches - final Map matchCount = {for (final team in teamPool) team: 0}; + final Map matchCount = { + for (final team in teamPool) team: 0 + }; // Update match count based on already scheduled matches for (final match in scheduledMatches) { @@ -683,6 +685,7 @@ class MatchScheduler { final teams = matches.expand((e) => e.teams.map((e) => e.team)).toSet().toList(); completeTeamSet(allMatches, teamPool, teams, boxSize); + teamPool.removeWhere((element) => teams.contains(element)); final teamPairs = createRoundRobinTeamPairs( teams,