namespace HSchool.People; /// /// Whether a generated or loaded roster still fills this map. A mismatch means the file is stale /// relative to the layout — the school must not start and the file must stay untouched. /// Staff openings are the player's to fill; only pupil seats have to be occupied. /// public static class RosterFit { public static bool Matches(Roster roster, SchoolDemand demand) { if (roster.Classes.Count != demand.Classes.Count || roster.People.Count(person => person.IsStudent) != demand.Seats.Count) { return false; } var classesByRoom = roster.Classes.ToDictionary(schoolClass => schoolClass.RoomId, StringComparer.Ordinal); foreach (var expected in demand.Classes) { if (!classesByRoom.TryGetValue(expected.RoomId, out var actual) || actual.Capacity != expected.Capacity || actual.PupilIds.Count != expected.Capacity) { return false; } } return true; } }