namespace HSchool.People; public readonly record struct StaffOpening(string RoomId, string Position); public readonly record struct PupilSeat(string ClassId, string RoomId, int Year, string Letter); /// /// How many pupils and staff a map asks for. Homeroom rooms with pupil slots become roster /// classes; every entry is a staff opening. /// public sealed class SchoolDemand { internal SchoolDemand( IReadOnlyList classes, IReadOnlyList seats, IReadOnlyList staff) { Classes = classes; Seats = seats; Staff = staff; } public IReadOnlyList Classes { get; } public IReadOnlyList Seats { get; } public IReadOnlyList Staff { get; } public static SchoolDemand From(DefCatalog catalog, MapLayout map) { var classrooms = new List<(RoomNode Room, int Slots)>(); var staff = new List(); foreach (var room in map.Rooms) { var slots = RoomOccupancy.PupilSlots(catalog, room); if (catalog.Rooms.TryGetValue(room.Def, out var def)) { foreach (var position in def.Positions) { staff.Add(new StaffOpening(room.Id, position)); } if (slots > 0 && def.Homeroom) { classrooms.Add((room, slots)); } } } const string letters = "АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЭЮЯ"; var classes = new SchoolClass[classrooms.Count]; var seats = new List(); for (var i = 0; i < classrooms.Count; i++) { var (room, capacity) = classrooms[i]; var year = (i % 11) + 1; var letterIndex = i / 11; var letter = letterIndex < letters.Length ? letters[letterIndex].ToString() : "?"; var classId = $"class-{room.Id}"; classes[i] = new SchoolClass(classId, year, letter, room.Id, capacity, []); for (var seat = 0; seat < capacity; seat++) { seats.Add(new PupilSeat(classId, room.Id, year, letter)); } } return new SchoolDemand(classes, seats, staff); } }