diff --git a/HFUTCourseSimulation/HFUTCourseSimulation.csproj b/HFUTCourseSimulation/HFUTCourseSimulation.csproj
index 0cc3b3c..2997690 100644
--- a/HFUTCourseSimulation/HFUTCourseSimulation.csproj
+++ b/HFUTCourseSimulation/HFUTCourseSimulation.csproj
@@ -74,14 +74,12 @@
MSBuild:Compile
-
EditCourse.xaml
EditSchedule.xaml
-
diff --git a/HFUTCourseSimulation/Kernel/Arranger.cs b/HFUTCourseSimulation/Kernel/Arranger.cs
index fafb2fd..c27361c 100644
--- a/HFUTCourseSimulation/Kernel/Arranger.cs
+++ b/HFUTCourseSimulation/Kernel/Arranger.cs
@@ -98,70 +98,48 @@ namespace HFUTCourseSimulation.Kernel {
/// 如果检查无误,返回检查后的结果,否则返回null
private Semester CheckSemester() {
// 检查Semester
+ reporter.Info($"正在检查学期");
if (semester.StartDate.DayOfWeek != DayOfWeek.Monday) {
reporter.Error($"起始日期{semester.StartDate:yyyy-MM-dd}不是星期一");
return null;
}
- int weekCount;
- if (int.TryParse(semester.WeekCount, out weekCount)) {
- if (weekCount <= 0) {
- reporter.Error($"周数{semester.WeekCount}超出范围(必须大于0)");
- return null;
- }
- } else {
- reporter.Error($"周数{semester.WeekCount}不是有效数字");
- return null;
- }
- int indexCount;
- if (int.TryParse(semester.IndexCount, out indexCount)) {
- if (indexCount <= 0) {
- reporter.Error($"节次数{semester.IndexCount}超出范围(必须大于0)");
- return null;
- }
- } else {
- reporter.Error($"节次数{semester.IndexCount}不是有效数字");
- return null;
- }
- int breakfastAt, lunchAt, dinnerAt;
- if (int.TryParse(semester.BreakfastAt, out breakfastAt)) {
- if (breakfastAt < 0 || breakfastAt > indexCount) {
- reporter.Error($"早餐时间点{semester.BreakfastAt}超出范围(必须大于等于0且小于等于节次数)");
- return null;
- }
- } else {
- reporter.Error($"早餐时间点{semester.BreakfastAt}不是有效数字");
- return null;
- }
- if (int.TryParse(semester.LunchAt, out lunchAt)) {
- if (lunchAt < breakfastAt || lunchAt > indexCount) {
- reporter.Error($"午餐时间点{semester.LunchAt}超出范围(必须大于等于早餐时间点且小于等于节次数)");
- return null;
- }
- } else {
- reporter.Error($"午餐时间点{semester.LunchAt}不是有效数字");
- return null;
- }
- if (int.TryParse(semester.DinnerAt, out dinnerAt)) {
- if (dinnerAt < lunchAt || dinnerAt > indexCount) {
- reporter.Error($"晚餐时间点{semester.DinnerAt}超出范围(必须大于等于午餐时间点且小于等于节次数)");
- return null;
- }
- } else {
- reporter.Error($"晚餐时间点{semester.DinnerAt}不是有效数字");
- return null;
- }
-
+ var rv = CheckInteger(semester.WeekCount, 1, 100, "周数", "0 < N");
+ if (rv is null) return null;
+ int weekCount = rv.Value;
+ rv = CheckInteger(semester.IndexCount, 1, 100, "节次数", "0 < N");
+ if (rv is null) return null;
+ int indexCount = rv.Value;
+ rv = CheckInteger(semester.BreakfastAt, 0, indexCount, "早餐时间点", "0 <= N <= 节次数");
+ if (rv is null) return null;
+ int breakfastAt = rv.Value;
+ rv = CheckInteger(semester.LunchAt, breakfastAt, indexCount, "午餐时间点", "早餐时间点 <= N <= 节次数");
+ if (rv is null) return null;
+ int lunchAt = rv.Value;
+ rv = CheckInteger(semester.DinnerAt, lunchAt, indexCount, "晚餐时间点", "午餐时间点 <= N <= 节次数");
+ if (rv is null) return null;
+ int dinnerAt = rv.Value;
var courses = new List();
foreach (var course in semester.Courses) {
// 检查课程(实际上只有安排需要检查)
+ reporter.Info($"正在检查课程:{course.Name}");
+
var schedules = new List();
foreach (var schedule in course.Schedules) {
// 检查安排
- if
-
+ var week = CheckIntegerCollection(schedule.Week, 1, weekCount, "周", "1 <= N <= 周数");
+ var day = CheckIntegerCollection(schedule.Day, 1, 7, "星期", "1 <= N <= 7");
+ var index = CheckIntegerCollection(schedule.Index, 1, indexCount, "节次", "1 <= N <= 节次数");
+ // 如果格式均正确,就添加这个安排
+ if (!(week is null || day is null || index is null)) {
+ schedules.Add(new Schedule() {
+ week = week,
+ day = day,
+ index = index
+ });
+ }
}
// OK,插入课程
@@ -184,6 +162,96 @@ namespace HFUTCourseSimulation.Kernel {
courses = courses
};
}
+ ///
+ /// 检查整数的辅助函数。
+ /// 检查范围时含提供的最小值min和最大值max。
+ /// field_name是字段的名称,field_require是字段的要求,均用于用户提示。
+ /// 返回null表示检查失败,否则返回检查好的值。
+ ///
+ private int? CheckInteger(string s, int min, int max, string field_name, string field_require) {
+ if (int.TryParse(semester.WeekCount, out int rv)) {
+ if (rv < min || rv > max) {
+ reporter.Error($"{field_name}的值“{s}”超出范围。要求:{field_require}");
+ return null;
+ } else {
+ return rv;
+ }
+ } else {
+ reporter.Error($"{field_name}的值“{s}”不是有效数字");
+ return null;
+ }
+ }
+ ///
+ /// 整数集合的两种类型
+ ///
+ private enum IntegerCollectionKind {
+ Individual,
+ Range
+ }
+ ///
+ /// 检查整数集合的辅助函数,即检查Schedule中的三个字段Week,Day和Index的格式。
+ /// 各类参数含义与上面函数相同,只不过是作用到每一项上。
+ ///
+ private IEnumerable CheckIntegerCollection(string s, int min, int max, string field_name, string field_require) {
+ // 两种整数集合所特有的字符常量,用于分割和分析
+ const char COMMA = ',';
+ const char DASH = '-';
+
+ // 分析文本组成,决定其整数集合类型
+ IntegerCollectionKind kind;
+ if (s.Contains(COMMA)) {
+ kind = IntegerCollectionKind.Individual;
+ } else if (s.Contains(DASH)) {
+ kind = IntegerCollectionKind.Range;
+ } else {
+ reporter.Error($"{field_name}的值“{s}”无法被解析");
+ return null;
+ }
+
+ // 根据整数集合类型,决定分割用字符
+ char split_char;
+ switch (kind) {
+ case IntegerCollectionKind.Individual:
+ split_char = COMMA;
+ break;
+ case IntegerCollectionKind.Range:
+ split_char = DASH;
+ break;
+ default:
+ return null;
+ }
+
+ // 开始分割文本并将每一项转换为整数,同时检查其范围
+ var ints = new List();
+ foreach (var part in s.Split(split_char).Select((i) => i.Trim())) {
+ if (int.TryParse(part, out int rv)) {
+ if (rv < min || rv > max) {
+ reporter.Error($"{field_name}的值“{s}”包含的整数超出范围。要求:{field_require}");
+ return null;
+ } else {
+ ints.Add(rv);
+ }
+ } else {
+ reporter.Error($"{field_name}的值“{s}”包含无效的整数");
+ return null;
+ }
+ }
+
+ // 按整数集合类型进行收尾检查并返回
+ switch (kind) {
+ case IntegerCollectionKind.Individual:
+ return new IndividualInt(ints);
+ case IntegerCollectionKind.Range:
+ if (ints.Count != 2) {
+ reporter.Error($"{field_name}的值“{s}”不是有效的整数范围表达式");
+ return null;
+ } else {
+ return new RangedInt(ints[0], ints[1]);
+ }
+ default:
+ return null;
+ }
+ }
///
/// 安排课程