コード例 #1
0
        /// <summary>
        /// Searches for the first and the last motor use and sums up the time between.
        /// The first motor use is when the motor value is not 0
        /// The last motor use is when the motor value is 0
        /// </summary>
        /// <param name="startTime">Uses the startTime as the start of the range.</param>
        /// <param name="endTime">Uses the startTime as the end of the range</param>
        /// <param name="targetUser"></param>
        /// <returns></returns>
        public static long CalculateFlightDuration(long startTime, long endTime, SmartPlaneUser targetUser)
        {
            var motorDatasInTimeRange = targetUser.MotorDatas.Where(m => m.TimeStamp <= endTime && m.TimeStamp >= startTime).ToList();

            //When there are no MotorData in Range return 0
            if (motorDatasInTimeRange.Any() == false)
            {
                return 0;
            }

            // get all motor values which are not 0
            var starts = motorDatasInTimeRange.Where(m => m.Value != 0).ToList();
            if (starts.Any() == false)
            {
                // if no motor data is not 0, the plane was not flying
                return 0;
            }
            var startOfTheFlight = starts.Min(m => m.TimeStamp);

            // get all motor values which are 0
            var ends = motorDatasInTimeRange.Where(m => m.Value == 0).ToList();

            // if no motor data is 0, use the time when the connection was closed
            var endOfTheFlight = ends.Any() ? ends.Min(m => m.TimeStamp) : endTime;

            //To be sure that no negative flight duration will be returned
            if (startOfTheFlight > endOfTheFlight)
            {
                return 0;
            }
            return endOfTheFlight - startOfTheFlight;
        }
コード例 #2
0
        public static IEnumerable<long> GetDurationOfFlightsWithSmoothMotor(SmartPlaneUser targetUser)
        {
            var motorDatasInRange = GetAllMotorDatasWithinConnections(targetUser).ToList();
            if (motorDatasInRange.Any() == false || motorDatasInRange.First().Any() == false)
            {
                yield break;
            }

            var lastValue = motorDatasInRange.First().First().Value;
            foreach (var connection in motorDatasInRange)
            {
                var motorDatas = connection as IList<MotorData> ?? connection.ToList();
                var timeStampOfCurrentValue = motorDatas.First().TimeStamp;

                foreach (var motorData in motorDatas)
                {
                    //save current length of smooth flying and reset start and end times to start new calculation
                    var timeStampOfPreviousValue = timeStampOfCurrentValue;
                    timeStampOfCurrentValue = motorData.TimeStamp;

                    if (_isSmoothDifference(motorData.Value, lastValue))
                    {
                        var durationBetweenMotorValues = timeStampOfCurrentValue - timeStampOfPreviousValue;

                        if (durationBetweenMotorValues > 0)
                        {
                            yield return durationBetweenMotorValues;
                        }
                    }

                    lastValue = motorData.Value;
                }
            }
        }
コード例 #3
0
 public void AddNewSmartplaneUser(string id)
 {
     var newUser = new SmartPlaneUser
     {
         ReleatedApplicationUserId = id
     };
     _db.SmartPlaneUsers.Add(newUser);
 }
コード例 #4
0
 protected override int CalculateProgress(SmartPlaneUser targetUser)
 {
     var timesWithMaxMotor = AchievementCalculationHelper.GetDurationsWithMaxMotor(targetUser).ToList();
     var maxMotorTimeDuration = timesWithMaxMotor.Where(d => d >= NeededDurationWithMaxMotor);
     var progress = maxMotorTimeDuration.Count() / OnePercentStep;
     if (progress > 100)
     {
         return 100;
     }
     return (int)progress;
 }
コード例 #5
0
        protected override int CalculateProgress(SmartPlaneUser targetUser)
        {
            var flights = AchievementCalculationHelper.GetEndAndStartTimesOfAllConnections(targetUser);
            var flightDurations = AchievementCalculationHelper.GetFlightDurationTimes(flights, targetUser).ToList();

            var flightDuration = flightDurations.Sum();
            var percent = flightDuration / OnePercentStep;
            if (percent >= 100)
            {
                return 100;
            }
            return (int)percent;
        }
コード例 #6
0
 protected override int CalculateProgress(SmartPlaneUser targetUser)
 {
     var smoothRudderFlightDurations = AchievementCalculationHelper.GetDurationOfFlightsWithSmoothRudder(targetUser).ToList();
     if (smoothRudderFlightDurations.Any() == false)
     {
         return 0;
     }
     var progress = smoothRudderFlightDurations.Sum() / OnePercentStep;
     if (progress >= 100)
     {
         return 100;
     }
     return (int)progress;
 }
コード例 #7
0
        private Achievement _addAchievementWhenMissing(SmartPlaneUser targetUser)
        {
            var achievement = targetUser.Achievements.FirstOrDefault(a => a.Name.Equals(_achievementName));
            if (achievement != null)
            {
                return achievement;
            }
            achievement = CreateAchievement();
            targetUser.Achievements.Add(achievement);

            var msg = $"Added missing Achievement {_achievementName} to user {targetUser.Id}.";
            Logger.Log(msg,LogLevel.Debug);

            return achievement;
        }
コード例 #8
0
        public void CalculateAchievementProgress(SmartPlaneUser targetUser)
        {
            var relatedAchievement = _addAchievementWhenMissing(targetUser);
            if (relatedAchievement.Progress == 100)
            {
                var skippedMsg =$"Skipped calculation of Achievement {_achievementName} of user {targetUser.Id}: Already achieved.";
                Logger.Log(skippedMsg, LogLevel.Debug);
                return;
            }
            var newProgress = CalculateProgress(targetUser);

            var newProgressMsg = $"Achievement {_achievementName} of user {targetUser.Id}, updated progress to {newProgress}.";
            Logger.Log(newProgressMsg, LogLevel.Info);

            relatedAchievement.Progress = Convert.ToByte(CalculateProgress(targetUser));
        }
コード例 #9
0
 private void _calculateAchievementsForUser(SmartPlaneUser user)
 {
     foreach (var achievementCalculator in _achievementCalculators)
     {
         try
         {
             _logger.Log($"start calculation with the calculator: {achievementCalculator.GetType().Name} ",
                 LogLevel.Info);
             achievementCalculator.CalculateAchievementProgress(user);
         }
         catch (Exception e)
         {
             _logger.Log(
                 $"The calculation of the AchievementCalculator {achievementCalculator.GetType().Name}, throws a exception: {e.Message}",
                 LogLevel.Error);
         }
     }
 }
コード例 #10
0
 protected override int CalculateProgress(SmartPlaneUser targetUser)
 {
     var restlessFlightDurations = AchievementCalculationHelper.GetDurationsOfRestlessFlyingTimes(targetUser);
     int progress = 0;
     long durationsSum = 0;
     foreach (var restlessFlightDuration in restlessFlightDurations)
     {
         if (restlessFlightDuration >= OnePercentStep)
         {
             durationsSum += restlessFlightDuration;
         }
     }
     progress = (int)durationsSum/OnePercentStep;
     if (progress >= 100)
     {
         return 100;
     }
     return (int)progress;
 }
コード例 #11
0
 /// <summary>
 /// Returns all RudderData for each passed flight
 /// </summary>
 /// <param name="targetUser"></param>
 /// <returns></returns>
 public static IEnumerable<IEnumerable<RudderData>> GetAllRudderDatasWithinConnections(SmartPlaneUser targetUser)
 {
     var flights = GetEndAndStartTimesOfAllConnections(targetUser);
     return flights.Select(flight => targetUser.RudderDatas.Where(x => x.TimeStamp >= flight.Item1 && x.TimeStamp <= flight.Item2));
 }
コード例 #12
0
 /// <summary>
 /// Calculates the time a plane is flying in the passed flight times
 /// </summary>
 /// <param name="flights">The start and end times of possible flights</param>
 /// <param name="targetUser"></param>
 /// <returns></returns>
 public static IEnumerable<long> GetFlightDurationTimes(IEnumerable<Tuple<long, long>> flights, SmartPlaneUser targetUser)
 {
     return flights.Select(flight => CalculateFlightDuration(flight.Item1, flight.Item2, targetUser));
 }
コード例 #13
0
        /// <summary>
        /// Returns a list of tuples which indicates a start time and a end time of one session
        /// </summary>
        /// <param name="targetUser"></param>
        /// <returns></returns>
        public static IEnumerable<Tuple<long, long>> GetEndAndStartTimesOfAllConnections(SmartPlaneUser targetUser)
        {
            var startTimes = targetUser.ConnectedDatas.Where(c => c.Value).Select(c => c.TimeStamp).ToList();
            var endTimes = targetUser.ConnectedDatas.Where(c => c.Value == false).Select(c => c.TimeStamp).ToList();
            foreach (var startTime in startTimes)
            {
                var endTimesAfterStartTime = endTimes.Where(e => e >= startTime).ToList();

                if (endTimesAfterStartTime.Any())
                {
                    var endTime = endTimesAfterStartTime.Min();
                    endTimes.Remove(endTime);
                    yield return new Tuple<long, long>(startTime, endTime);
                    continue;
                }
                //If there is no en connection for the start connection and the start connection is the last start connection, the use the last
                //Motor data time stamp as end time because the plane is actually flying
                if (startTimes.Any(x => x > startTime))
                {
                    continue;
                }
                var motorDatas = targetUser.MotorDatas.Where(x => x.Value != 0).Where(x => x.TimeStamp > startTime).ToList();
                if (motorDatas.Any() == false)
                {
                    continue;
                }
                var lastMotorData = motorDatas.Max(x => x.TimeStamp);
                yield return new Tuple<long, long>(startTime, lastMotorData);
            }
        }
コード例 #14
0
 private void _calculateRankingForUser(SmartPlaneUser user)
 {
     user.RankingPoints = 0;
     //The first version of ranking calculation uses a constant for each achievement. So all achievements got the same points
     const int achievementPoints = 1;
     foreach (var achievement in user.Achievements)
     {
         user.RankingPoints += achievementPoints*achievement.Progress;
     }
 }
コード例 #15
0
        /// <summary>
        /// Returns the Durations of Times without same Motor values
        /// </summary>
        /// <param name="targetUser"></param>
        /// <returns></returns>
        public static IEnumerable<long> GetDurationsOfRestlessFlyingTimes(SmartPlaneUser targetUser)
        {
            var motorDatasInRange = GetAllMotorDatasWithinConnections(targetUser).ToList();
            if (motorDatasInRange.Any() == false || motorDatasInRange.First().Any() == false)
            {
                yield break;
            }

            foreach (var motorDatas in motorDatasInRange)
            {
                long? startTime = 0;
                long endtime = 0;
                long? duration;
                var lastValue = 999; //definitely different from first value encountered

                foreach (var motorData in motorDatas)
                {
                    if (motorData.Value != lastValue)
                    {
                        lastValue = motorData.Value;
                        endtime = motorData.TimeStamp;
                    }
                    else
                    {
                        duration = endtime - startTime;
                        if (duration > 0)
                        {
                            yield return (long)duration;
                        }
                        startTime = motorData.TimeStamp;
                    }
                }
                duration = endtime - startTime;
                if (duration > 0)
                {
                    yield return (long) duration;
                }
            }
        }
コード例 #16
0
 /// <summary>
 /// Method which calculates the progress of this achievement with the passed SmartPlaneUser
 /// </summary>
 /// <param name="targetUser"></param>
 /// <returns></returns>
 protected abstract int CalculateProgress(SmartPlaneUser targetUser);
コード例 #17
0
 protected override int CalculateProgress(SmartPlaneUser targetUser)
 {
     var connectionTimes = targetUser.ConnectedDatas.Count(c => c.Value);
     var percent = connectionTimes / OnePercentStep;
     return percent > 100 ? 100 : percent;
 }
コード例 #18
0
 /// <summary>
 /// Returns the length of the times a plane was flying with maximum motor value
 /// </summary>
 /// <param name="targetUser"></param>
 /// <returns></returns>
 public static IEnumerable<long> GetDurationsWithMaxMotor(SmartPlaneUser targetUser)
 {
     const int motorMax = 253; // Tolerance: 100% can be 253 or 255
     var motorDatasInRange = GetAllMotorDatasWithinConnections(targetUser);
     foreach (var motorDatas in motorDatasInRange)
     {
         long? startTime = null;
         long endTime = 0;
         long? duration;
         foreach (var motorData in motorDatas)
         {
             endTime = motorData.TimeStamp;
             if (motorData.Value < motorMax)
             {
                 duration = endTime - startTime;
                 if (duration > 0)
                 {
                     yield return (long)duration;
                 }
                 startTime = null;
                 endTime = 0;
             }
             else
             {
                 if (startTime == null)
                 {
                     startTime = motorData.TimeStamp;
                 }
             }
         }
         duration = endTime - startTime;
         if (duration > 0)
         {
             yield return (long) duration;
         }
     }
 }