public AnalyticData ProcessData() { AnalyticData data = new AnalyticData(); Streak currentStreak = Streak.Up; Streak previousRound = Streak.NoData; int currentStreakCount = 0; decimal priceAccumulator = 0; long volumeAccumulator = 0; Dictionary <int, int> sequenceDist = new Dictionary <int, int>(); data.Symbol = Symbol; data.RoundsCount = this.PriceSeries.Count; InitAnalytics(data); foreach (PriceData round in PriceSeries) { priceAccumulator += RoundPriceAvg(round); volumeAccumulator += round.Volume; MinsMaxs(data, round); StreakCalculator(data, ref currentStreak, ref previousRound, ref currentStreakCount, round, sequenceDist); } CalculateAverages(sequenceDist, data, volumeAccumulator, priceAccumulator, data.RoundsCount); return(data); }
public PlayarStatisistics(Guid id, PlayarName name) { Id = id; Name = name; Score = InitialScore; ScoreHistory = new LimitedQueue<Tuple<double, Activity>>(KeepLatestResults); Offensive = new GamePercentage(); Defensive = new GamePercentage(); Total = new GamePercentage(); _winning = new Streak(5); _loosing = new Streak(5); }
private void StreakCalculator(AnalyticData data, ref Streak currentStreak, ref Streak previousRound, ref int currentStreakCount, PriceData round, Dictionary <int, int> sequenceDist) { if (round.ClosingPrice > round.OpenPrice) { data.UpsideRoundsCount++; if (currentStreak == Streak.Down && previousRound == Streak.Up) { data.Sequence.Add($"{currentStreakCount}U"); UpdateSequenceDictionary(sequenceDist, -currentStreakCount); if (currentStreakCount > data.MaxDownsideStreakCount) { data.MaxDownsideStreakCount = currentStreakCount; } currentStreakCount = 2; currentStreak = Streak.Up; } else { currentStreakCount++; } previousRound = Streak.Up; } else if (round.ClosingPrice <= round.OpenPrice) { data.DownsideRoundsCount++; if (currentStreak == Streak.Up && previousRound == Streak.Down) { data.Sequence.Add($"{currentStreakCount}D"); UpdateSequenceDictionary(sequenceDist, currentStreakCount); if (currentStreakCount > data.MaxUpsideStreakCount) { data.MaxUpsideStreakCount = currentStreakCount; } currentStreakCount = 2; currentStreak = Streak.Down; } else { currentStreakCount++; } previousRound = Streak.Down; } }
/// <summary> /// Compare Streaks with current kill streak. /// </summary> private void CheackForStreak() { var highestStreak = new Streak(); foreach (var streak in Streaks) { var nextStreak = streak; if (nextStreak.RequiredKills > highestStreak.RequiredKills) { highestStreak = nextStreak; } if (m_currentKillStreak >= nextStreak.RequiredKills) { ScriptableTextDisplay.DisableAll(8); ScriptableTextDisplay.InitializeScriptableText(8, transform.position, streak.Name); } } }
/// <summary> /// Create new attempt records and return them in a list. All new attempts should be after the most recent successful attempt. /// </summary> /// <param name="achievementTypeCache">The achievement type cache.</param> /// <param name="streak">The streak.</param> /// <param name="mostRecentClosedAttempt">The most recent closed attempt.</param> /// <returns></returns> protected override List <AchievementAttempt> CreateNewAttempts(AchievementTypeCache achievementTypeCache, Streak streak, AchievementAttempt mostRecentClosedAttempt) { var rockContext = new RockContext(); var streakTypeService = new StreakTypeService(rockContext); var streakTypeCache = StreakTypeCache.Get(streak.StreakTypeId); // Validate the attribute values var numberToAchieve = GetAttributeValue(achievementTypeCache, AttributeKey.NumberToAchieve).AsInteger(); if (numberToAchieve <= 0) { ExceptionLogService.LogException($"StreakAchievement.CreateNewAttempts cannot process because the NumberToAchieve attribute is less than 1"); return(null); } var attributeTimespanDays = GetAttributeValue(achievementTypeCache, AttributeKey.TimespanInDays).AsIntegerOrNull(); if (attributeTimespanDays.HasValue && attributeTimespanDays.Value <= 0) { ExceptionLogService.LogException($"StreakAchievement.CreateNewAttempts cannot process because the TimespanInDays attribute is less than 1"); return(null); } // Calculate the date range where new achievements can be validly found var attributeMinDate = GetAttributeValue(achievementTypeCache, AttributeKey.StartDateTime).AsDateTime(); var attributeMaxDate = GetAttributeValue(achievementTypeCache, AttributeKey.EndDateTime).AsDateTime(); var minDate = CalculateMinDateForAchievementAttempt(streak.EnrollmentDate, mostRecentClosedAttempt, attributeMinDate, numberToAchieve); var maxDate = CalculateMaxDateForAchievementAttempt(minDate, attributeMaxDate); // Get the max date that streaks can be broken. This is to avoid breaking streaks while people still have time to // engage in that day or week (because it is the current day or week) var maxDateForStreakBreaking = StreakTypeService.GetMaxDateForStreakBreaking(streakTypeCache); // Track the attempts in a list that will be returned. The int is the streak count for that attempt var attempts = new List <AchievementAttempt>(); var streaks = new List <ComputedStreak>(); // Define what happens for each bit in the date range bool iterationAction(int currentUnit, DateTime currentDate, bool hasOccurrence, bool hasEngagement, bool hasExclusion) { // If there is an engagement and a timespan, then this is a possible attempt. If there is no timespan then only one // attempt needs to be tracked at a time if (hasOccurrence && hasEngagement && (attributeTimespanDays.HasValue || !streaks.Any())) { streaks.Add(new ComputedStreak(currentDate)); } else if (hasOccurrence && !hasEngagement && !hasExclusion && streaks.Any()) { // Break the streaks and close an attempt if there is an unexcused absence var longestStreak = streaks.First(); attempts.Add(GetAttemptFromStreak(longestStreak, numberToAchieve, currentDate <= maxDateForStreakBreaking)); streaks.Clear(); return(false); } for (var i = streaks.Count - 1; i >= 0; i--) { var computedStreak = streaks[i]; if (hasOccurrence && hasEngagement) { // Increment the streak computedStreak.Count++; computedStreak.EndDate = currentDate; // Check for a fulfilled attempt if (computedStreak.Count >= numberToAchieve) { streaks.Clear(); if (achievementTypeCache.AllowOverAchievement) { streaks.Add(computedStreak); i = 0; } else { attempts.Add(GetAttemptFromStreak(computedStreak, numberToAchieve, !achievementTypeCache.AllowOverAchievement)); break; } } } // If there is a timespan and this streak is too old, then the attempt is closed if (attributeTimespanDays.HasValue) { var inclusiveAge = (currentDate - computedStreak.StartDate).Days + 1; if (inclusiveAge >= attributeTimespanDays.Value) { var timedOutAttempt = GetAttemptFromStreak(computedStreak, numberToAchieve, true); attempts.Add(timedOutAttempt); streaks.RemoveAt(i); // Remove more recently started streaks that started before the next valid start date (based // on the deficiency of this timed out attempt) var nextValidStartDate = CalculateMinDateForAchievementAttempt(streak.EnrollmentDate, timedOutAttempt, attributeMinDate, numberToAchieve); for (var j = streaks.Count - 1; j >= i; j--) { var moreRecentStreak = streaks[j]; if (moreRecentStreak.StartDate < nextValidStartDate) { streaks.RemoveAt(j); } } } } } return(false); } // Iterate through the streak date for the date range specified streakTypeService.IterateStreakMap(streakTypeCache, streak.PersonAliasId, minDate, maxDate, iterationAction, out var errorMessage); if (!errorMessage.IsNullOrWhiteSpace()) { ExceptionLogService.LogException($"StreakAchievement.CreateNewAttempts got an error calling StreakTypeService.IterateStreakMap: {errorMessage}"); return(null); } // The longest leftover streak is an open attempt if (streaks.Any()) { var longestStreak = streaks.First(); attempts.Add(GetAttemptFromStreak(longestStreak, numberToAchieve, false)); } return(attempts); }
/// <summary> /// Update the open attempt record if there are changes. /// </summary> /// <param name="openAttempt"></param> /// <param name="achievementTypeCache">The achievement type cache.</param> /// <param name="streak">The streak.</param> protected override void UpdateOpenAttempt(AchievementAttempt openAttempt, AchievementTypeCache achievementTypeCache, Streak streak) { var rockContext = new RockContext(); var streakTypeService = new StreakTypeService(rockContext); var streakTypeCache = GetStreakTypeCache(achievementTypeCache); // Validate the attribute values var numberToAchieve = GetAttributeValue(achievementTypeCache, AttributeKey.NumberToAchieve).AsInteger(); if (numberToAchieve <= 0) { ExceptionLogService.LogException($"StreakAchievement.UpdateOpenAttempt cannot process because the numberToAchieve attribute is less than 1"); return; } var attributeTimespanDays = GetAttributeValue(achievementTypeCache, AttributeKey.TimespanInDays).AsIntegerOrNull(); if (attributeTimespanDays.HasValue && attributeTimespanDays.Value <= 0) { ExceptionLogService.LogException($"StreakAchievement.UpdateOpenAttempt cannot process because the TimespanInDays attribute is less than 1"); return; } // Calculate the date range where the open attempt can be validly fulfilled var attributeMaxDate = GetAttributeValue(achievementTypeCache, AttributeKey.EndDateTime).AsDateTime(); var minDate = openAttempt.AchievementAttemptStartDateTime; var maxDate = CalculateMaxDateForAchievementAttempt(minDate, attributeMaxDate); // Get the max date that streaks can be broken. This is to avoid breaking streaks while people still have time to // engage in that day or week (because it is the current day or week) var maxDateForStreakBreaking = StreakTypeService.GetMaxDateForStreakBreaking(streakTypeCache); // Track the streak var computedStreak = new ComputedStreak(minDate) { EndDate = minDate }; // Define what happens for each bit in the date range bool iterationAction(int currentUnit, DateTime currentDate, bool hasOccurrence, bool hasEngagement, bool hasExclusion) { var iterationCanStop = false; // If there is an engagement, then increment the streak if (hasOccurrence && hasEngagement) { computedStreak.Count++; computedStreak.EndDate = currentDate; // Check for a fulfilled attempt if (computedStreak.Count >= numberToAchieve) { ApplyStreakToAttempt(computedStreak, openAttempt, numberToAchieve, !achievementTypeCache.AllowOverAchievement); iterationCanStop = !achievementTypeCache.AllowOverAchievement; } } else if (hasOccurrence && !hasEngagement && !hasExclusion) { // Break the streak and close the attempt if there is an unexcused absence ApplyStreakToAttempt(computedStreak, openAttempt, numberToAchieve, currentDate <= maxDateForStreakBreaking); iterationCanStop = true; } // If there is a timespan and this streak is too old, then the attempt is closed if (attributeTimespanDays.HasValue) { var inclusiveAge = (currentDate - computedStreak.StartDate).Days + 1; if (inclusiveAge >= attributeTimespanDays.Value) { ApplyStreakToAttempt(computedStreak, openAttempt, numberToAchieve, currentDate <= maxDateForStreakBreaking); iterationCanStop = true; } } return(iterationCanStop); } // Iterate through the streak date for the date range specified streakTypeService.IterateStreakMap(streakTypeCache, streak.PersonAliasId, minDate, maxDate, iterationAction, out var errorMessage); if (!errorMessage.IsNullOrWhiteSpace()) { ExceptionLogService.LogException($"StreakAchievement.UpdateOpenAttempt got an error calling StreakTypeService.IterateStreakMap: {errorMessage}"); return; } // If the attempt wasn't closed in the iteration, then it will remain open if (!openAttempt.IsClosed) { var progress = CalculateProgress(computedStreak.Count, numberToAchieve); openAttempt.Progress = progress; openAttempt.IsSuccessful = progress >= 1m; } }
public int GetMaxStreak(IEnumerable<int> values) { int zerosCount = 0; var streaksList = new List<Streak>(); var sortedSet = new SortedSet<int>(); foreach (var value in values) { if (value == 0) { zerosCount++; } else { sortedSet.Add(value); } } var valuesIterator = sortedSet.GetEnumerator(); valuesIterator.MoveNext(); var previousValue = valuesIterator.Current; var firstStreak = new Streak { ZerosLeft = zerosCount, StartValue = valuesIterator.Current }; streaksList.Add(firstStreak); if (sortedSet.Count == 0) { return zerosCount; } if (sortedSet.Count == 1) { firstStreak.EndValue = valuesIterator.Current; } while (valuesIterator.MoveNext()) { int missingValuesGap = valuesIterator.Current - previousValue - 1; int streaksCount = streaksList.Count; if (missingValuesGap > 0) { streaksList.Add(new Streak { ZerosLeft = zerosCount, StartValue = valuesIterator.Current }); } for (int index = 0; index < streaksCount; index++) { var streak = streaksList[index]; if (!streak.IsSealed) { if (streak.ZerosLeft >= missingValuesGap) { streak.ZerosLeft -= missingValuesGap; } else { streak.EndValue = previousValue; streak.IsSealed = true; } streak.EndValue = missingValuesGap == 0 ? valuesIterator.Current : previousValue; } } previousValue = valuesIterator.Current; } return streaksList.Max(x => x.GetValue()); }
public int GetMaxStreak(IEnumerable <int> values) { int zerosCount = 0; var streaksList = new List <Streak>(); var sortedSet = new SortedSet <int>(); foreach (var value in values) { if (value == 0) { zerosCount++; } else { sortedSet.Add(value); } } var valuesIterator = sortedSet.GetEnumerator(); valuesIterator.MoveNext(); var previousValue = valuesIterator.Current; var firstStreak = new Streak { ZerosLeft = zerosCount, StartValue = valuesIterator.Current }; streaksList.Add(firstStreak); if (sortedSet.Count == 0) { return(zerosCount); } if (sortedSet.Count == 1) { firstStreak.EndValue = valuesIterator.Current; } while (valuesIterator.MoveNext()) { int missingValuesGap = valuesIterator.Current - previousValue - 1; int streaksCount = streaksList.Count; if (missingValuesGap > 0) { streaksList.Add(new Streak { ZerosLeft = zerosCount, StartValue = valuesIterator.Current }); } for (int index = 0; index < streaksCount; index++) { var streak = streaksList[index]; if (!streak.IsSealed) { if (streak.ZerosLeft >= missingValuesGap) { streak.ZerosLeft -= missingValuesGap; } else { streak.EndValue = previousValue; streak.IsSealed = true; } streak.EndValue = missingValuesGap == 0 ? valuesIterator.Current : previousValue; } } previousValue = valuesIterator.Current; } return(streaksList.Max(x => x.GetValue())); }
/// <summary> /// Update the open attempt record if there are changes. /// </summary> /// <param name="openAttempt"></param> /// <param name="streakTypeAchievementTypeCache">The streak type achievement type cache.</param> /// <param name="streak">The streak.</param> protected override void UpdateOpenAttempt(StreakAchievementAttempt openAttempt, StreakTypeAchievementTypeCache streakTypeAchievementTypeCache, Streak streak) { var rockContext = new RockContext(); var streakTypeService = new StreakTypeService(rockContext); var streakTypeCache = streakTypeAchievementTypeCache.StreakTypeCache; // Validate the attribute values var numberToAccumulate = GetAttributeValue(streakTypeAchievementTypeCache, AttributeKey.NumberToAccumulate).AsInteger(); if (numberToAccumulate <= 0) { ExceptionLogService.LogException($"AccumulativeAchievement.UpdateOpenAttempt cannot process because the NumberToAccumulate attribute is less than 1"); return; } var attributeTimespanDays = GetAttributeValue(streakTypeAchievementTypeCache, AttributeKey.TimespanInDays).AsIntegerOrNull(); if (attributeTimespanDays.HasValue && attributeTimespanDays.Value <= 0) { ExceptionLogService.LogException($"AccumulativeAchievement.UpdateOpenAttempt cannot process because the TimespanInDays attribute is less than 1"); return; } // Calculate the date range where the open attempt can be validly fulfilled var attributeMaxDate = GetAttributeValue(streakTypeAchievementTypeCache, AttributeKey.EndDateTime).AsDateTime(); var minDate = openAttempt.AchievementAttemptStartDateTime; var maxDate = CalculateMaxDateForAchievementAttempt(minDate, attributeMaxDate); // Track the accumulation var accumulation = new ComputedStreak(minDate) { EndDate = minDate }; // Define what happens for each bit in the date range bool iterationAction(int currentUnit, DateTime currentDate, bool hasOccurrence, bool hasEngagement, bool hasExclusion) { // If there is an engagement, then increment the accumulation if (hasOccurrence && hasEngagement) { accumulation.Count++; accumulation.EndDate = currentDate; // Check for a fulfilled attempt if (accumulation.Count >= numberToAccumulate) { var progress = CalculateProgress(accumulation.Count, numberToAccumulate); openAttempt.AchievementAttemptEndDateTime = accumulation.EndDate; openAttempt.Progress = progress; openAttempt.IsClosed = !streakTypeAchievementTypeCache.AllowOverAchievement; openAttempt.IsSuccessful = progress >= 1m; } } // If there is a timespan and this accumulation is too old, then the attempt is closed if (attributeTimespanDays.HasValue) { var inclusiveAge = (currentDate - accumulation.StartDate).Days + 1; if (inclusiveAge >= attributeTimespanDays.Value) { var progress = CalculateProgress(accumulation.Count, numberToAccumulate); openAttempt.AchievementAttemptEndDateTime = accumulation.EndDate; openAttempt.Progress = progress; openAttempt.IsClosed = true; openAttempt.IsSuccessful = progress >= 1m; } } return(openAttempt.IsClosed); } // Iterate through the streak date for the date range specified streakTypeService.IterateStreakMap(streakTypeCache, streak.PersonAliasId, minDate, maxDate, iterationAction, out var errorMessage); if (!errorMessage.IsNullOrWhiteSpace()) { ExceptionLogService.LogException($"AccumulativeAchievement.UpdateOpenAttempt got an error calling StreakTypeService.IterateStreakMap: {errorMessage}"); return; } // If the attempt wasn't closed in the iteration, then it will remain open if (!openAttempt.IsClosed) { var progress = CalculateProgress(accumulation.Count, numberToAccumulate); openAttempt.Progress = progress; openAttempt.IsSuccessful = progress >= 1m; } }
/// <summary> /// Create new attempt records and return them in a list. All new attempts should be after the most recent successful attempt. /// </summary> /// <param name="achievementTypeCache">The achievement type cache.</param> /// <param name="streak">The streak.</param> /// <param name="mostRecentSuccess">The most recent successful attempt.</param> /// <returns></returns> protected abstract List <AchievementAttempt> CreateNewAttempts(AchievementTypeCache achievementTypeCache, Streak streak, AchievementAttempt mostRecentSuccess);
/// <summary> /// Update the open attempt record if there are changes. Be sure to close the attempt if it is no longer possible to make /// progress on this open attempt. /// </summary> /// <param name="openAttempt">The open attempt.</param> /// <param name="achievementTypeCache">The achievement type cache.</param> /// <param name="streak">The streak.</param> protected abstract void UpdateOpenAttempt(AchievementAttempt openAttempt, AchievementTypeCache achievementTypeCache, Streak streak);