public static void AddFinalsRaces(this Tournament tournament)
        {
            if (!tournament.Races.All(r => r.IsFinished()) || tournament.Groups.Any(g => g.Name == "Finals"))
            {
                return;
            }
            var finalsCars = new List<Car>();
            var scoutGroup = tournament.Groups.First(g => g.Name == "Scouts");
            var resultsByClass = ResultsByClass(tournament, scoutGroup);
            foreach (var classGroup in resultsByClass)
            {
                var firstCar = GetFirstCar(tournament, classGroup);
                if (firstCar == null)
                {
                    return;
                }
                finalsCars.Add(firstCar.Copy());
            }
            for (int i = 0; i < finalsCars.Count; i++)
            {
                finalsCars[i].Number = i + 1;
            }

            var tournamentBuilder = new TournamentBuilder("finals", "");
            var laneStats = tournament.LaneStats;
            var finalsGroup = new Group {Name = "Finals", Round = "Finals", Cars = finalsCars.ToArray()};
            var raceDef = RaceDefinitionSource.RaceDefinitions(finalsCars.Count, 1, laneStats);
            tournamentBuilder.AddGroup(finalsGroup, raceDef);
            var finalsTournament = tournamentBuilder.Build("Finals");
            tournament.AddGroupsAndRaces(finalsTournament.Groups, finalsTournament.Races);
        }
        private static int BuildTiebreakerRacesForPointLevel(Tournament tournament, string classKey, IEnumerable <CarResult> classGroup, int maxPoints, Group g,
                                                             LaneStat[] laneStats, int byeCounter, string roundName, TournamentBuilder tiebreakerTournamentBuilder, int tiebreakerPlace)
        {
            var carsWithMaxPoints = classGroup.Where(r => r.Points == maxPoints).ToArray();
            var baseGroup         = g.ShowClassStandings ? classKey : g.Name;

            if (carsWithMaxPoints.Count() > 1 && !tournament.Groups.Any(_g => _g.TiebreakGroup == baseGroup && _g.TiebreakerPlace() == tiebreakerPlace))
            {
                int i        = 1;
                var tiedCars =
                    carsWithMaxPoints.Select(
                        c =>
                        new Car
                {
                    Builder = c.Car.Builder,
                    Class   = c.Car.Class,
                    ID      = c.Car.ID,
                    Name    = c.Car.Name,
                    Number  = i++
                }).ToList();
                var raceDef = RaceDefinitionSource.RaceDefinitions(tiedCars.Count(), 1, laneStats);
                while (tiedCars.Count() < 4)
                {
                    byeCounter++;
                    var carId = "BYE" + byeCounter;
                    tiedCars.Add(new Car {
                        Builder = carId, Name = carId, ID = carId, Number = i
                    });
                    i++;
                }
                var ordinal   = tiebreakerPlace == 1 ? "1st" : tiebreakerPlace == 2 ? "2nd" : "3rd";
                var name      = string.Join(" - ", baseGroup.Split('-').First().Trim(), ordinal, roundName);
                var tiedGroup = new Group {
                    Name = name, Cars = tiedCars.ToArray(), Round = roundName, TiebreakGroup = baseGroup
                };
                tiebreakerTournamentBuilder.AddGroup(tiedGroup, raceDef);
            }
            return(byeCounter);
        }
        public static void AddFinalsRaces(this Tournament tournament)
        {
            if (!tournament.Races.All(r => r.IsFinished()) || tournament.Groups.Any(g => g.Name == "Finals"))
            {
                return;
            }
            var finalsCars     = new List <Car>();
            var scoutGroup     = tournament.Groups.First(g => g.Name == "Scouts");
            var resultsByClass = ResultsByClass(tournament, scoutGroup);

            foreach (var classGroup in resultsByClass)
            {
                var firstCar = GetFirstCar(tournament, classGroup);
                if (firstCar == null)
                {
                    return;
                }
                finalsCars.Add(firstCar.Copy());
            }
            for (int i = 0; i < finalsCars.Count; i++)
            {
                finalsCars[i].Number = i + 1;
            }

            var tournamentBuilder = new TournamentBuilder("finals", "");
            var laneStats         = tournament.LaneStats;
            var finalsGroup       = new Group {
                Name = "Finals", Round = "Finals", Cars = finalsCars.ToArray()
            };
            var raceDef = RaceDefinitionSource.RaceDefinitions(finalsCars.Count, 1, laneStats);

            tournamentBuilder.AddGroup(finalsGroup, raceDef);
            var finalsTournament = tournamentBuilder.Build("Finals");

            tournament.AddGroupsAndRaces(finalsTournament.Groups, finalsTournament.Races);
        }
 private static int BuildTiebreakerRacesForPointLevel(Tournament tournament, string classKey, IEnumerable<CarResult> classGroup, int maxPoints, Group g,
     LaneStat[] laneStats, int byeCounter, string roundName, TournamentBuilder tiebreakerTournamentBuilder, int tiebreakerPlace)
 {
     var carsWithMaxPoints = classGroup.Where(r => r.Points == maxPoints).ToArray();
     var baseGroup = g.ShowClassStandings ? classKey : g.Name;
     if (carsWithMaxPoints.Count() > 1 && !tournament.Groups.Any(_g => _g.TiebreakGroup == baseGroup))
     {
         int i = 1;
         var tiedCars =
             carsWithMaxPoints.Select(
                 c =>
                     new Car
                     {
                         Builder = c.Car.Builder,
                         Class = c.Car.Class,
                         ID = c.Car.ID,
                         Name = c.Car.Name,
                         Number = i++
                     }).ToList();
         var raceDef = RaceDefinitionSource.RaceDefinitions(tiedCars.Count(), 1, laneStats);
         while (tiedCars.Count() < 4)
         {
             byeCounter++;
             var carId = "BYE" + byeCounter;
             tiedCars.Add(new Car {Builder = carId, Name = carId, ID = carId, Number = i});
             i++;
         }
         var name = tiebreakerPlace == 1
             ? string.Join("-", baseGroup.Split('-').First(), roundName)
             : string.Join("-", baseGroup.Split('-').First()+":"+tiebreakerPlace, roundName);
         var tiedGroup = new Group {Name = name, Cars = tiedCars.ToArray(), Round = roundName, TiebreakGroup = baseGroup};
         tiebreakerTournamentBuilder.AddGroup(tiedGroup, raceDef);
     }
     return byeCounter;
 }