public PatternAnalyzer(List <Note> notes, List <LongNote> lns, int key, List <Tuple <double, double> > bpms, bool specialstyle) { Key = key; Count = notes.Count + lns.Count; SpecialStyle = specialstyle; TotalNotes = new List <INote> [key]; Times = new Dictionary <int, List <Tuple <int, int> > >(); JackSectionList = new List <List <INote> >(); NewJacks = bpms.Select(cur => Tuple.Create(Math.Min(BpmConverter.BpmToMilliseconds(cur.Item1, 1), BpmConverter.BpmToMilliseconds(75)), cur.Item2)).ToList(); var tempDic = new Dictionary <int, List <Tuple <int, int> > >(); for (var i = 0; i < key; i++) { TotalNotes[i] = new List <INote>(); } foreach (var cur in notes) { TotalNotes[cur.Lane].Add(cur); if (!tempDic.ContainsKey(cur.Time)) { tempDic.Add(cur.Time, new List <Tuple <int, int> >()); } tempDic[cur.Time].Add(Tuple.Create(cur.Lane, 0)); } foreach (var cur in lns) { TotalNotes[cur.Lane].Add(cur); if (!tempDic.ContainsKey(cur.Time)) { tempDic.Add(cur.Time, new List <Tuple <int, int> >()); } tempDic[cur.Time].Add(Tuple.Create(cur.Lane, cur.EndTime)); } foreach (var cur in TotalNotes) { cur.Sort(new NoteComparer()); } var varList = tempDic.Keys.ToList(); varList.Sort(); foreach (var cur in varList) { var temp = tempDic[cur]; temp.Sort(new TupleComparer()); Times.Add(cur, temp); } GetJackSections(); }
public static double CalcJackScore(PatternAnalyzer pat) { var jackScore = 0.0; foreach (var curJack in pat.JackSectionList) { for (var i = 0; i < curJack.Count; i++) { double gap1 = 0, gap2 = 0; if (i > 0) { gap1 = GetJackBpmScore(BpmConverter.MillisecondsToBpm(curJack[i].Time - curJack[i - 1].Time)); } if (i < curJack.Count - 1) { gap2 = GetJackBpmScore(BpmConverter.MillisecondsToBpm(curJack[i + 1].Time - curJack[i].Time)); } jackScore += (gap1 + gap2) / (Math.Abs(gap1) < 0.001 || Math.Abs(gap2) < 0.001 ? 1 : 2) * GetJackTimesScore(curJack.Count); } } return(jackScore / pat.Count); }
public static Metadata Parse(string filename) { var data = new Metadata(); using (var reader = new StreamReader(filename)) { string currentLine; while ((currentLine = reader.ReadLine()) != null) { // Get Mode. If not 3, it's not a mania mode. if (currentLine.StartsWith("Mode:")) { if (currentLine.Split(' ')[1] != "3") { throw new InvalidModeException("It's not a Mania beatmap."); } } // Special Style. if (currentLine.StartsWith("SpecialStyle:")) { data.SpecialStyle = Convert.ToInt32(currentLine.Split(' ')[1]) == 1; } // Title if (currentLine.StartsWith("TitleUnicode:")) { data.Title = currentLine.Substring(currentLine.IndexOf(':') + 1); } // Artist if (currentLine.StartsWith("ArtistUnicode:")) { data.Artist = currentLine.Substring(currentLine.IndexOf(':') + 1); } // Creator if (currentLine.StartsWith("Creator:")) { data.Creator = currentLine.Substring(currentLine.IndexOf(':') + 1); } // Difficulty if (currentLine.StartsWith("Version:")) { data.Diff = currentLine.Substring(currentLine.IndexOf(':') + 1); } // HP if (currentLine.StartsWith("HPDrainRate:")) { data.Hp = Convert.ToDouble(currentLine.Split(':')[1]); } // Keys if (currentLine.StartsWith("CircleSize:")) { data.Keys = Convert.ToInt32(currentLine.Split(':')[1]); } // Od if (currentLine.StartsWith("OverallDifficulty:")) { data.Od = Convert.ToDouble(currentLine.Split(':')[1]); } // BPM if (currentLine.StartsWith("[TimingPoints]")) { string cur; var bpms = new List <Tuple <double, double> >(); while ((cur = reader.ReadLine()) != null) { if (cur == "") { break; } var offset = Convert.ToDouble(cur.Split(',')[0]); // Osu stores BPM as 'Miliseconds/Beat'. var msPerBeat = Convert.ToDouble(cur.Split(',')[1]); if (msPerBeat < 0) { continue; } var curBpm = BpmConverter.MillisecondsToBpm(msPerBeat, 1); bpms.Add(Tuple.Create(curBpm, offset)); } data.Bpms = bpms; // The rest part doesn't have any metadata. break; } } } return(data); }