예제 #1
0
        public override double Calculate(Dictionary <string, double> categoryDifficulty = null)
        {
            OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap((List <OsuHitObject>)Beatmap.HitObjects, TimeRate);

            Skill[] skills =
            {
                new Aim(),
                new Speed()
            };
            double sectionLength = section_length * TimeRate;

            // The first object doesn't generate a strain, so we begin with an incremented section end
            double currentSectionEnd = 2 * sectionLength;

            foreach (OsuDifficultyHitObject h in beatmap)
            {
                while (h.BaseObject.StartTime > currentSectionEnd)
                {
                    foreach (Skill s in skills)
                    {
                        s.SaveCurrentPeak();
                        s.StartNewSectionFrom(currentSectionEnd);
                    }

                    currentSectionEnd += sectionLength;
                }

                foreach (Skill s in skills)
                {
                    s.Process(h);
                }
            }

            double aimRating      = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
            double speedRating    = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
            double avgAimRating   = skills[0].AverageDifficultyValue() * aimRating;
            double avgSpeedRating = skills[1].AverageDifficultyValue() * speedRating;

            double starRating    = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;
            double avgStarRating = avgAimRating + avgSpeedRating + Math.Abs(avgAimRating - avgSpeedRating) / 2;

            if (categoryDifficulty != null)
            {
                categoryDifficulty.Add("Aim", aimRating);
                categoryDifficulty.Add("Speed", speedRating);
                // categoryDifficulty.Add("Average Aim", avgAimRating);
                //categoryDifficulty.Add("Average Speed", avgSpeedRating);
                categoryDifficulty.Add("Average Star", avgStarRating);
            }

            return(starRating);
        }
        public override double Calculate(Dictionary <string, double> categoryDifficulty = null)
        {
            OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Beatmap.HitObjects, TimeRate);

            Skill[] skills =
            {
                new Jump(),
                new Speed(),
                new Flow(),
            };

            double sectionEnd = section_length / TimeRate;

            foreach (OsuDifficultyHitObject h in beatmap)
            {
                while (h.BaseObject.StartTime > sectionEnd)
                {
                    foreach (Skill s in skills)
                    {
                        s.SaveCurrentPeak();
                        s.StartNewSectionFrom(sectionEnd);
                    }

                    sectionEnd += section_length;
                }

                foreach (Skill s in skills)
                {
                    s.Process(h);
                }
            }

            double jumpRating  = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
            double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
            double flowRating  = Math.Sqrt(skills[2].DifficultyValue()) * difficulty_multiplier;

            double[] list = { jumpRating, speedRating, flowRating };
            double   max  = System.Linq.Enumerable.Max <double>(list);
            double   min  = System.Linq.Enumerable.Min <double>(list);

            double starRating = (jumpRating + speedRating + flowRating) * 2 / 3 + Math.Abs(max - min) / 2;

            if (categoryDifficulty != null)
            {
                categoryDifficulty.Add("Jump", jumpRating);
                categoryDifficulty.Add("Speed", speedRating);
                categoryDifficulty.Add("Flow", flowRating);
            }

            return(starRating);
        }
        public override double Calculate(Dictionary <string, double> categoryDifficulty = null)
        {
            OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap(Beatmap.HitObjects, TimeRate);

            Skill[] skills =
            {
                new Aim(),
                new Speed()
            };

            double sectionEnd = section_length / TimeRate;

            foreach (OsuDifficultyHitObject h in beatmap)
            {
                while (h.BaseObject.StartTime > sectionEnd)
                {
                    foreach (Skill s in skills)
                    {
                        s.SaveCurrentPeak();
                        s.StartNewSectionFrom(sectionEnd);
                    }

                    sectionEnd += section_length;
                }

                foreach (Skill s in skills)
                {
                    s.Process(h);
                }
            }

            double aimRating   = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
            double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;

            double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;

            if (categoryDifficulty != null)
            {
                categoryDifficulty.Add("Aim", aimRating);
                categoryDifficulty.Add("Speed", speedRating);
            }

            return(starRating);
        }
예제 #4
0
        protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate)
        {
            OsuDifficultyBeatmap difficultyBeatmap = new OsuDifficultyBeatmap(beatmap.HitObjects.Cast <OsuHitObject>().ToList(), timeRate);

            Skill[] skills =
            {
                new Aim(),
                new Speed()
            };

            double sectionLength = section_length * timeRate;

            // The first object doesn't generate a strain, so we begin with an incremented section end
            double currentSectionEnd = 2 * sectionLength;

            foreach (OsuDifficultyHitObject h in difficultyBeatmap)
            {
                while (h.BaseObject.StartTime > currentSectionEnd)
                {
                    foreach (Skill s in skills)
                    {
                        s.SaveCurrentPeak();
                        s.StartNewSectionFrom(currentSectionEnd);
                    }

                    currentSectionEnd += sectionLength;
                }

                foreach (Skill s in skills)
                {
                    s.Process(h);
                }
            }

            double aimRating   = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
            double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
            double starRating  = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;

            return(new OsuDifficultyAttributes(mods, starRating)
            {
                AimStrain = aimRating,
                SpeedStrain = speedRating
            });
        }
예제 #5
0
        protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate)
        {
            if (!beatmap.HitObjects.Any())
            {
                return(new OsuDifficultyAttributes(mods, 0));
            }

            OsuDifficultyBeatmap difficultyBeatmap = new OsuDifficultyBeatmap(beatmap.HitObjects.Cast <OsuHitObject>().ToList(), timeRate);

            Skill[] skills =
            {
                new Aim(),
                new Speed()
            };

            double sectionLength = section_length * timeRate;

            // The first object doesn't generate a strain, so we begin with an incremented section end
            double currentSectionEnd = Math.Ceiling(beatmap.HitObjects.First().StartTime / sectionLength) * sectionLength;

            foreach (OsuDifficultyHitObject h in difficultyBeatmap)
            {
                while (h.BaseObject.StartTime > currentSectionEnd)
                {
                    foreach (Skill s in skills)
                    {
                        s.SaveCurrentPeak();
                        s.StartNewSectionFrom(currentSectionEnd);
                    }

                    currentSectionEnd += sectionLength;
                }

                foreach (Skill s in skills)
                {
                    s.Process(h);
                }
            }

            // The peak strain will not be saved for the last section in the above loop
            foreach (Skill s in skills)
            {
                s.SaveCurrentPeak();
            }

            double aimRating   = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
            double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
            double starRating  = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;

            // Todo: These int casts are temporary to achieve 1:1 results with osu!stable, and should be removed in the future
            double hitWindowGreat = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / timeRate;
            double preempt        = (int)BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate;

            int maxCombo = beatmap.HitObjects.Count;

            // Add the ticks + tail of the slider. 1 is subtracted because the head circle would be counted twice (once for the slider itself in the line above)
            maxCombo += beatmap.HitObjects.OfType <Slider>().Sum(s => s.NestedHitObjects.Count - 1);

            return(new OsuDifficultyAttributes(mods, starRating)
            {
                AimStrain = aimRating,
                SpeedStrain = speedRating,
                ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
                OverallDifficulty = (80 - hitWindowGreat) / 6,
                MaxCombo = maxCombo
            });
        }