refactor: write shit
This commit is contained in:
@ -1,60 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace HFUTCourseSimulation {
|
||||
|
||||
public class Semester {
|
||||
|
||||
public Semester() {
|
||||
this.Courses = new List<CourseItem>();
|
||||
StartDate = DateTime.Today.ToString();
|
||||
WeekCount = 1;
|
||||
}
|
||||
|
||||
public string StartDate { get; set; }
|
||||
public int WeekCount { get; set; }
|
||||
public List<CourseItem> Courses { get; set; }
|
||||
}
|
||||
|
||||
public class CourseItem {
|
||||
|
||||
public CourseItem() {
|
||||
//BkColor = Colors.LightBlue.ColorToInt();
|
||||
this.Schedule = new List<ScheduleItem>();
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public int BkColor { get; set; }
|
||||
|
||||
public List<ScheduleItem> Schedule { get; set; }
|
||||
|
||||
public CourseItem Clone() {
|
||||
var newobj = new CourseItem();
|
||||
newobj.Name = this.Name;
|
||||
newobj.Description = this.Description;
|
||||
newobj.BkColor = this.BkColor;
|
||||
newobj.Schedule = new List<ScheduleItem>();
|
||||
newobj.Schedule.AddRange((from item in this.Schedule select item.Clone()));
|
||||
return newobj;
|
||||
}
|
||||
}
|
||||
|
||||
public class ScheduleItem {
|
||||
public string Week { get; set; }
|
||||
public string Day { get; set; }
|
||||
public string Index { get; set; }
|
||||
|
||||
public ScheduleItem Clone() {
|
||||
return new ScheduleItem() { Week = this.Week, Index = this.Index, Day = this.Day };
|
||||
}
|
||||
public override string ToString() {
|
||||
return Week + " - " + Day + " - " + Index;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HFUTCourseSimulation {
|
||||
public static class General {
|
||||
|
||||
public static Semester GeneralSheet;
|
||||
|
||||
public static CourseItem CourseCache = new CourseItem();
|
||||
public static ScheduleItem ScheduleCache = new ScheduleItem();
|
||||
|
||||
public static string FilePath = "";
|
||||
|
||||
}
|
||||
}
|
@ -83,10 +83,12 @@
|
||||
</Compile>
|
||||
<Compile Include="General.cs" />
|
||||
<Compile Include="ImageExport.cs" />
|
||||
<Compile Include="Kernel\Arranger.cs" />
|
||||
<Compile Include="Kernel\Data\Built.cs" />
|
||||
<Compile Include="Kernel\Data\Presentation.cs" />
|
||||
<Compile Include="Kernel\Data\Storage.cs" />
|
||||
<Compile Include="Kernel\Data\Ui.cs" />
|
||||
<Compile Include="Kernel\MsgRecorder.cs" />
|
||||
<Compile Include="Kernel\Reporter.cs" />
|
||||
<Compile Include="Kernel\Data\LegacyStorage\V1.cs" />
|
||||
<Compile Include="Simulation.xaml.cs">
|
||||
<DependentUpon>Simulation.xaml</DependentUpon>
|
||||
|
234
HFUTCourseSimulation/Kernel/Arranger.cs
Normal file
234
HFUTCourseSimulation/Kernel/Arranger.cs
Normal file
@ -0,0 +1,234 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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>
|
||||
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 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 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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始安排课程
|
||||
/// </summary>
|
||||
/// <returns>安排好的,用于呈现的课程。如果安排失败,则为null,查看汇报器来了解具体差错</returns>
|
||||
public Kernel.Data.Presentation.Semester Arrange() {
|
||||
reporter.Clear();
|
||||
arrangeMap.Clear();
|
||||
return ConcludeCourses();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查用户输入的学期数据是否正确
|
||||
/// </summary>
|
||||
/// <returns>如果检查无误,返回检查后的结果,否则返回null</returns>
|
||||
private Semester CheckSemester() {
|
||||
// 检查Semester
|
||||
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 courses = new List<Course>();
|
||||
foreach (var course in semester.Courses) {
|
||||
// 检查课程(实际上只有安排需要检查)
|
||||
var schedules = new List<Schedule>();
|
||||
|
||||
foreach (var schedule in course.Schedules) {
|
||||
// 检查安排
|
||||
if
|
||||
|
||||
|
||||
}
|
||||
|
||||
// OK,插入课程
|
||||
courses.Add(new Course() {
|
||||
name = course.Name,
|
||||
description = course.Description,
|
||||
color = ColorTrans.ToStandardColorPair(course.Color),
|
||||
schedules = schedules
|
||||
});
|
||||
}
|
||||
|
||||
// OK无误,返回结果
|
||||
return new Semester() {
|
||||
startDate = semester.StartDate,
|
||||
weekCount = weekCount,
|
||||
indexCount = indexCount,
|
||||
breakfastAt = breakfastAt,
|
||||
lunchAt = lunchAt,
|
||||
dinnerAt = dinnerAt,
|
||||
courses = courses
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 安排课程
|
||||
/// </summary>
|
||||
/// <returns>安排无误返回true,否则返回false</returns>
|
||||
private bool ArrangeCourses() {
|
||||
// Check it first
|
||||
var rv = CheckSemester();
|
||||
if (rv is null) return false;
|
||||
|
||||
// 遍历所有课程安排开始排课
|
||||
bool okey = true;
|
||||
for (int course_index = 0; course_index < rv.courses.Count; ++course_index) {
|
||||
var course = rv.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;
|
||||
} else {
|
||||
arrangeMap.Add(spot, course_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return okey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将安排好的课程总结为方便渲染的结果
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Kernel.Data.Presentation.Semester ConcludeCourses() {
|
||||
// Arrange it first
|
||||
var rv = ArrangeCourses();
|
||||
if (!rv) return null;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
61
HFUTCourseSimulation/Kernel/Data/Built.cs
Normal file
61
HFUTCourseSimulation/Kernel/Data/Built.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HFUTCourseSimulation.Kernel.Data.Built {
|
||||
|
||||
public class Semester {
|
||||
public DateTime startDate;
|
||||
public int weekCount, indexCount;
|
||||
public int breakfastAt, lunchAt, dinnerAt;
|
||||
public List<Course> courses;
|
||||
}
|
||||
|
||||
public class Course {
|
||||
public string name, description;
|
||||
public Util.ColorPair color;
|
||||
public List<Schedule> schedules;
|
||||
}
|
||||
|
||||
public class Schedule {
|
||||
public IEnumerable<int> week;
|
||||
public IEnumerable<int> day;
|
||||
public IEnumerable<int> index;
|
||||
}
|
||||
|
||||
public class IndividualInt : IEnumerable<int> {
|
||||
public IndividualInt(IEnumerable<int> it) {
|
||||
_values = it.ToList();
|
||||
}
|
||||
|
||||
private List<int> _values;
|
||||
|
||||
public IEnumerator<int> GetEnumerator() {
|
||||
return _values.GetEnumerator();
|
||||
}
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
public class RangedInt : IEnumerable<int> {
|
||||
public RangedInt(int start, int end) {
|
||||
this._start = start;
|
||||
this._end = end;
|
||||
}
|
||||
|
||||
private int _start, _end;
|
||||
|
||||
public IEnumerator<int> GetEnumerator() {
|
||||
return Enumerable.Range(_start, _end).GetEnumerator();
|
||||
}
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,12 +5,12 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HFUTCourseSimulation.Kernel.MsgRecorder {
|
||||
namespace HFUTCourseSimulation.Kernel {
|
||||
|
||||
/// <summary>
|
||||
/// 消息的类型
|
||||
/// </summary>
|
||||
public enum Kind {
|
||||
public enum ReporterKind {
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
@ -19,57 +19,28 @@ namespace HFUTCourseSimulation.Kernel.MsgRecorder {
|
||||
/// <summary>
|
||||
/// 被记录的消息条目
|
||||
/// </summary>
|
||||
public class Entry {
|
||||
public Entry(Kind kind, string message) {
|
||||
this.kind = kind;
|
||||
this.message = message;
|
||||
public class ReporterEntry {
|
||||
public ReporterEntry(ReporterKind kind, string message) {
|
||||
this.Kind = kind;
|
||||
this.Message = message;
|
||||
}
|
||||
|
||||
public readonly Kind kind;
|
||||
public readonly string message;
|
||||
public ReporterKind Kind { get; private set; }
|
||||
public string Message { get; private set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于记录模拟过程中的消息(例如错误,警告等)
|
||||
/// </summary>
|
||||
public class Recorder : IEnumerable<Entry> {
|
||||
public Recorder() {
|
||||
entries = new List<Entry>();
|
||||
public class Reporter : IEnumerable<ReporterEntry> {
|
||||
public Reporter() {
|
||||
entries = new List<ReporterEntry>();
|
||||
hasError = false;
|
||||
}
|
||||
|
||||
private List<Entry> entries;
|
||||
private List<ReporterEntry> entries;
|
||||
private bool hasError;
|
||||
|
||||
/// <summary>
|
||||
/// 记录一条提示消息
|
||||
/// </summary>
|
||||
/// <param name="message">消息内容</param>
|
||||
public void Info(string message) {
|
||||
entries.Add(new Entry(Kind.Info, message));
|
||||
}
|
||||
/// <summary>
|
||||
/// 记录一条警告消息
|
||||
/// </summary>
|
||||
/// <param name="message">消息内容</param>
|
||||
public void Warning(string message) {
|
||||
entries.Add(new Entry(Kind.Warning, message));
|
||||
}
|
||||
/// <summary>
|
||||
/// 记录一条错误消息
|
||||
/// </summary>
|
||||
/// <param name="message">消息内容</param>
|
||||
public void Error(string message) {
|
||||
this.hasError = true;
|
||||
entries.Add(new Entry(Kind.Error, message));
|
||||
}
|
||||
|
||||
public IEnumerator<Entry> GetEnumerator() {
|
||||
return entries.GetEnumerator();
|
||||
}
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return GetEnumerator();
|
||||
}
|
||||
/// <summary>
|
||||
/// 检查过程中是否有错误类型的消息被记录
|
||||
/// </summary>
|
||||
@ -78,6 +49,28 @@ namespace HFUTCourseSimulation.Kernel.MsgRecorder {
|
||||
return hasError;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录一条提示消息
|
||||
/// </summary>
|
||||
/// <param name="message">消息内容</param>
|
||||
public void Info(string message) {
|
||||
entries.Add(new ReporterEntry(ReporterKind.Info, message));
|
||||
}
|
||||
/// <summary>
|
||||
/// 记录一条警告消息
|
||||
/// </summary>
|
||||
/// <param name="message">消息内容</param>
|
||||
public void Warning(string message) {
|
||||
entries.Add(new ReporterEntry(ReporterKind.Warning, message));
|
||||
}
|
||||
/// <summary>
|
||||
/// 记录一条错误消息
|
||||
/// </summary>
|
||||
/// <param name="message">消息内容</param>
|
||||
public void Error(string message) {
|
||||
this.hasError = true;
|
||||
entries.Add(new ReporterEntry(ReporterKind.Error, message));
|
||||
}
|
||||
/// <summary>
|
||||
/// 重置记录器状态
|
||||
/// </summary>
|
||||
@ -86,6 +79,12 @@ namespace HFUTCourseSimulation.Kernel.MsgRecorder {
|
||||
hasError = false;
|
||||
}
|
||||
|
||||
public IEnumerator<ReporterEntry> GetEnumerator() {
|
||||
return entries.GetEnumerator();
|
||||
}
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user