public MatchInfo[] ProvisionMatches(int playersCount, int qualifyingPlayersCount, int actualPlayersCount) { var engine = new KnockoutCalculationEngine(); var output = engine.Calculate(playersCount, qualifyingPlayersCount, actualPlayersCount); var matches = new List <MatchInfo>(output.MainDrawMatchesCount + output.QualifyingDrawMatchesCount); matches.AddRange(CreateMainDrawMatches(output.MainDrawMatchesCount, output.ActualMainDrawPlayers, output.TotalMainDrawPlayers, output.ActualQualifyingPlayers)); if (output.TotalQualifyingPlayers > 0) { matches.AddRange(CreateQualifyingMatches(output.QualifyingDrawMatchesCount, output.TotalQualifyingPlayers, output.ActualQualifyingPlayers)); } return(matches.ToArray()); }
public void AddPlayersToCompetition(int competitionId, AddCompetitionPlayerInfo[] players) { var competitionsRepository = ServiceProvider.Get <ICompetitionRepository>(); var competitionTypesRepository = ServiceProvider.Get <ICompetitionTypeRepository>(); var competition = competitionsRepository.GetCompetitionDetails(competitionId); if (competition.IsNull()) { throw new ArgumentException("Competition '{0}' could not be found.".ParseTemplate(competitionId)); } var competitionType = competitionTypesRepository.Get(competition.Type.Id); if (competition.Players.Length == competitionType.PlayersCount) { throw new ArgumentException("Competition '{0}' is already full.".ParseTemplate(competitionId)); } var qualifyingPlayersCount = players.Count(p => p.Section == CompetitionSection.Qualifying); if (qualifyingPlayersCount > 0) { if (competitionType.QualifyingPlayersCount == 0) { throw new ArgumentException( "Competition '{0}' does not have qualifying section.".ParseTemplate(competitionId)); } if (qualifyingPlayersCount > competitionType.QualifyingPlayersCount) { throw new ArgumentException( "Competition '{0}' has only {1} players in qualifying section but more players designated to that section.".ParseTemplate(competitionId, competitionType.QualifyingPlayersCount)); } var competitionQualifyingPlayersCount = competition.Players.Count(p => p.Section == CompetitionSection.Qualifying); if (competitionQualifyingPlayersCount == competitionType.QualifyingPlayersCount) { throw new ArgumentException( "Competition '{0}' qualifying section is already full.".ParseTemplate(competitionId)); } } var competitionPlayers = new List <PlayerInCompetition>(); for (var i = 0; i < players.Length; i++) { var player = players[i]; var rank = competitionType.RankPlayer(player.Player); var section = player.Section ?? CompetitionSection.Final; var playerInCompetition = new PlayerInCompetition() { PlayerId = player.Player.Id, Rank = rank, Source = player.Source, Section = section }; competitionPlayers.Add(playerInCompetition); } var engine = new KnockoutCalculationEngine(); var output = engine.Calculate(competitionType.PlayersCount, competitionType.QualifyingToFinalPlayersCount, players.Length); var finalPlayersCount = output.ActualMainDrawPlayers; var playersToTake = players.Length - finalPlayersCount;// Math.Min(players.Length - finalPlayersCount, competitionType.QualifyingPlayersCount); if (playersToTake > 0) { var qualifyingPlayers = competitionPlayers.OrderByDescending(p => p.Rank).Take(playersToTake); qualifyingPlayers.ForEach(cp => cp.Section = CompetitionSection.Qualifying); } competitionsRepository.AddPlayersToCompetition(competitionId, competitionPlayers.ToArray()); }
public UpdatePlayerPositionInfo[] PositionPlayers(CompetitionDetails details, CompetitionSection section) { var helper = new KnockoutMatchProvisioningEngineHelper(); var engine = new KnockoutCalculationEngine(); var output = engine.Calculate(details.Type.PlayersCount, details.Type.QualifyingToFinalPlayersCount, details.Players.Length); var sectionCodes = section == CompetitionSection.Final ? helper.GenerateMainDrawCodesQueue(output.TotalMainDrawPlayers, output.ActualMainDrawPlayers, details.Type.QualifyingToFinalPlayersCount) : helper.GenerateQualifyingDrawCodes(output.TotalQualifyingPlayers, output.ActualQualifyingPlayers); var sectionPlayers = details.Players.Where(p => p.Section == section); var items = new List <UpdatePlayerPositionInfo>(); if (sectionCodes.Count > 0 && sectionPlayers.Any()) { var map = new Dictionary <string, int>(); foreach (var competitionPlayer in sectionPlayers) { map[sectionCodes.Dequeue()] = competitionPlayer.Id; } var sectionMatches = details.Matches.Where(m => m.Section == section); foreach ( var match in sectionMatches.Where(m => m.Player1Code.NotNullOrEmpty() || m.Player2Code.NotNullOrEmpty()) ) { int playerId; if (match.Player1Code.NotNullOrEmpty()) { if (map.TryGetValue(match.Player1Code, out playerId)) { items.Add(new UpdatePlayerPositionInfo() { MatchId = match.Id, PlayerId = playerId, Position = 0 }); } } if (match.Player2Code.NotNullOrEmpty()) { if (map.TryGetValue(match.Player2Code, out playerId)) { items.Add(new UpdatePlayerPositionInfo() { MatchId = match.Id, PlayerId = playerId, Position = 1 }); } } } } return(items.ToArray()); if (details.Type.QualifyingPlayersCount > 0 && section == CompetitionSection.Qualifying) { items.AddRange(this.GetQualifyingPlayersPositions(details)); } if (section == CompetitionSection.Final) { items.AddRange(this.GetFinalPlayersPositions(details)); } return((from item in items where item.IsNotNull <UpdatePlayerPositionInfo>() select item).ToArray <UpdatePlayerPositionInfo>()); }