From ecedc8f04fd6619d58ff1fb9a712a1bee2add149 Mon Sep 17 00:00:00 2001 From: shoot Date: Fri, 29 Dec 2023 22:22:08 +0400 Subject: [PATCH] PIbd22_NikiforovaMV_lab8 --- ContainerShip/DrawningShipEqutables.cs | 56 ++++++++++++ ContainerShip/FormShipCollection.Designer.cs | 34 ++++++- ContainerShip/FormShipCollection.cs | 26 +++++- ContainerShip/SetGeneric.cs | 15 +++- ContainerShip/ShipCompareByColor.cs | 34 +++++++ ContainerShip/ShipCompareByType.cs | 31 +++++++ ContainerShip/ShipsCollectionInfo.cs | 27 ++++++ ContainerShip/ShipsGenericCollection.cs | 3 +- ContainerShip/ShipsGenericStorage.cs | 93 +++++++++++++------- ContainerShip/nlog.config | 11 +++ 10 files changed, 286 insertions(+), 44 deletions(-) create mode 100644 ContainerShip/DrawningShipEqutables.cs create mode 100644 ContainerShip/ShipCompareByColor.cs create mode 100644 ContainerShip/ShipCompareByType.cs create mode 100644 ContainerShip/ShipsCollectionInfo.cs create mode 100644 ContainerShip/nlog.config diff --git a/ContainerShip/DrawningShipEqutables.cs b/ContainerShip/DrawningShipEqutables.cs new file mode 100644 index 0000000..9eea7ce --- /dev/null +++ b/ContainerShip/DrawningShipEqutables.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; +using ContainerShip.Entities; +using ContainerShip.DrawningObjects; + +namespace ContainerShip.Generic +{ + internal class DrawningShipEqutables : IEqualityComparer + { + public bool Equals(DrawningShip? x, DrawningShip? y) + { + if (x == null && x.EntityShip == null) + throw new ArgumentNullException(nameof(x)); + + if (y == null && y.EntityShip == null) + throw new ArgumentNullException(nameof(y)); + + if ((x.GetType().Name != y.GetType().Name)) + return false; + + if (x.EntityShip.Speed != y.EntityShip.Speed) + return false; + + if (x.EntityShip.Weight != y.EntityShip.Weight) + return false; + + if (x.EntityShip.BodyColor != y.EntityShip.BodyColor) + return false; + + if (x is DrawingContainerShip && y is DrawingContainerShip) + { + var xPlane = (EntityContainerShip)x.EntityShip; + var yPlane = (EntityContainerShip)y.EntityShip; + + if (xPlane.AdditionalColor != yPlane.AdditionalColor) + return false; + + if (xPlane.Load != yPlane.Load) + return false; + + if (xPlane.Crane != yPlane.Crane) + return false; + } + return true; + } + + public int GetHashCode([DisallowNull] DrawningShip? obj) + { + return obj.GetHashCode(); + } + } +} diff --git a/ContainerShip/FormShipCollection.Designer.cs b/ContainerShip/FormShipCollection.Designer.cs index a03add4..d0da279 100644 --- a/ContainerShip/FormShipCollection.Designer.cs +++ b/ContainerShip/FormShipCollection.Designer.cs @@ -45,13 +45,15 @@ LoadToolStripMenuItem = new ToolStripMenuItem(); openFileDialog = new OpenFileDialog(); saveFileDialog = new SaveFileDialog(); + buttonSortByColor = new Button(); + buttonSortByType = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBoxCollection).BeginInit(); menuStrip.SuspendLayout(); SuspendLayout(); // // buttonAdd // - buttonAdd.Location = new Point(739, 407); + buttonAdd.Location = new Point(736, 480); buttonAdd.Margin = new Padding(3, 4, 3, 4); buttonAdd.Name = "buttonAdd"; buttonAdd.Size = new Size(165, 32); @@ -62,7 +64,7 @@ // // buttonDelete // - buttonDelete.Location = new Point(737, 482); + buttonDelete.Location = new Point(736, 555); buttonDelete.Margin = new Padding(3, 4, 3, 4); buttonDelete.Name = "buttonDelete"; buttonDelete.Size = new Size(163, 32); @@ -82,7 +84,7 @@ // // maskedTextBoxNumber // - maskedTextBoxNumber.Location = new Point(737, 447); + maskedTextBoxNumber.Location = new Point(736, 520); maskedTextBoxNumber.Margin = new Padding(3, 4, 3, 4); maskedTextBoxNumber.Name = "maskedTextBoxNumber"; maskedTextBoxNumber.Size = new Size(162, 27); @@ -197,11 +199,35 @@ // saveFileDialog.Filter = "txt file | *.txt"; // + // buttonSortByColor + // + buttonSortByColor.Location = new Point(739, 374); + buttonSortByColor.Margin = new Padding(3, 4, 3, 4); + buttonSortByColor.Name = "buttonSortByColor"; + buttonSortByColor.Size = new Size(165, 32); + buttonSortByColor.TabIndex = 14; + buttonSortByColor.Text = "Сортировка по цвету"; + buttonSortByColor.UseVisualStyleBackColor = true; + buttonSortByColor.Click += buttonSortByColor_Click; + // + // buttonSortByType + // + buttonSortByType.Location = new Point(739, 414); + buttonSortByType.Margin = new Padding(3, 4, 3, 4); + buttonSortByType.Name = "buttonSortByType"; + buttonSortByType.Size = new Size(165, 32); + buttonSortByType.TabIndex = 15; + buttonSortByType.Text = "Сортировка по типу"; + buttonSortByType.UseVisualStyleBackColor = true; + buttonSortByType.Click += buttonSortByType_Click; + // // FormShipCollection // AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(914, 600); + Controls.Add(buttonSortByType); + Controls.Add(buttonSortByColor); Controls.Add(menuStrip); Controls.Add(buttonDeleteStorage); Controls.Add(buttonAddStorage); @@ -243,5 +269,7 @@ private ToolStripMenuItem LoadToolStripMenuItem; private OpenFileDialog openFileDialog; private SaveFileDialog saveFileDialog; + private Button buttonSortByColor; + private Button buttonSortByType; } } \ No newline at end of file diff --git a/ContainerShip/FormShipCollection.cs b/ContainerShip/FormShipCollection.cs index 831f3f8..71e0326 100644 --- a/ContainerShip/FormShipCollection.cs +++ b/ContainerShip/FormShipCollection.cs @@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging; using ContainerShip.DrawningObjects; using ContainerShip.Generic; using ContainerShip.Exceptions; +using ContainerShip.Entities; namespace ContainerShip @@ -28,13 +29,30 @@ namespace ContainerShip _storage = new ShipsGenericStorage(pictureBoxCollection.Width, pictureBoxCollection.Height); _logger = logger; } + + private void buttonSortByType_Click(object sender, EventArgs e) => CompareShip(new ShipCompareByType()); + private void buttonSortByColor_Click(object sender, EventArgs e) => CompareShip(new ShipCompareByColor()); + private void CompareShip(IComparer comparer) + { + if (listBoxStorages.SelectedIndex == -1) + { + return; + } + var obj = _storage[listBoxStorages.SelectedItem.ToString() ?? string.Empty]; + if (obj == null) + { + return; + } + obj.Sort(comparer); + pictureBoxCollection.Image = obj.ShowShips(); + } private void ReloadObjects() { int index = listBoxStorages.SelectedIndex; listBoxStorages.Items.Clear(); for (int i = 0; i < _storage.Keys.Count; i++) { - listBoxStorages.Items.Add(_storage.Keys[i]); + listBoxStorages.Items.Add(_storage.Keys[i].Name); } if (listBoxStorages.Items.Count > 0 && (index == -1 || index >= listBoxStorages.Items.Count)) { @@ -114,6 +132,11 @@ namespace ContainerShip MessageBox.Show(ex.Message); _logger.LogWarning(ex.Message); } + catch (Exception ex) + { + MessageBox.Show(ex.Message); + _logger.LogWarning(ex.Message); + } } private void buttonDelete_Click(object sender, EventArgs e) @@ -209,6 +232,5 @@ namespace ContainerShip } ReloadObjects(); } - } } diff --git a/ContainerShip/SetGeneric.cs b/ContainerShip/SetGeneric.cs index c2744f8..178c213 100644 --- a/ContainerShip/SetGeneric.cs +++ b/ContainerShip/SetGeneric.cs @@ -18,11 +18,12 @@ namespace ContainerShip.Generic _maxCount = count; _places = new List(count); } - public int Insert(T ship) + public void SortSet(IComparer comparer) => _places.Sort(comparer); + public int Insert(T ship, IEqualityComparer? equal = null) { - return Insert(ship, 0); + return Insert(ship, 0, equal); } - public int Insert(T ship, int position) + public int Insert(T ship, int position, IEqualityComparer? equal = null) { if (Count >= _maxCount) { @@ -32,6 +33,11 @@ namespace ContainerShip.Generic { throw new IndexOutOfRangeException("Индекс вне границ коллекции"); } + if (equal != null && _places.Contains(ship, equal)) + { + throw new ArgumentException("Данный объект уже есть в коллекции"); + } + _places.Insert(position, ship); return 0; } @@ -56,10 +62,11 @@ namespace ContainerShip.Generic } set { - if (position < 0 || position > Count || Count >= _maxCount) + if (position < 0 || Count >= _maxCount) { return; } + _places.Insert(position, value); } } diff --git a/ContainerShip/ShipCompareByColor.cs b/ContainerShip/ShipCompareByColor.cs new file mode 100644 index 0000000..397fcba --- /dev/null +++ b/ContainerShip/ShipCompareByColor.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ContainerShip.DrawningObjects; +using ContainerShip.Entities; + +namespace ContainerShip.Entities +{ + internal class ShipCompareByColor : IComparer + { + public int Compare(DrawningShip? x, DrawningShip? y) + { + if (x == null || x.EntityShip == null) + throw new ArgumentNullException(nameof(x)); + + if (y == null || y.EntityShip == null) + throw new ArgumentNullException(nameof(y)); + + var xPlane = x.EntityShip; + var yPlane = y.EntityShip; + + if (xPlane.BodyColor != yPlane.BodyColor) + return xPlane.BodyColor.Name.CompareTo(yPlane.BodyColor.Name); + + var speedCompare = x.EntityShip.Speed.CompareTo(y.EntityShip.Speed); + if (speedCompare != 0) + return speedCompare; + + return x.EntityShip.Weight.CompareTo(y.EntityShip.Weight); + } + } +} diff --git a/ContainerShip/ShipCompareByType.cs b/ContainerShip/ShipCompareByType.cs new file mode 100644 index 0000000..9c8590a --- /dev/null +++ b/ContainerShip/ShipCompareByType.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ContainerShip.DrawningObjects; +using ContainerShip.Entities; + +namespace ContainerShip.Entities +{ + internal class ShipCompareByType : IComparer + { + public int Compare(DrawningShip? x, DrawningShip? y) + { + if (x == null || x.EntityShip == null) + throw new ArgumentNullException(nameof(x)); + + if (y == null || y.EntityShip == null) + throw new ArgumentNullException(nameof(y)); + + if (x.GetType().Name != y.GetType().Name) + return x.GetType().Name.CompareTo(y.GetType().Name); + + var speedCompare = x.EntityShip.Speed.CompareTo(y.EntityShip.Speed); + if (speedCompare != 0) + return speedCompare; + + return x.EntityShip.Weight.CompareTo(y.EntityShip.Weight); + } + } +} diff --git a/ContainerShip/ShipsCollectionInfo.cs b/ContainerShip/ShipsCollectionInfo.cs new file mode 100644 index 0000000..9efc24d --- /dev/null +++ b/ContainerShip/ShipsCollectionInfo.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ContainerShip.Generic +{ + internal class ShipsCollectionInfo : IEquatable + { + public string Name { get; private set; } + public string Description { get; private set; } + public ShipsCollectionInfo(string name, string description) + { + Name = name; + Description = description; + } + public bool Equals(ShipsCollectionInfo? other) + { + if (ReferenceEquals(other, null)) + return false; + + return Name.Equals(other.Name); + } + public override int GetHashCode() => Name.GetHashCode(); + } +} diff --git a/ContainerShip/ShipsGenericCollection.cs b/ContainerShip/ShipsGenericCollection.cs index 143062a..7b84aee 100644 --- a/ContainerShip/ShipsGenericCollection.cs +++ b/ContainerShip/ShipsGenericCollection.cs @@ -28,11 +28,12 @@ namespace ContainerShip.Generic _pictureHeight = picHeight; _collection = new SetGeneric(width * height); } + public void Sort(IComparer comparer) => _collection.SortSet(comparer); public static int operator +(ShipsGenericCollection collect, T? obj) { if (obj != null) { - return collect._collection.Insert(obj); + return collect._collection.Insert(obj, new DrawningShipEqutables()); } return -1; } diff --git a/ContainerShip/ShipsGenericStorage.cs b/ContainerShip/ShipsGenericStorage.cs index 941dabb..f8e5d0f 100644 --- a/ContainerShip/ShipsGenericStorage.cs +++ b/ContainerShip/ShipsGenericStorage.cs @@ -11,42 +11,68 @@ namespace ContainerShip.Generic { internal class ShipsGenericStorage { - private static readonly char _separatorForKeyValue = '|'; - private readonly char _separatorRecords = ';'; - private static readonly char _separatorForObject = ':'; - readonly Dictionary> _shipStorages; - public List Keys => _shipStorages.Keys.ToList(); + //Словарь (хранилище) + readonly Dictionary> _shipStorages; + //Возвращение списка названий наборов + public List Keys => _shipStorages.Keys.ToList(); + //Ширина окна отрисовки private readonly int _pictureWidth; - + //Высота окна отрисовки private readonly int _pictureHeight; + + // Разделитель для записи ключа и значения элемента словаря + private static readonly char _separatorForKeyValue = '|'; + // Разделитель для записей коллекции данных в файл + private readonly char _separatorRecords = ';'; + // Разделитель для записи информации по объекту в файл + private static readonly char _separatorForObject = ':'; + public ShipsGenericStorage(int pictureWidth, int pictureHeight) { - _shipStorages = new Dictionary>(); + _shipStorages = new Dictionary>(); _pictureWidth = pictureWidth; _pictureHeight = pictureHeight; } + + // Добавление набора public void AddSet(string name) { - foreach (string nameStorage in Keys) - { - if (nameStorage == name) - { - MessageBox.Show("Набор с заданным именем уже существует", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - } - _shipStorages.Add(name, new ShipsGenericCollection(_pictureWidth, _pictureHeight)); + ShipsCollectionInfo set = new ShipsCollectionInfo(name, string.Empty); + + if (_shipStorages.ContainsKey(set)) + return; + + _shipStorages.Add(set, new ShipsGenericCollection(_pictureWidth, _pictureHeight)); } + // Удаление набора public void DelSet(string name) { - if (_shipStorages.ContainsKey(name)) - { - _shipStorages.Remove(name); - } + ShipsCollectionInfo set = new ShipsCollectionInfo(name, string.Empty); + // проверка, что нет набора с таким именем + if (!_shipStorages.ContainsKey(set)) + return; + + _shipStorages.Remove(set); } + + // Доступ к набору + public ShipsGenericCollection? this[string ind] + { + get + { + ShipsCollectionInfo set = new ShipsCollectionInfo(ind, string.Empty); + + if (!_shipStorages.ContainsKey(set)) + { + return null; + } + return _shipStorages[set]; + } + } + + // Сохранение информации по автомобилям в хранилище в файл public bool SaveData(string filename) { if (_shipStorages.Count == 0) @@ -80,6 +106,8 @@ namespace ContainerShip.Generic } return true; } + + // Загрузка информации по автомобилям в хранилище из файла public bool LoadData(string filename) { if (!File.Exists(filename)) @@ -89,13 +117,17 @@ namespace ContainerShip.Generic using (StreamReader sr = File.OpenText(filename)) { + // 1-ая строка string? curLine = sr.ReadLine(); + // пустая или не те данные if (curLine == null || curLine.Length == 0 || !curLine.StartsWith("ShipStorage")) { throw new ArgumentException("Неверный формат данных"); } + // очищаем _shipStorages.Clear(); + // загружаем данные построчно curLine = sr.ReadLine(); if (curLine == null || curLine.Length == 0) { @@ -103,6 +135,7 @@ namespace ContainerShip.Generic } while (curLine != null) { + // загружаем запись if (!curLine.Contains(_separatorRecords)) { throw new ArgumentException("Коллекция пуста"); @@ -110,13 +143,16 @@ namespace ContainerShip.Generic string[] record = curLine.Split(_separatorForKeyValue, StringSplitOptions.RemoveEmptyEntries); + // загружаем набор ShipsGenericCollection collection = new(_pictureWidth, _pictureHeight); + // record[0] - название набора, record[1] - куча объектов string[] set = record[1].Split(_separatorRecords, StringSplitOptions.RemoveEmptyEntries); foreach (string elem in set) { DrawningShip? ship = elem?.CreateDrawningShip(_separatorForObject, _pictureWidth, _pictureHeight); + // проверяем, не переполнится ли коллекция if (ship != null) { if (collection + ship == -1) @@ -125,23 +161,12 @@ namespace ContainerShip.Generic } } } - _shipStorages.Add(record[0], collection); + _shipStorages.Add(new ShipsCollectionInfo(record[0], string.Empty), collection); curLine = sr.ReadLine(); } } return true; } - public ShipsGenericCollection? this[string ind] - { - get - { - if (_shipStorages.ContainsKey(ind)) - { - return _shipStorages[ind]; - } - return null; - } - } - } + } diff --git a/ContainerShip/nlog.config b/ContainerShip/nlog.config new file mode 100644 index 0000000..cccd4e0 --- /dev/null +++ b/ContainerShip/nlog.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file -- 2.25.1