private async Task StartSimulation()
{
if(Simulator.SongData==null)
{
MessageBox.Show("楽曲を選んでください");
return;
}
if (Simulator.Unit == null)
{
MessageBox.Show("ユニットを選んでください");
return;
}
if (Runs < 1 || Runs > 1000000)
{
MessageBox.Show("試行回数は1から1,000,000までである必要があります");
return;
}
Note[] pattern = null;
if (UtilizeActualPattern)
{
pattern = await new PatternProvider().GetPattern(Simulator.Song, Simulator.SongData.Difficulty, Simulator.SongData.Notes);
if (pattern == null)
{
MessageBox.Show($"{Simulator.Song.Title}({Simulator.SongData.Difficulty})の譜面データが見つかりませんでした。");
return;
}
}
SimulationCompleted = false;
var results = new ConcurrentBag<SimulationResult>();
await Task.Run(() => Parallel.For(1, Runs+1, i => results.Add(Simulator.StartSimulation(RandomFactory.Create(), i, pattern == null ? null : new Queue<Note>(pattern)))));
MaxScore = results.Max(x=>x.Score);
MaxScorePerNote = results.Max(x => x.ScorePerNote);
MinScore = results.Min(x => x.Score);
MinScorePerNote = results.Min(x => x.ScorePerNote);
AverageScore = (int)results.Average(x => x.Score);
AverageScorePerNote = (int)results.Average(x => x.ScorePerNote);
ScoreDistribution = results.GroupBy(x => (int)Math.Floor(x.Score / 10000.0)).OrderBy(x => x.Key).ToDictionary(x => x.Key, x => (double)x.Count() / results.Count);
StandardDeviation = Math.Round(Math.Sqrt(results.Sum(x => Math.Pow(x.Score - AverageScore, 2))) / results.Count);
int idx = 1;
var duration = results.First().Duration;
ActualTriggerRatio = Simulator.Unit.Slots.ToDictionary(s => $"スロット{idx++}",
s => s == null ? 0 : results.SelectMany(x => x.TriggeredSkills).Where(x => x.Who == s).Count() / (results.Count * Math.Floor((duration - 1.0) / s.Skill.Interval)));
SimulationResults = results.OrderBy(x => x.Id).Take(100).ToList();
SelectedResult = SimulationResults[0];
SimulationCompleted = true;
}