public Round StartRoundOrGetExisting(int userId)
        {
            GameEntity  gameEntity  = StartNewGameOrGetExisting(userId);
            RoundEntity roundEntity = _roundRepository.GetCurrentOpenRound(gameEntity.Id);

            if (null != roundEntity)
            {
                // Unfinished round
                return(RoundEntityFactory.Create(roundEntity, ROUNDS_PER_GAME, RoundsPlayedInGame(gameEntity.Id)));
            }
            roundEntity = RoundEntityFactory.Create(gameEntity.Id);

            // Determine the correct one
            var randomImages = _imageRepository.GetRandomImages(IMAGES_PER_ROUND, _userRepository.Get(userId).FullName);
            int indexOfCorrectImageInList = (new Random()).Next(IMAGES_PER_ROUND);
            var correctImage = randomImages.ElementAt(indexOfCorrectImageInList);

            Round round = RoundFactory.Create(new List <Image>(), RoundsPlayedInGame(gameEntity.Id), ROUNDS_PER_GAME, correctImage.Name);

            roundEntity.CorrectImageId = correctImage.Id;
            _roundRepository.Create(roundEntity);

            foreach (ImageEntity imageEntity in randomImages)
            {
                ImageInRoundEntity imageInRoundEntity = ImageInRoundEntityFactory.Create(imageEntity.Id, roundEntity.Id);
                _imageInRoundRepository.Create(imageInRoundEntity);
                round.Images.Add(ImageFactory.Create(imageEntity.Url, imageEntity.Id));
            }

            return(round);
        }
        public RoundInfo GetLatestRoundInfo(int userId)
        {//TODO optimize
            GameEntity  lastGame  = _gameRepository.GetLatestGameForUser(userId);
            RoundEntity lastRound = _roundRepository.GetAll().Where(x => x.GameId == lastGame.Id).OrderByDescending(x => x.Id).FirstOrDefault();

            return(GetRoundInfo(lastRound.Id));
        }
Exemplo n.º 3
0
 private void DisplayRoundData(RoundEntity roundResult, int roundNumber)
 {
     boxResults.Text += $"Round {roundNumber}\r\n";
     boxResults.Text += $"Round Type: {roundResult.RoundType}\r\n";
     boxResults.Text += $"Qualified: {roundResult.Qualified}\r\n";
     boxResults.Text += $"Kudos Earned: {roundResult.Kudos}\r\n";
     boxResults.Text += $"Badge Earned: {roundResult.Badge}\r\n";
     boxResults.Text += $"\r\n";
 }
Exemplo n.º 4
0
        public static Round Create(RoundEntity roundEntity, int totalRounds, int amountOfRoundsPlayed)
        {
            Round round = new Round
            {
                Name                 = roundEntity.CorrectImage.Name,
                TotalRounds          = totalRounds,
                AmountOfRoundsPlayed = amountOfRoundsPlayed,
                Images               = roundEntity.ImagesInRound.Select(ImageFactory.Create).ToList()
            };

            return(round);
        }
Exemplo n.º 5
0
        public virtual RoundEntity GetRoundWithLegs(long roundId)
        {
            var            round = new RoundEntity(roundId);
            IPrefetchPath2 prefetchPathRoundLegs = new PrefetchPath2(EntityType.RoundEntity);

            prefetchPathRoundLegs.Add(RoundEntity.PrefetchPathRoundLegs);

            using var da = _dbContext.GetNewAdapter();
            da.FetchEntity(round, prefetchPathRoundLegs);
            da.CloseConnection();
            return(round);
        }
Exemplo n.º 6
0
        public virtual void SetRoundCompleted(RoundEntity round)
        {
            if (!new MatchRepository(_appDb.DbContext).AllMatchesCompleted(round))
            {
                throw new ArgumentException($"Round {round.Id} has uncompleted matches.");
            }

            using var da = _appDb.DbContext.GetNewAdapter();
            da.FetchEntity(round);
            round.IsComplete = true;
            round.ModifiedOn = DateTime.Now;
            da.SaveEntity(round);
            da.CloseConnection();
        }
        public bool AnswerRound(int answerImageId, int userId)
        {
            GameEntity currentGameForPlayer = _gameRepository.GetLatestGameForUser(userId);

            // id should be replaced with start date
            RoundEntity currentRound = _roundRepository.GetCurrentOpenRound(currentGameForPlayer.Id);

            ImageEntity answerImage = _imageRepository.Get(answerImageId);

            currentRound.GuessedImageId   = answerImage.Id;
            currentGameForPlayer.Duration = DateTime.Now - currentGameForPlayer.StartDate;

            _gameRepository.Update(currentGameForPlayer);
            _roundRepository.Update(currentRound);

            return(currentRound.GuessedImageId == currentRound.CorrectImageId);
        }
Exemplo n.º 8
0
        public virtual EntityCollection <MatchEntity> GetMatches(RoundEntity round)
        {
            IRelationPredicateBucket bucket      = new RelationPredicateBucket();
            IPredicateExpression     roundFilter =
                new PredicateExpression(new FieldCompareRangePredicate(MatchFields.RoundId, null, false,
                                                                       new[] { round.Id }));

            bucket.PredicateExpression.AddWithAnd(roundFilter);

            var matches = new EntityCollection <MatchEntity>();

            using var da = _dbContext.GetNewAdapter();
            da.FetchEntityCollection(matches, bucket);
            da.CloseConnection();

            return(matches);
        }
Exemplo n.º 9
0
        public EnterResultViewModel(TournamentEntity tournament, RoundEntity round,
                                    MatchEntity match, MatchRuleEntity matchRule, IList <TeamInRoundEntity> teamInRound,
                                    Axuno.Tools.DateAndTime.TimeZoneConverter timeZoneConverter)
        {
            Tournament = tournament ?? throw new ArgumentNullException(nameof(tournament));
            Round      = round ?? throw new ArgumentNullException(nameof(round));
            Match      = match ?? throw new ArgumentNullException(nameof(match));
            Opponent   = new Opponent(
                teamInRound.FirstOrDefault(o => o.TeamId == match.HomeTeamId)?.TeamNameForRound ?? throw new ArgumentNullException(nameof(teamInRound)),
                teamInRound.FirstOrDefault(o => o.TeamId == match.GuestTeamId)?.TeamNameForRound ?? throw new ArgumentNullException(nameof(teamInRound)));;
            TimeZoneConverter = timeZoneConverter ?? throw new ArgumentNullException(nameof(timeZoneConverter));

            _localizer = CreateModelStringLocalizer();

            _maxNumberOfSets = matchRule.MaxNumOfSets();
            MapEntityToFormFields();
        }
        public RoundInfo GetRoundInfo(int roundId)
        {//TODO optimize
            RoundInfo roundInfo = new RoundInfo();

            RoundEntity roundEntity = _roundRepository.Get(roundId);
            IEnumerable <ImageInRoundEntity> imageInRoundEntity = _imageInRoundRepository.GetAll().Where(x => x.RoundId == roundId);

            roundInfo.GameId         = roundEntity.GameId;
            roundInfo.CorrectImageId = roundEntity.CorrectImageId;
            roundInfo.GuessedImageId = roundEntity.GuessedImageId.Value;
            roundInfo.Name           = _imageRepository.Get(roundEntity.CorrectImageId).Name;
            roundInfo.Images         = imageInRoundEntity.Select(x => new Image {
                Id = x.ImageId, Url = _imageRepository.Get(x.ImageId).Url
            }).ToList();
            roundInfo.AmountOfRoundsPlayed = RoundsPlayedInGame(roundEntity.GameId);
            roundInfo.TotalRounds          = ROUNDS_PER_GAME;

            return(roundInfo);
        }
Exemplo n.º 11
0
        public static List <EpisodeEntity> GetEpisodesFromLog()
        {
            List <EpisodeEntity> allEpisodes = new List <EpisodeEntity>();
            var playerLogData         = ReadLogData();
            var episodeStartingPoints = playerLogData.FindAll(data => data.Contains("[CompletedEpisodeDto]"));

            foreach (string episodeStartingPoint in episodeStartingPoints)
            {
                var episodeToAdd = new EpisodeEntity();

                //get timestamp
                var    episodeTimestamp = TimestampRegex.Match(episodeStartingPoint);
                string episodeData      = "";
                int    startIndex       = playerLogData.IndexOf(episodeStartingPoint);
                int    endIndex         = playerLogData.FindIndex(startIndex + 2, timestamp => Regex.IsMatch(timestamp, TimestampPattern));
                for (int i = startIndex; i <= endIndex; i++)
                {
                    episodeData += playerLogData[i];
                }
                episodeToAdd = GetEpisodeStats(episodeData);

                // Get timestamps
                episodeToAdd.Timestamp = episodeTimestamp.Groups[1].Value;
                DateTime episodeFinished;
                if (DateTime.TryParse(episodeToAdd.Timestamp, out episodeFinished))
                {
                    episodeToAdd.EpisodeFinished = episodeFinished;
                }

                //get rounds
                List <RoundEntity> roundsInEpisode = new List <RoundEntity>();
                for (int i = 0; i < episodeToAdd.RoundsPlayed; i++)
                {
                    RoundEntity evaluatedRound = GetRoundStats(episodeData, i);
                    roundsInEpisode.Add(evaluatedRound);
                }
                episodeToAdd.RoundEntities = roundsInEpisode;
                allEpisodes.Add(episodeToAdd);
            }
            return(allEpisodes);
        }
Exemplo n.º 12
0
        private static List <RoundEntity> GetRoundsFromString(string roundString)
        {
            var roundMatches = Regex.Matches(roundString, roundPattern, RegexOptions.Singleline);
            var results      = new List <RoundEntity>();

            foreach (Match roundMatch in roundMatches)
            {
                var round = new RoundEntity();
                if (roundMatch.Success)
                {
                    round.RoundType  = roundMatch.Groups["roundName"].Value ?? string.Empty;
                    round.Qualified  = Util.BoolParse(roundMatch.Groups["qualified"].Value);
                    round.Position   = Util.IntParse(roundMatch.Groups["position"].Value);
                    round.Kudos      = Util.IntParse(roundMatch.Groups["kudos"].Value);
                    round.Fame       = Util.IntParse(roundMatch.Groups["fame"].Value);
                    round.BonusTier  = Util.IntParse(roundMatch.Groups["bonusTier"].Value);
                    round.BonusKudos = Util.IntParse(roundMatch.Groups["bonusKudos"].Value);
                    round.BonusFame  = Util.IntParse(roundMatch.Groups["bonusFame"].Value);
                    round.Badge      = roundMatch.Groups["badge"].Value ?? string.Empty;
                    results.Add(round);
                }
            }
            return(results);
        }
Exemplo n.º 13
0
        public async Task GenerateAvailableMatchDatesAsync(ClearMatchDates clearMatchDates, RoundEntity round,
                                                           CancellationToken cancellationToken)
        {
            _ = await _availableMatchDates.ClearAsync(clearMatchDates, cancellationToken);

            if (!AreEntitiesLoaded)
            {
                await LoadEntitiesAsync(cancellationToken);
            }
            await _availableMatchDates.GenerateNewAsync(round, cancellationToken);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Generate available match dates for teams where
        /// <see cref="TeamEntity.MatchDayOfWeek"/>, <see cref="TeamEntity.MatchTime"/>, <see cref="TeamEntity.VenueId"/>
        /// are not <see langword="null"/>.
        /// </summary>
        /// <param name="round"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        internal async Task GenerateNewAsync(RoundEntity round, CancellationToken cancellationToken)
        {
            await Initialize(cancellationToken);

            var teamIdProcessed        = new List <long>();
            var listTeamsWithSameVenue = new List <EntityCollection <TeamEntity> >();

            // Make a list of teams of the same round and with the same venue AND weekday AND match time
            // Venues will later be assigned to these teams alternately
            foreach (var team in round.TeamCollectionViaTeamInRound)
            {
                // the collection will contain at least one team
                var teams = GetTeamsWithSameVenueAndMatchTime(team, round);
                if (teamIdProcessed.Contains(teams[0].Id))
                {
                    continue;
                }

                listTeamsWithSameVenue.Add(teams);
                foreach (var t in teams)
                {
                    if (!teamIdProcessed.Contains(t.Id))
                    {
                        teamIdProcessed.Add(t.Id);
                    }
                }
            }

            foreach (var roundLeg in round.RoundLegs)
            {
                var startDate = DateTime.SpecifyKind(roundLeg.StartDateTime, DateTimeKind.Utc);
                var endDate   = DateTime.SpecifyKind(roundLeg.EndDateTime, DateTimeKind.Utc);

                foreach (var teamsWithSameVenue in listTeamsWithSameVenue)
                {
                    var teamIndex = 0;

                    // Make sure these values are not null
                    if (!teamsWithSameVenue[teamIndex].MatchDayOfWeek.HasValue ||
                        !teamsWithSameVenue[teamIndex].MatchTime.HasValue ||
                        !teamsWithSameVenue[teamIndex].VenueId.HasValue)
                    {
                        continue;
                    }

                    // Create Tuple for non-nullable context
                    var team = (Id : teamsWithSameVenue[teamIndex].Id,
                                MatchDayOfWeek : (DayOfWeek)teamsWithSameVenue[teamIndex].MatchDayOfWeek !.Value,
                                MatchTime : teamsWithSameVenue[teamIndex].MatchTime !.Value,
                                VenueId : teamsWithSameVenue[teamIndex].VenueId !.Value);

                    // get the first possible match date equal or after the leg's starting date
                    var matchDate = IncrementDateUntilDayOfWeek(startDate, team.MatchDayOfWeek);

                    // process the period of a leg
                    while (matchDate <= endDate)
                    {
                        // if there is more than one team per venue with same weekday and match time,
                        // match dates will be assigned alternately
                        var matchDateAndTimeUtc = _timeZoneConverter.ToUtc(matchDate.Date.Add(team.MatchTime));

                        // check whether the calculated date
                        // is within the borders of round legs (if any) and is not marked as excluded
                        if (IsDateWithinRoundLegDateTime(roundLeg, matchDateAndTimeUtc) &&
                            !IsExcludedDate(matchDateAndTimeUtc, round.Id, team.Id) &&
                            !await IsVenueOccupiedByMatchAsync(
                                new DateTimePeriod(matchDateAndTimeUtc,
                                                   matchDateAndTimeUtc.Add(_tenantContext.TournamentContext.FixtureRuleSet
                                                                           .PlannedDurationOfMatch)), team.VenueId, cancellationToken))
                        {
                            var av = new AvailableMatchDateEntity
                            {
                                TournamentId   = _tenantContext.TournamentContext.MatchPlanTournamentId,
                                HomeTeamId     = team.Id,
                                VenueId        = team.VenueId,
                                MatchStartTime = matchDateAndTimeUtc,
                                MatchEndTime   =
                                    matchDateAndTimeUtc.Add(_tenantContext.TournamentContext.FixtureRuleSet.PlannedDurationOfMatch),
                                IsGenerated = true
                            };

                            _generatedAvailableMatchDateEntities.Add(av);
                            teamIndex = ++teamIndex >= teamsWithSameVenue.Count ? 0 : teamIndex;
                        }

                        matchDate = matchDate.Date.AddDays(7);
                    }
                }
            }

            _logger.LogTrace("Generated {Count} UTC dates for HomeTeams:", _generatedAvailableMatchDateEntities.Count);
            _logger.LogTrace("{Generated}\n", _generatedAvailableMatchDateEntities.Select(gen => (gen.HomeTeamId, gen.MatchStartTime)));

            // save to the persistent storage
            // await _appDb.GenericRepository.SaveEntitiesAsync(_generatedAvailableMatchDateEntities, true, false, cancellationToken);
        }
Exemplo n.º 15
0
        private EntityCollection <TeamEntity> GetTeamsWithSameVenueAndMatchTime(TeamEntity team, RoundEntity round)
        {
            var resultTeams = new EntityCollection <TeamEntity>();

            var teamStartTime = team.MatchTime;
            var teamEndTime   = teamStartTime?.Add(_tenantContext.TournamentContext.FixtureRuleSet.PlannedDurationOfMatch);

            // get a list of other teams in this round with same venue and match day-of-the-week
            var otherTeams = round.TeamCollectionViaTeamInRound.FindMatches((TeamFields.VenueId == team.VenueId) &
                                                                            (TeamFields.MatchDayOfWeek ==
                                                                             team.MatchDayOfWeek) &
                                                                            (TeamFields.Id != team.Id));

            foreach (var index in otherTeams)
            {
                var otherStartTime = round.TeamCollectionViaTeamInRound[index].MatchTime;
                var otherEndTime   = otherStartTime?.Add(_tenantContext.TournamentContext.FixtureRuleSet.PlannedDurationOfMatch);

                if (otherStartTime <= teamStartTime && otherEndTime >= teamStartTime ||
                    otherStartTime <= teamEndTime && otherEndTime >= teamEndTime)
                {
                    resultTeams.Add(round.TeamCollectionViaTeamInRound[index]);
                }
            }

            // list is expected to contain at least one team
            resultTeams.Add(team);

            return(resultTeams);
        }
Exemplo n.º 16
0
        private EntityCollection <TeamEntity> GetTeamsWithSameVenueAndMatchTime(TeamEntity team, RoundEntity round)
        {
            var resultTeams = new EntityCollection <TeamEntity>();

            TimeSpan?teamStartTime = team.MatchTime;
            TimeSpan?teamEndTime   = teamStartTime?.Add(_matchPlanner.PlannedDurationOfMatch);

            // first get a list of other teams with same venue and match day of the week
            List <int> tmpTeams = round.TeamCollectionViaTeamInRound.FindMatches(TeamFields.VenueId == team.VenueId & TeamFields.MatchDayOfWeek == (int)team.MatchDayOfWeek & TeamFields.Id != team.Id);

            foreach (var index in tmpTeams)
            {
                TimeSpan?otherStartTime = round.TeamCollectionViaTeamInRound[index].MatchTime;
                TimeSpan?otherEndTime   = otherStartTime?.Add(_matchPlanner.PlannedDurationOfMatch);

                if ((otherStartTime <= teamStartTime && otherEndTime >= teamStartTime) || (otherStartTime <= teamEndTime && otherEndTime >= teamEndTime))
                {
                    resultTeams.Add(round.TeamCollectionViaTeamInRound[index]);
                }
            }

            // list is expected to contain at least one team
            resultTeams.Add(team);

            return(resultTeams);
        }
Exemplo n.º 17
0
        internal void GenerateNew(RoundEntity round)
        {
            var teamIdProcessed        = new List <long>();
            var listTeamsWithSameVenue = new List <EntityCollection <TeamEntity> >();

            // Make a list of teams of the same round and with the same venue + weekday + match time
            // Venues will later be assigned to these teams in an alternating way
            foreach (var team in round.TeamCollectionViaTeamInRound)
            {
                // the collection will contain at least one team
                EntityCollection <TeamEntity> teams = GetTeamsWithSameVenueAndMatchTime(team, round);
                if (!teamIdProcessed.Contains(teams[0].Id))
                {
                    listTeamsWithSameVenue.Add(teams);
                    foreach (var t in teams)
                    {
                        if (!teamIdProcessed.Contains(t.Id))
                        {
                            teamIdProcessed.Add(t.Id);
                        }
                    }
                }
            }

            foreach (var roundLeg in round.RoundLegs)
            {
                DateTime startDate = roundLeg.StartDateTime;
                DateTime endDate   = roundLeg.EndDateTime;
                var      matchDate = new DateTime();

                foreach (var teamsWithSameVenue in listTeamsWithSameVenue)
                {
                    int teamIndex = 0;

                    // get the first possible match date equal or after the leg's starting date
                    matchDate = IncrementDateUntilDayOfWeek(startDate, (DayOfWeek)teamsWithSameVenue[teamIndex].MatchDayOfWeek);

                    // process the period of a leg
                    while (matchDate <= endDate)
                    {
                        // if there is more than one team per venue with same weekday and match time,
                        // match dates will be assigned alternately
                        TeamEntity team             = teamsWithSameVenue[teamIndex];
                        DateTime   matchDateAndTime = DateTime.Parse(string.Concat(matchDate.ToShortDateString(), " ", team.MatchTime));

                        // check whether the calculated date
                        // is within the borders of round legs (if any) and is not marked as excluded
                        if (IsDateWithinRoundLegDateTime(roundLeg, matchDate) &&
                            !IsExcludedDate(matchDate, round.Id, team.Id) &&
                            !IsVenueOccupiedByMatch(new DateTimePeriod(matchDateAndTime, matchDateAndTime.Add(_matchPlanner.PlannedDurationOfMatch)), team.VenueId.Value))
                        {
                            var av = new AvailableMatchDateEntity();
                            av.TournamentId   = _matchPlanner.Tournament.Id;
                            av.HomeTeamId     = team.Id;
                            av.VenueId        = team.Venue.Id;
                            av.MatchStartTime = matchDateAndTime;
                            av.MatchEndTime   = matchDateAndTime.Add(_matchPlanner.PlannedDurationOfMatch);
                            av.IsGenerated    = true;
                            av.CreatedOn      = DateTime.Now;

                            _availableMatchDate.Add(av);
                            teamIndex = (++teamIndex >= teamsWithSameVenue.Count) ? 0 : teamIndex;
                        }
                        matchDate = matchDate.Date.AddDays(7);
                    }
                }
            }

            // save to the persistent storage
            _matchPlanner.Adapter.SaveEntityCollection(_availableMatchDate, true, false);
        }
Exemplo n.º 18
0
        public static RoundEntity GetRoundStats(string roundData, int roundNumber)
        {
            RoundEntity roundResults = new RoundEntity();

            // Get round type
            int    roundIndex         = roundData.IndexOf($"[Round {roundNumber}");
            string roundCodeStateText = roundData.Substring(roundIndex, 50);
            Regex  roundCodeRegex     = new Regex(@"\[Round \d \| (.+)\]");
            Match  roundCodeState     = roundCodeRegex.Match(roundCodeStateText);

            // Get qualification status for round
            int    qualifiedIndex     = roundData.IndexOf("Qualified:", roundIndex);
            string qualifiedStateText = roundData.Substring(qualifiedIndex, 25);
            Regex  qualifiedRegex     = new Regex(@"Qualified:.([a-zA-Z]+)");
            Match  qualifiedState     = qualifiedRegex.Match(qualifiedStateText);

            // Get starting position in round
            int    positionIndex     = roundData.IndexOf("Position:", roundIndex);
            string positionStateText = roundData.Substring(positionIndex, 25);
            Regex  positionRegex     = new Regex(@"Position:.(\d+)");
            Match  positionState     = positionRegex.Match(positionStateText);

            // Get Kudos earned in round
            int    kudosIndex     = roundData.IndexOf("Kudos:", roundIndex);
            string kudosStateText = roundData.Substring(kudosIndex, 25);
            Regex  kudosRegex     = new Regex(@"Kudos:.(\d+)");
            Match  kudosState     = kudosRegex.Match(kudosStateText);

            // Get Fame earned in round
            int    fameIndex     = roundData.IndexOf("Fame:", roundIndex);
            string fameStateText = roundData.Substring(fameIndex, 25);
            Regex  fameRegex     = new Regex(@"Fame:.(\d+)");
            Match  fameState     = fameRegex.Match(fameStateText);

            // Get round's bonus tier
            int    bonusTierIndex     = roundData.IndexOf("Bonus Tier:", roundIndex);
            string bonusTierStateText = roundData.Substring(bonusTierIndex, 25);
            Regex  bonusTierRegex     = new Regex(@"Bonus Tier:.(\d+)");
            Match  bonusTierState     = bonusTierRegex.Match(bonusTierStateText);

            int bonusTier;

            if (bonusTierState.Captures.Count == 0)
            {
                bonusTier = -1;
            }
            else
            {
                bonusTier = Int32.Parse(bonusTierState.Groups[1].Value);
            }


            // Get round's bonus Kudos
            int    bonusKudosIndex     = roundData.IndexOf("Bonus Kudos:", roundIndex);
            string bonusKudosStateText = roundData.Substring(bonusKudosIndex, 25);
            Regex  bonusKudosRegex     = new Regex(@"Bonus Kudos:.(\d+)");
            Match  bonusKudosState     = bonusKudosRegex.Match(bonusKudosStateText);

            // Get round's bonus Fame
            int    bonusFameIndex     = roundData.IndexOf("Bonus Fame:", roundIndex);
            string bonusFameStateText = roundData.Substring(bonusFameIndex, 16);
            Regex  bonusFameRegex     = new Regex(@"Bonus Fame:.(\d+)");
            Match  bonusFameState     = bonusFameRegex.Match(bonusFameStateText);

            // Get round's earned badge
            int    badgeIndex     = roundData.IndexOf("BadgeId:", roundIndex);
            string badgeStateText = roundData.Substring(badgeIndex, 16);
            Regex  badgeRegex     = new Regex(@"BadgeId:.([a-zA-Z]+)");
            Match  badgeState     = badgeRegex.Match(badgeStateText);
            string badgeId        = "failure";

            if (bonusTierState.Captures.Count == 0 && qualifiedState.Groups[1].Value == "True")
            {
                badgeId = "Passed";
            }
            else if (qualifiedState.Groups[1].Value == "False")
            {
                badgeId = "Failure";
            }
            else
            {
                badgeId = badgeState.Groups[1].Value;
            }


            // Assemble round data object
            roundResults.RoundType  = roundCodeState.Groups[1].Value;
            roundResults.Qualified  = (qualifiedState.Groups[1].Value == "True");
            roundResults.Position   = Int32.Parse(positionState.Groups[1].Value);
            roundResults.Kudos      = Int32.Parse(kudosState.Groups[1].Value);
            roundResults.Fame       = Int32.Parse(fameState.Groups[1].Value);
            roundResults.BonusTier  = bonusTier;
            roundResults.BonusKudos = Int32.Parse(bonusKudosState.Groups[1].Value);
            roundResults.BonusFame  = Int32.Parse(bonusFameState.Groups[1].Value);
            roundResults.Badge      = badgeId;

            return(roundResults);
        }
Exemplo n.º 19
0
        /// <summary>
        /// Copies the round basic data and the round leg data
        /// from the source to an existing target tournament. The new tournament id must
        /// already exist. Leg data for each round is taken over from target tournament legs
        /// on a 1:1 base (same number of legs, dates/times).
        /// </summary>
        /// <param name="fromTournamentId">Existing source tournament id.</param>
        /// <param name="toTournamentId">Existing target tournament id.</param>
        /// <param name="excludeRoundId">List of round id's to be excluded (may be null for none)</param>
        /// <returns>True, if creation was successful, false otherwise.</returns>
        public bool CopyRound(long fromTournamentId, long toTournamentId, IEnumerable <long> excludeRoundId)
        {
            const string transactionName = "CloneRounds";

            if (excludeRoundId == null)
            {
                excludeRoundId = new List <long>();
            }
            DateTime now = DateTime.Now;

            // get the rounds of SOURCE tournament
            var roundIds = _appDb.TournamentRepository.GetTournamentRounds(fromTournamentId).Select(r => r.Id).ToList();

            using var da = _appDb.DbContext.GetNewAdapter();
            // da.StartTransaction(System.Data.IsolationLevel.ReadUncommitted, transactionName);
            var roundsWithLegs = new Queue <RoundEntity>();

            foreach (var r in roundIds)
            {
                roundsWithLegs.Enqueue(_appDb.RoundRepository.GetRoundWithLegs(r));
            }

            foreach (var r in roundIds)
            {
                var round = roundsWithLegs.Dequeue();

                // skip excluded round id's
                if (excludeRoundId.Contains(r))
                {
                    continue;
                }

                // create new round and overtake data of source round
                var newRound = new RoundEntity()
                {
                    TournamentId = toTournamentId,
                    Name         = round.Name,
                    Description  = round.Description,
                    TypeId       = round.TypeId,
                    NumOfLegs    = round.NumOfLegs,
                    MatchRuleId  = round.MatchRuleId,
                    SetRuleId    = round.MatchRuleId,
                    IsComplete   = false,
                    CreatedOn    = now,
                    ModifiedOn   = now,
                    NextRoundId  = null
                };

                // create the round leg records based on the TARGET tournament legs
                foreach (var rl in round.RoundLegs)
                {
                    var newRoundLeg = new RoundLegEntity()
                    {
                        SequenceNo    = rl.SequenceNo,
                        Description   = rl.Description,
                        StartDateTime = rl.StartDateTime,
                        EndDateTime   = rl.EndDateTime,
                        CreatedOn     = now,
                        ModifiedOn    = now
                    };
                    newRound.RoundLegs.Add(newRoundLeg);
                }

                // save recursively (new round with its new round legs)
                if (!da.SaveEntity(newRound, true, true))
                {
                    // roll back if any round fails
                    da.Rollback(transactionName);
                    return(false);
                }
            }

            // commit only after all rounds are processed successfully
            da.Commit();
            return(true);
        }
Exemplo n.º 20
0
        /// <summary>
        /// Generates round match combinations for the Round Robin system,
        /// assigns optimized match dates and stores the matches to
        /// the persistent storage.
        /// </summary>
        public async Task GenerateFixturesForRound(RoundEntity round, bool keepExisting,
                                                   CancellationToken cancellationToken)
        {
            if (!AreEntitiesLoaded)
            {
                await LoadEntitiesAsync(cancellationToken);
            }

            round = _tournament.Rounds.First(r => r.Id == round.Id);

            if (_appDb.MatchRepository.AnyCompleteMatchesExist(round))
            {
                throw new Exception($"Completed matches exist for round '{round.Id}'. Generating fixtures aborted.");
            }

            // generated matches will be stored here
            var roundMatches = new EntityCollection <MatchEntity>();

            if (keepExisting)
            {
                roundMatches = _appDb.MatchRepository.GetMatches(round);
            }
            else
            {
                var bucket = new RelationPredicateBucket(new PredicateExpression(
                                                             new FieldCompareRangePredicate(MatchFields.RoundId, null, false, new[] { round.Id })));
                await _appDb.GenericRepository.DeleteEntitiesDirectlyAsync(typeof(MatchEntity), bucket,
                                                                           cancellationToken);
            }

            await GenerateAvailableMatchDatesAsync(ClearMatchDates.OnlyAutoGenerated, round, cancellationToken);

            // get the team ids because TeamEntity lacks IComparable
            // and cannot be used directly
            var teams = new Collection <long>(round.TeamCollectionViaTeamInRound.Select(t => t.Id).ToList());

            // now calculate matches for each leg of a round
            foreach (var roundLeg in round.RoundLegs)
            {
                // build up match combinations for the teams of round
                var roundRobin    = new RoundRobinSystem <long>(teams);
                var bundledGroups =
                    roundRobin.GetBundledGroups(RefereeType.HomeTeam,
                                                roundLeg.SequenceNo % 2 == 1 ? LegType.First : LegType.Return,
                                                CombinationGroupOptimization.GroupWithAlternatingHomeGuest);

                /*
                 * Special treatment for teams which do not have home matches
                 */
                foreach (var teamCombinationGroup in bundledGroups)
                {
                    foreach (var combination in teamCombinationGroup)
                    {
                        if (!TeamsWithoutHomeMatches.Contains(combination.HomeTeam))
                        {
                            continue;
                        }

                        // swap home and guest team, keep referee unchanged
                        (combination.HomeTeam, combination.GuestTeam) = (combination.GuestTeam, combination.HomeTeam);
                    }
                }

                /*
                 * Assign desired from/to dates to bundled groups for later orientation
                 * in which period matches should take place
                 */
                AssignRoundDatePeriods(roundLeg, bundledGroups);

                if (bundledGroups.Any(g => !g.DateTimePeriod.Start.HasValue))
                {
                    throw new Exception(
                              "Not all bundled groups got a date period assigned. Probably not enough dates available for assignment.");
                }

                // process each team combination (match) that shall take place in the same week (if possible)
                foreach (var teamCombinationGroup in bundledGroups)
                {
                    // get match dates for every combination of a group.
                    // matches in the same teamCombinationGroup can even take place on the same day.
                    // matchDates contains calculated dates in the same order as combinations,
                    // so the index can be used for both.
                    var availableDates = GetMatchDates(roundLeg, teamCombinationGroup, roundMatches);
                    _logger.LogTrace("Selected dates: {0}", string.Join(", ", availableDates.OrderBy(bd => bd?.MatchStartTime).Select(bd => bd?.MatchStartTime.ToShortDateString())).TrimEnd(',', ' '));

                    for (var index = 0; index < teamCombinationGroup.Count; index++)
                    {
                        var combination = teamCombinationGroup[index];

                        // If existing matches were loaded from database, we have to skip such combinations!
                        // Note: Home team and guest team of combinations could have been swapped for TeamsWithoutHomeMatches
                        if (roundMatches.Any(rm =>
                                             rm.HomeTeamId == combination.HomeTeam && rm.GuestTeamId == combination.GuestTeam &&
                                             rm.LegSequenceNo == roundLeg.SequenceNo || rm.GuestTeamId == combination.HomeTeam &&
                                             rm.HomeTeamId == combination.GuestTeam && rm.LegSequenceNo == roundLeg.SequenceNo))
                        {
                            continue;
                        }

                        var match = new MatchEntity
                        {
                            HomeTeamId   = combination.HomeTeam,
                            GuestTeamId  = combination.GuestTeam,
                            RefereeId    = combination.Referee,
                            PlannedStart = availableDates[index] != null ? availableDates[index] !.MatchStartTime : default(DateTime?),
                            PlannedEnd   = availableDates[index] != null ? availableDates[index] !.MatchStartTime
                                           .Add(_tenantContext.TournamentContext.FixtureRuleSet.PlannedDurationOfMatch) : default(DateTime?),
                            VenueId = availableDates[index] != null
                                ? availableDates[index] !.VenueId
                                      // take over the venue stored in the team entity (may also be null!)
                                : _tournament.Rounds[_tournament.Rounds.FindMatches(RoundFields.Id == roundLeg.RoundId).First()].TeamCollectionViaTeamInRound.First(t => t.Id == combination.HomeTeam).VenueId,
                            RoundId       = round.Id,
                            IsComplete    = false,
                            LegSequenceNo = roundLeg.SequenceNo,
                            ChangeSerial  = 0,
                            Remarks       = string.Empty
                        };
                        roundMatches.Add(match);
                    }
                }
            }

            // save the matches for the group
            await _appDb.GenericRepository.SaveEntitiesAsync(roundMatches, true, false, cancellationToken);

            await _availableMatchDates.ClearAsync(ClearMatchDates.OnlyAutoGenerated, cancellationToken);
        }