public static DebugSongScore?DebugMap(BSMap map) { int len = (int)BSMath.Ceiling(map.Data.Notes.Max(x => (float?)x.Time) ?? 0); if (len == 0) { //throw new InvalidOperationException("Invalid Map"); return(null); } var timedRed = ProcessColor(map, NoteColor.Red); var timedBlue = ProcessColor(map, NoteColor.Blue); DebugHitScore[] DebugHits(IEnumerable <ScoredClusterHit> arr) => arr.Select(x => { var d = new DebugHitScore(); d.Set(x); return(d); }).ToArray(); var debugRed = DebugHits(timedRed); var debugBlue = DebugHits(timedBlue); return(new DebugSongScore { Name = map.Info.SongName, DifficultyName = map.MapInfo.Difficulty, DataRed = debugRed, DataBlue = debugBlue, }); }
public static SongScore AnalyzeMap(BSMap map) { int len = (int)BSMath.Ceiling(map.Data.Notes.Max(x => (float?)x.Time) ?? 0); if (len == 0) { return(new SongScore(average: 0, max: 0, graph: Array.Empty <AggregatedHit>())); } var scoredRed = ProcessColor(map, NoteColor.Red); var scoredBlue = ProcessColor(map, NoteColor.Blue); var timedRed = ConvertToFixedTimeBlocks(scoredRed, len); var timedBlue = ConvertToFixedTimeBlocks(scoredBlue, len); var combined = new AggregatedHit[len]; for (int i = 0; i < len; i++) { int cnt = timedRed[i].HitDifficulty > 0 && timedBlue[i].HitDifficulty > 0 ? 2 : 1; combined[i] = (timedRed[i] + timedBlue[i]) / cnt; } var totalDifficulty = combined.Select(h => h.TotalDifficulty()).ToList(); return(new SongScore ( average: totalDifficulty.Average(), max: totalDifficulty.Max(), graph: combined )); }
public static ScoredClusterHit[] ProcessColor(BSMap map, NoteColor color) { var json = map.Data.Notes.Where(n => n.Type == color).ToArray(); var hits = json.Select(x => Hit.FromSingle(map, x)).ToArray(); var clustered = ClusterNotes(hits); var scored = AnalyzeNotes(clustered); return(scored); }
public static Hit FromSingle(BSMap map, JsonNote note) { return(new( note.Position() + .5f + note.Rotation() * -.5f, note.Position() + .5f + note.Rotation() * .5f, note.Time, map.BeatTimeToRealTime(note.Time), new List <JsonNote> { note } )); }
public static TimeSpan BeatTimeToRealTime(this BSMap map, float beat) => TimeSpan.FromMinutes(beat / map.Info.BPM);
public static float RealTimeToBeatTime(this BSMap map, TimeSpan time) => (float)(time.TotalMinutes * map.Info.BPM);