Files
h-school/src/HSchool.People/SchoolDemand.cs
T
2026-08-18 23:51:10 +03:00

71 lines
2.3 KiB
C#

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);
/// <summary>
/// How many pupils and staff a map asks for. Homeroom rooms with pupil slots become roster
/// classes; every <see cref="RoomDef.Positions"/> entry is a staff opening.
/// </summary>
public sealed class SchoolDemand
{
internal SchoolDemand(
IReadOnlyList<SchoolClass> classes,
IReadOnlyList<PupilSeat> seats,
IReadOnlyList<StaffOpening> staff)
{
Classes = classes;
Seats = seats;
Staff = staff;
}
public IReadOnlyList<SchoolClass> Classes { get; }
public IReadOnlyList<PupilSeat> Seats { get; }
public IReadOnlyList<StaffOpening> Staff { get; }
public static SchoolDemand From(DefCatalog catalog, MapLayout map)
{
var classrooms = new List<(RoomNode Room, int Slots)>();
var staff = new List<StaffOpening>();
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<PupilSeat>();
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);
}
}