using ProjectQuint.Core.Charts; namespace ProjectQuint.Probes; public readonly record struct ReplayInput(double Time, int Lane, bool Pressed); public sealed record SyntheticWorkload(PlayableNote[] Notes, ReplayInput[] Events, uint Seed) { public static SyntheticWorkload Create(int noteCount, uint seed) { if (noteCount < 1 || noteCount > 100_000) throw new ArgumentOutOfRangeException(nameof(noteCount), "Use 1 to 100000 notes."); var notes = new PlayableNote[noteCount]; var events = new List(noteCount * 2); var state = seed; for (var index = 0; index < noteCount; index++) { // Explicit integer PRNG makes the workload independent of System.Random versions. state = unchecked(state * 1664525u + 1013904223u); var time = 1.0 + index * 0.125; var longNote = index % 11 == 0; var note = new PlayableNote { Id = index + 1, Lane = index % 4, StartTime = time, EndTime = time + (longNote ? 0.375 : 0), }; notes[index] = note; // Deliberate misses and early releases exercise failure as well as perfect play. if (index % 17 == 0) continue; var pressTime = time + ((int)(state % 7) - 3) * 0.01; events.Add(new ReplayInput(pressTime, note.Lane, true)); events.Add(new ReplayInput(longNote ? note.EndTime - (index % 23 == 0 ? 0.2 : 0) : pressTime + 0.02, note.Lane, false)); } return new SyntheticWorkload(notes, events.OrderBy(e => e.Time) .ThenBy(e => e.Pressed).ThenBy(e => e.Lane).ToArray(), seed); } }