refactor: finish arranger
This commit is contained in:
@ -1,140 +1,129 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HFUTCourseSimulation.Kernel.Data.Built;
|
||||
using HFUTCourseSimulation.Util;
|
||||
|
||||
namespace HFUTCourseSimulation.Kernel {
|
||||
|
||||
/// <summary>
|
||||
/// 一个标识符,用于指代学期中指定周的指定星期的指定节次
|
||||
/// </summary>
|
||||
internal class ArrangerSpot : IEquatable<ArrangerSpot> {
|
||||
public ArrangerSpot(int week, int day, int index) {
|
||||
this.week = week;
|
||||
this.day = day;
|
||||
this.index = index;
|
||||
}
|
||||
///// <summary>
|
||||
///// 一个标识符,用于指代学期中指定周的指定星期的指定节次
|
||||
///// </summary>
|
||||
//internal class ArrangerSpot : IEquatable<ArrangerSpot> {
|
||||
// public ArrangerSpot(int week, int day, int index) {
|
||||
// this.week = week;
|
||||
// this.day = day;
|
||||
// this.index = index;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// 教学周
|
||||
/// </summary>
|
||||
public int week;
|
||||
/// <summary>
|
||||
/// 星期几
|
||||
/// </summary>
|
||||
public int day;
|
||||
/// <summary>
|
||||
/// 节次
|
||||
/// </summary>
|
||||
public int index;
|
||||
// /// <summary>
|
||||
// /// 教学周
|
||||
// /// </summary>
|
||||
// public int week;
|
||||
// /// <summary>
|
||||
// /// 星期几
|
||||
// /// </summary>
|
||||
// public int day;
|
||||
// /// <summary>
|
||||
// /// 节次
|
||||
// /// </summary>
|
||||
// public int index;
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
return Equals(obj as ArrangerSpot);
|
||||
}
|
||||
// public override bool Equals(object obj) {
|
||||
// return Equals(obj as ArrangerSpot);
|
||||
// }
|
||||
|
||||
public bool Equals(ArrangerSpot other) {
|
||||
return !(other is null) &&
|
||||
week == other.week &&
|
||||
day == other.day &&
|
||||
index == other.index;
|
||||
}
|
||||
// public bool Equals(ArrangerSpot other) {
|
||||
// return !(other is null) &&
|
||||
// week == other.week &&
|
||||
// day == other.day &&
|
||||
// index == other.index;
|
||||
// }
|
||||
|
||||
public override int GetHashCode() {
|
||||
int hashCode = -206993699;
|
||||
hashCode = hashCode * -1521134295 + week.GetHashCode();
|
||||
hashCode = hashCode * -1521134295 + day.GetHashCode();
|
||||
hashCode = hashCode * -1521134295 + index.GetHashCode();
|
||||
return hashCode;
|
||||
}
|
||||
// public override int GetHashCode() {
|
||||
// int hashCode = -206993699;
|
||||
// hashCode = hashCode * -1521134295 + week.GetHashCode();
|
||||
// hashCode = hashCode * -1521134295 + day.GetHashCode();
|
||||
// hashCode = hashCode * -1521134295 + index.GetHashCode();
|
||||
// return hashCode;
|
||||
// }
|
||||
|
||||
public static bool operator ==(ArrangerSpot left, ArrangerSpot right) {
|
||||
return EqualityComparer<ArrangerSpot>.Default.Equals(left, right);
|
||||
}
|
||||
// public static bool operator ==(ArrangerSpot left, ArrangerSpot right) {
|
||||
// return EqualityComparer<ArrangerSpot>.Default.Equals(left, right);
|
||||
// }
|
||||
|
||||
public static bool operator !=(ArrangerSpot left, ArrangerSpot right) {
|
||||
return !(left == right);
|
||||
}
|
||||
}
|
||||
// public static bool operator !=(ArrangerSpot left, ArrangerSpot right) {
|
||||
// return !(left == right);
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 课程安排器。
|
||||
/// 负责将课程安排到每周之中,并提示用户错误等各种信息。
|
||||
/// </summary>
|
||||
public class Arranger {
|
||||
public Arranger(Kernel.Data.Storage.Semester semester) {
|
||||
this.semester = semester;
|
||||
arrangeMap = new Dictionary<ArrangerSpot, int>();
|
||||
reporter = new Reporter();
|
||||
}
|
||||
|
||||
private Kernel.Data.Storage.Semester semester;
|
||||
private Dictionary<ArrangerSpot, int> arrangeMap;
|
||||
private Reporter reporter;
|
||||
|
||||
/// <summary>
|
||||
/// 获取汇报器用于查看安排日志
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Reporter GetReporter() {
|
||||
return reporter;
|
||||
}
|
||||
public static class Arranger {
|
||||
|
||||
/// <summary>
|
||||
/// 开始安排课程
|
||||
/// </summary>
|
||||
/// <returns>安排好的,用于呈现的课程。如果安排失败,则为null,查看汇报器来了解具体差错</returns>
|
||||
public Kernel.Data.Presentation.Semester Arrange() {
|
||||
reporter.Clear();
|
||||
arrangeMap.Clear();
|
||||
return ConcludeCourses();
|
||||
public static Data.Presentation.Semester Arrange(Data.Storage.Semester semester, Reporter reporter) {
|
||||
var builtSemester = CheckSemester(semester, reporter);
|
||||
if (builtSemester is null) return null;
|
||||
|
||||
var arrangeMap = ArrangeCourses(builtSemester, reporter);
|
||||
var renderResult = ConcludeCourses(builtSemester, arrangeMap, reporter);
|
||||
|
||||
return renderResult;
|
||||
}
|
||||
|
||||
#region 验证用户课表输入
|
||||
|
||||
/// <summary>
|
||||
/// 检查用户输入的学期数据是否正确
|
||||
/// </summary>
|
||||
/// <returns>如果检查无误,返回检查后的结果,否则返回null</returns>
|
||||
private Semester CheckSemester() {
|
||||
/// <returns>如果检查无误则返回检查好的结构,否则返回null</returns>
|
||||
private static Data.Built.Semester CheckSemester(Data.Storage.Semester semester, Reporter reporter) {
|
||||
// 检查Semester
|
||||
reporter.Info($"正在检查学期");
|
||||
if (semester.StartDate.DayOfWeek != DayOfWeek.Monday) {
|
||||
reporter.Error($"起始日期{semester.StartDate:yyyy-MM-dd}不是星期一");
|
||||
return null;
|
||||
}
|
||||
var rv = CheckInteger(semester.WeekCount, 1, 100, "周数", "0 < N");
|
||||
var rv = CheckInteger(reporter, semester.WeekCount, 1, 100, "周数", "0 < N");
|
||||
if (rv is null) return null;
|
||||
int weekCount = rv.Value;
|
||||
rv = CheckInteger(semester.IndexCount, 1, 100, "节次数", "0 < N");
|
||||
rv = CheckInteger(reporter, semester.IndexCount, 1, 100, "节次数", "0 < N");
|
||||
if (rv is null) return null;
|
||||
int indexCount = rv.Value;
|
||||
rv = CheckInteger(semester.BreakfastAt, 0, indexCount, "早餐时间点", "0 <= N <= 节次数");
|
||||
rv = CheckInteger(reporter, semester.BreakfastAt, 0, indexCount, "早餐时间点", "0 <= N <= 节次数");
|
||||
if (rv is null) return null;
|
||||
int breakfastAt = rv.Value;
|
||||
rv = CheckInteger(semester.LunchAt, breakfastAt, indexCount, "午餐时间点", "早餐时间点 <= N <= 节次数");
|
||||
rv = CheckInteger(reporter, semester.LunchAt, breakfastAt, indexCount, "午餐时间点", "早餐时间点 <= N <= 节次数");
|
||||
if (rv is null) return null;
|
||||
int lunchAt = rv.Value;
|
||||
rv = CheckInteger(semester.DinnerAt, lunchAt, indexCount, "晚餐时间点", "午餐时间点 <= N <= 节次数");
|
||||
rv = CheckInteger(reporter, semester.DinnerAt, lunchAt, indexCount, "晚餐时间点", "午餐时间点 <= N <= 节次数");
|
||||
if (rv is null) return null;
|
||||
int dinnerAt = rv.Value;
|
||||
|
||||
var courses = new List<Course>();
|
||||
var courses = new List<Data.Built.Course>();
|
||||
foreach (var course in semester.Courses) {
|
||||
// 检查课程(实际上只有安排需要检查)
|
||||
reporter.Info($"正在检查课程:{course.Name}");
|
||||
|
||||
var schedules = new List<Schedule>();
|
||||
var schedules = new List<Data.Built.Schedule>();
|
||||
|
||||
foreach (var schedule in course.Schedules) {
|
||||
// 检查安排
|
||||
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 <= 节次数");
|
||||
var week = CheckIntegerCollection(reporter, schedule.Week, 1, weekCount, "周", "1 <= N <= 周数");
|
||||
var day = CheckIntegerCollection(reporter, schedule.Day, 1, 7, "星期", "1 <= N <= 7");
|
||||
var index = CheckIntegerCollection(reporter, schedule.Index, 1, indexCount, "节次", "1 <= N <= 节次数");
|
||||
|
||||
// 如果格式均正确,就添加这个安排
|
||||
if (!(week is null || day is null || index is null)) {
|
||||
schedules.Add(new Schedule() {
|
||||
schedules.Add(new Data.Built.Schedule() {
|
||||
week = week,
|
||||
day = day,
|
||||
index = index
|
||||
@ -143,7 +132,7 @@ namespace HFUTCourseSimulation.Kernel {
|
||||
}
|
||||
|
||||
// OK,插入课程
|
||||
courses.Add(new Course() {
|
||||
courses.Add(new Data.Built.Course() {
|
||||
name = course.Name,
|
||||
description = course.Description,
|
||||
color = ColorTrans.ToStandardColorPair(course.Color),
|
||||
@ -152,7 +141,7 @@ namespace HFUTCourseSimulation.Kernel {
|
||||
}
|
||||
|
||||
// OK无误,返回结果
|
||||
return new Semester() {
|
||||
return new Data.Built.Semester() {
|
||||
startDate = semester.StartDate,
|
||||
weekCount = weekCount,
|
||||
indexCount = indexCount,
|
||||
@ -168,8 +157,8 @@ namespace HFUTCourseSimulation.Kernel {
|
||||
/// field_name是字段的名称,field_require是字段的要求,均用于用户提示。
|
||||
/// 返回null表示检查失败,否则返回检查好的值。
|
||||
/// </summary>
|
||||
private int? CheckInteger(string s, int min, int max, string field_name, string field_require) {
|
||||
if (int.TryParse(semester.WeekCount, out int rv)) {
|
||||
private static int? CheckInteger(Reporter reporter, string s, int min, int max, string field_name, string field_require) {
|
||||
if (int.TryParse(s, out int rv)) {
|
||||
if (rv < min || rv > max) {
|
||||
reporter.Error($"{field_name}的值“{s}”超出范围。要求:{field_require}");
|
||||
return null;
|
||||
@ -192,7 +181,7 @@ namespace HFUTCourseSimulation.Kernel {
|
||||
/// 检查整数集合的辅助函数,即检查Schedule中的三个字段Week,Day和Index的格式。
|
||||
/// 各类参数含义与上面函数相同,只不过是作用到每一项上。
|
||||
/// </summary>
|
||||
private IEnumerable<int> CheckIntegerCollection(string s, int min, int max, string field_name, string field_require) {
|
||||
private static IEnumerable<int> CheckIntegerCollection(Reporter reporter, string s, int min, int max, string field_name, string field_require) {
|
||||
// 两种整数集合所特有的字符常量,用于分割和分析
|
||||
const char COMMA = ',';
|
||||
const char DASH = '-';
|
||||
@ -215,7 +204,7 @@ namespace HFUTCourseSimulation.Kernel {
|
||||
split_char = COMMA;
|
||||
break;
|
||||
case IntegerCollectionKind.Range:
|
||||
split_char = DASH;
|
||||
split_char = DASH;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
@ -240,63 +229,148 @@ namespace HFUTCourseSimulation.Kernel {
|
||||
// 按整数集合类型进行收尾检查并返回
|
||||
switch (kind) {
|
||||
case IntegerCollectionKind.Individual:
|
||||
return new IndividualInt(ints);
|
||||
return new Data.Built.IndividualInt(ints);
|
||||
case IntegerCollectionKind.Range:
|
||||
if (ints.Count != 2) {
|
||||
reporter.Error($"{field_name}的值“{s}”不是有效的整数范围表达式");
|
||||
return null;
|
||||
} else {
|
||||
return new RangedInt(ints[0], ints[1]);
|
||||
return new Data.Built.RangedInt(ints[0], ints[1]);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 安排课程
|
||||
|
||||
/// <summary>
|
||||
/// 安排课程
|
||||
/// </summary>
|
||||
/// <returns>安排无误返回true,否则返回false</returns>
|
||||
private bool ArrangeCourses() {
|
||||
// Check it first
|
||||
var rv = CheckSemester();
|
||||
if (rv is null) return false;
|
||||
/// <returns>返回安排好的课程表</returns>
|
||||
private static int[,,] ArrangeCourses(Data.Built.Semester semester, Reporter reporter) {
|
||||
// 创建课程表并预填充所有项为-1。
|
||||
var arrangeMap = new int[semester.weekCount, 7, semester.indexCount];
|
||||
for (var week = 0; week < semester.weekCount; ++week) {
|
||||
for (var day = 0; day < 7; ++day) {
|
||||
for (var index = 0; index < semester.indexCount; ++index) {
|
||||
arrangeMap[week, day, index] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历所有课程安排开始排课
|
||||
bool okey = true;
|
||||
for (int course_index = 0; course_index < rv.courses.Count; ++course_index) {
|
||||
var course = rv.courses[course_index];
|
||||
// 排课冲突并不是严重错误,因此不需要强制退出
|
||||
for (int course_index = 0; course_index < semester.courses.Count; ++course_index) {
|
||||
var course = semester.courses[course_index];
|
||||
foreach (var schedule in course.schedules) {
|
||||
foreach (var week in schedule.week) {
|
||||
foreach (var day in schedule.day) {
|
||||
foreach (var index in schedule.index) {
|
||||
var spot = new ArrangerSpot(week, day, index);
|
||||
if (arrangeMap.TryGetValue(spot, out int occupied_course_index)) {
|
||||
var occupied_course = rv.courses[occupied_course_index];
|
||||
reporter.Error($"课程冲突:无法将{course.name}安排到周{week},星期{day},第{index}节。因为此处已被{occupied_course.name}占据");
|
||||
okey = false;
|
||||
// 获取课程占用情况并分析
|
||||
var occupied_course_index = arrangeMap[week - 1, day - 1, index - 1];
|
||||
if (occupied_course_index < 0) {
|
||||
// 没有占用的课程,可以放心安排
|
||||
arrangeMap[week - 1, day - 1, index - 1] = course_index;
|
||||
} else {
|
||||
arrangeMap.Add(spot, course_index);
|
||||
// 发现课程占用,汇报占用的课程并记录到flag
|
||||
var occupied_course = semester.courses[occupied_course_index];
|
||||
reporter.Error($"课程冲突:无法将{course.name}安排到周{week},星期{day},第{index}节。因为此处已被{occupied_course.name}占据");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return okey;
|
||||
|
||||
// 返回结果
|
||||
return arrangeMap;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 总结课程为方便渲染的结构
|
||||
|
||||
/// <summary>
|
||||
/// 将安排好的课程总结为方便渲染的结果
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Kernel.Data.Presentation.Semester ConcludeCourses() {
|
||||
// Arrange it first
|
||||
var rv = ArrangeCourses();
|
||||
if (!rv) return null;
|
||||
/// <returns>总结好的可用于渲染的结果</returns>
|
||||
private static Data.Presentation.Semester ConcludeCourses(Data.Built.Semester semester, int[,,] arrangeMap, Reporter reporter) {
|
||||
var dateCursor = semester.startDate;
|
||||
|
||||
return null;
|
||||
var weeks = new List<Data.Presentation.Week>();
|
||||
for (var week = 1; week <= semester.weekCount; ++week) {
|
||||
var days = new List<Data.Presentation.Day>();
|
||||
for (var day = 1; day <= 7; ++day) {
|
||||
// 获取日期的字符串形式,并自增天数
|
||||
var dateString = dateCursor.ToString("MM/dd");
|
||||
dateCursor = dateCursor.AddDays(1);
|
||||
|
||||
// 获取这一日的课程
|
||||
var lessons = new List<Data.Presentation.Lesson>();
|
||||
Data.Presentation.Lesson current_lesson = null;
|
||||
int previous_course_index = -1;
|
||||
for (var index = 1; index <= semester.indexCount; ++index) {
|
||||
// 比较上一个课程和当前课程的区别
|
||||
var this_course_index = arrangeMap[week - 1, day - 1, index - 1];
|
||||
if (this_course_index != previous_course_index) {
|
||||
// 课程发生了变化,我们需要根据这种变化做出操作。
|
||||
// 如果有上一任课程,我们就把它push到列表中。
|
||||
if (previous_course_index >= 0) {
|
||||
lessons.Add(current_lesson);
|
||||
current_lesson = null;
|
||||
}
|
||||
// 然后设置当前课程
|
||||
var this_course = semester.courses[this_course_index];
|
||||
current_lesson = new Data.Presentation.Lesson() {
|
||||
name = this_course.name,
|
||||
description = this_course.description,
|
||||
color = this_course.color,
|
||||
startIndex = index,
|
||||
indexSpan = 1
|
||||
};
|
||||
} else {
|
||||
// 课程未曾发生改变,如果当前有课程,我们只需要单纯地自增其节次跨度
|
||||
if (previous_course_index >= 0) {
|
||||
current_lesson.indexSpan++;
|
||||
}
|
||||
}
|
||||
// 更新上一个课程的index
|
||||
previous_course_index = this_course_index;
|
||||
}
|
||||
// 收尾处理最后一个课程
|
||||
if (previous_course_index >= 0) {
|
||||
lessons.Add(current_lesson);
|
||||
current_lesson = null;
|
||||
}
|
||||
|
||||
// 将这一日添加到这周中
|
||||
days.Add(new Data.Presentation.Day() {
|
||||
date = dateString,
|
||||
lessons = lessons.ToImmutableList()
|
||||
});
|
||||
}
|
||||
|
||||
// 将这一星期添加教学周中
|
||||
weeks.Add(new Data.Presentation.Week() {
|
||||
days = days.ToImmutableList()
|
||||
});
|
||||
}
|
||||
|
||||
// 以教学周构建并返回学期
|
||||
return new Data.Presentation.Semester() {
|
||||
weekCount = semester.weekCount,
|
||||
indexCount = semester.indexCount,
|
||||
breakfastAt = semester.breakfastAt,
|
||||
lunchAt = semester.lunchAt,
|
||||
dinnerAt = semester.dinnerAt,
|
||||
weeks = weeks.ToImmutableList()
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,10 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// 安排课程时使用的课表数据。
|
||||
/// 仅在课表安排器中作为中间结构使用,其本质上为经过验证的用户输入的课表数据。
|
||||
/// </summary>
|
||||
namespace HFUTCourseSimulation.Kernel.Data.Built {
|
||||
|
||||
public class Semester {
|
||||
|
@ -5,6 +5,10 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// 用于最终呈现的排课完毕的课表数据。
|
||||
/// 方便模拟器和图片输出接口使用的课表数据,是用户输入课表的最终“编译”后的形式。
|
||||
/// </summary>
|
||||
namespace HFUTCourseSimulation.Kernel.Data.Presentation {
|
||||
|
||||
/// <summary>
|
||||
@ -30,42 +34,37 @@ namespace HFUTCourseSimulation.Kernel.Data.Presentation {
|
||||
}
|
||||
|
||||
public class Semester {
|
||||
/// <summary>
|
||||
/// 学期开始日期。
|
||||
/// 该类保证该日期一定是星期一,且没有时间数据。
|
||||
/// </summary>
|
||||
public readonly DateTime startDate;
|
||||
/// <summary>
|
||||
/// 教学周个数。
|
||||
/// 该类保证该数值与weeks中存储的数据个数相同。
|
||||
/// </summary>
|
||||
public readonly int weekCount;
|
||||
public int weekCount;
|
||||
/// <summary>
|
||||
/// 每天课程的节次数。
|
||||
/// 该类保证该数值总是大于等于1。
|
||||
/// </summary>
|
||||
public readonly int indexCount;
|
||||
public int indexCount;
|
||||
/// <summary>
|
||||
/// 早餐插入在第几节次后。
|
||||
/// 该类保证该数值总是位于0至indexCount之间(含首尾)。
|
||||
/// </summary>
|
||||
public readonly int breakfastAt;
|
||||
public int breakfastAt;
|
||||
/// <summary>
|
||||
/// 午餐插入在第几节次后。
|
||||
/// 该类保证该数值总是位于0至indexCount之间(含首尾),
|
||||
/// 且总是大于等于breakfastAt。
|
||||
/// </summary>
|
||||
public readonly int lunchAt;
|
||||
public int lunchAt;
|
||||
/// <summary>
|
||||
/// 晚餐插入在第几节次后。
|
||||
/// 该类保证该数值总是位于0至indexCount之间(含首尾),
|
||||
/// 且总是大于等于lunchAt。
|
||||
/// </summary>
|
||||
public readonly int dinnerAt;
|
||||
public int dinnerAt;
|
||||
/// <summary>
|
||||
/// 每周课程数据。
|
||||
/// </summary>
|
||||
public readonly ImmutableList<Week> weeks;
|
||||
public ImmutableList<Week> weeks;
|
||||
|
||||
public IndexKind GetIndexKind(int index) {
|
||||
if (index <= 0) throw new ArgumentException("index out of range");
|
||||
@ -82,41 +81,44 @@ namespace HFUTCourseSimulation.Kernel.Data.Presentation {
|
||||
/// 每周七天的数据。
|
||||
/// 该类保证该字段总包含7项。
|
||||
/// </summary>
|
||||
public readonly ImmutableList<Day> days;
|
||||
public ImmutableList<Day> days;
|
||||
}
|
||||
|
||||
public class Day {
|
||||
/// <summary>
|
||||
/// 这一天的日期的字符串形式
|
||||
/// </summary>
|
||||
public string date;
|
||||
/// <summary>
|
||||
/// 这一天的所有课程。
|
||||
/// </summary>
|
||||
public readonly ImmutableList<Lesson> lessons;
|
||||
public ImmutableList<Lesson> lessons;
|
||||
}
|
||||
|
||||
public class Lesson {
|
||||
/// <summary>
|
||||
/// 课程的名称。
|
||||
/// </summary>
|
||||
public readonly string name;
|
||||
public string name;
|
||||
/// <summary>
|
||||
/// 课程的说明,例如教室位置,教师姓名等。
|
||||
/// 该值可以包含换行。
|
||||
/// </summary>
|
||||
public readonly string description;
|
||||
public string description;
|
||||
/// <summary>
|
||||
/// 课程的颜色
|
||||
/// </summary>
|
||||
public readonly Util.ColorPair color;
|
||||
public Util.ColorPair color;
|
||||
/// <summary>
|
||||
/// 课程的起始节次。
|
||||
/// 该类保证该值位于1到indexCount之间(含首尾)。
|
||||
/// </summary>
|
||||
public readonly int startIndex;
|
||||
public int startIndex;
|
||||
/// <summary>
|
||||
/// 课程的结束节次。
|
||||
/// 该类保证该值位于1到indexCount之间(含首尾),
|
||||
/// 且大于等于startIndex。
|
||||
/// 课程的节次跨度。
|
||||
/// 该类保证该值总大于0,且加上startIndex后不会大于节次数。
|
||||
/// </summary>
|
||||
public readonly int endIndex;
|
||||
public int indexSpan;
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,6 +8,10 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
/// <summary>
|
||||
/// 用于保存到文件的课表数据。
|
||||
/// 同时也是程序中作为转换核心的数据结构,各种课表数据之间的转换以该结构为核心。
|
||||
/// </summary>
|
||||
namespace HFUTCourseSimulation.Kernel.Data.Storage {
|
||||
|
||||
/// <summary>
|
||||
|
@ -7,6 +7,10 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
/// <summary>
|
||||
/// 用于用户界面呈现的课表数据。
|
||||
/// 该命名空间的类针对WPF的UI实现了特殊的接口,以正确地和用户交互。
|
||||
/// </summary>
|
||||
namespace HFUTCourseSimulation.Kernel.Data.Ui {
|
||||
|
||||
public class Semester : INotifyPropertyChanged {
|
||||
|
Reference in New Issue
Block a user