using System; using System.Collections.Generic; using System.Linq; namespace spplus; public class CourseCrafter { public class CourseInstance { public Sport Sport = null!; public int Remaining; public List Students = new(); } public static List<(int Semester, CourseInstance Instance)> GeneratedCourses = new(); public static void Craft() { GeneratedCourses = new(); int globalCount = 0; List<(Sport, List)> initial_sportlist = new(); List[] students_in_semester = new List[4] { new(), new(), new(), new() }; foreach (var sp in Settings.Instance.Sports) { initial_sportlist.Add((sp, new())); } foreach (Student s in Settings.Instance.Students) { foreach (var sp in s.SelectedCourseNames) { foreach (var item in initial_sportlist) { if (item.Item1.AlternativeNames.Contains(sp)) { item.Item2.Add(s.ID); break; } } } } while (!requestExit()) { Console.WriteLine($"Calculating... ({globalCount})"); foreach (var item in initial_sportlist) { if (item.Item2.Count >= item.Item1.MinStudents) { int semester = getSemesterForSport(item.Item1); if (semester <= 0) goto semeq0; var inst = new CourseInstance(); inst.Sport = item.Item1; inst.Students = new List(); // int dist = 1; for (int i = item.Item2.Count - 1; i >= 0; i--) { if (inst.Students.Count >= inst.Sport.MaxStudents) break; string stud = item.Item2[i]; if (!students_in_semester[semester - 1].Contains(stud)) { inst.Students.Add(stud); students_in_semester[semester - 1].Add(stud); item.Item2.RemoveAt(i); } } if (inst.Students.Count < inst.Sport.MinStudents) { // Rückgängig machen foreach (var s in inst.Students) { students_in_semester[semester-1].Remove(s); item.Item2.Add(s); } continue; // Kurs nicht erstellen } GeneratedCourses.Add((semester, inst)); MainWindow.Instance.TbResultLog.Text += ($"{semester} -> {inst.Students.Count}\n"); MainWindow.Instance.TbResultLog.Text += ($"{students_in_semester[0].Count} - {students_in_semester[1].Count} - {students_in_semester[2].Count} - {students_in_semester[3].Count}\n\n"); } semeq0: ; } // foreach (var item in initial_sportlist) // { // Console.WriteLine($"{item.Item1.Name}: {item.Item2.Count}x gewählt"); // } } // Kurse auffüllen (mit restl. Leuten) foreach (var item in initial_sportlist) { if (item.Item2.Count > 0) { foreach (var ci in GeneratedCourses) { if (item.Item1.ID == ci.Instance.Sport.ID) { int semester = ci.Semester; List added = new(); foreach (string stud in item.Item2) { if (ci.Instance.Students.Count >= ci.Instance.Sport.MaxStudents) break; if (!students_in_semester[semester-1].Contains(stud)) { ci.Instance.Students.Add(stud); students_in_semester[semester-1].Add(stud); //ci.Instance.Students.Add(stud); added.Add(stud); } } // Hinzugefügte aus Initialkurs entfernen foreach (string s in added) { item.Item2.Remove(s); } } MainWindow.Instance.TbResultLog.Text += ($"{ci.Semester} -> {ci.Instance.Students.Count}\n"); MainWindow.Instance.TbResultLog.Text += ($"{students_in_semester[0].Count} - {students_in_semester[1].Count} - {students_in_semester[2].Count} - {students_in_semester[3].Count}\n\n"); } } } int getSemester() { //int sem = 0; if (GeneratedCourses.Count == 0) return 1; // zunächst im ersten Semester beginnen int[] semcount = new int[4] {0,0,0,0}; // Anzahl der generierten Kurse im jeweiligen Semester foreach (var inst in GeneratedCourses) { semcount[inst.Semester - 1]++; // ...füllen } for (int i = 0; i= Settings.Instance.NumCoursesPerSemester * 4) return true; // // max Anzahl in allen Semestern // foreach(int sem in new[]{1,2,3,4}) // { // int count = 0; // foreach (var inst in GeneratedCourses) // { // if (inst.Semester == sem) count++; // } // // if (sem >= Settings.Instance.NumCoursesPerSemester); // } int low = 0; foreach (var item in initial_sportlist) { if (item.Item2.Count < item.Item1.MinStudents) low++; } if (low >= initial_sportlist.Count) return true; if (globalCount >= 12) return true; return false; } foreach (var tuple in initial_sportlist) { MainWindow.Instance.TbResultTextout.Text += $"{tuple.Item1}: {tuple.Item2.Count} remaining\n"; } int getSemesterForSport(Sport sp) { int[] semcount = new int[4] {0,0,0,0}; foreach (var inst in GeneratedCourses) { semcount[inst.Semester - 1]++; } for (int i = 0; i < 4; i++) { // 1. Ist der Sport in diesem Semester erlaubt? if (sp.Semester[i] == 0) continue; // 2. Ist noch Platz für Kurse? if (semcount[i] < Settings.Instance.NumCoursesPerSemester) { return i + 1; } } return 0; } } public static string GenerateStatistics() { string sb = $"Generierte Kurse: {GeneratedCourses.Count}\n\n"; foreach (var genc in GeneratedCourses) { sb += $"Sem. {genc.Semester}: {genc.Instance.Sport.Name} ({genc.Instance.Students.Count} SuS)\n"; } return sb; } public static string GenerateStatisticsOld() { var settings = Settings.Instance; var students = settings.Students; if (GeneratedCourses == null || GeneratedCourses.Count == 0) return "Keine Kurse generiert."; int semesterCount = students .Where(s => s.Result != null) .Select(s => s.Result!.Count) .DefaultIfEmpty(0) .Max(); var sb = new System.Text.StringBuilder(); sb.AppendLine($"Anzahl generierter Kurse: {GeneratedCourses.Count}"); sb.AppendLine("Übersicht:"); // ===== Kursübersicht ===== var grouped = GeneratedCourses .GroupBy(g => new { g.Semester, g.Instance.Sport.Name }) .OrderBy(g => g.Key.Semester) .ThenBy(g => g.Key.Name); foreach (var group in grouped) { int counter = 1; foreach (var entry in group) { int semester = group.Key.Semester + 1; string sportName = group.Key.Name; string number = counter.ToString("D2"); int count = entry.Instance.Students.Count; sb.AppendLine( $"Semester {semester}: {sportName} {number}: {count} Schüler*innen" ); counter++; } } sb.AppendLine(); sb.AppendLine("Fehlerübersicht:"); // ===== Fehler pro Semester ===== for (int sem = 0; sem < semesterCount; sem++) { int errors = students.Count(st => st.Result != null && st.Result.Count > sem && st.Result[sem] == "Fehler"); sb.AppendLine($"Semester {sem + 1}: {errors} Fehler"); } return sb.ToString(); } }