diff --git a/AirBomber/AirBomber/AbstractMap.cs b/AirBomber/AirBomber/AbstractMap.cs index 02bd9a7..1c78651 100644 --- a/AirBomber/AirBomber/AbstractMap.cs +++ b/AirBomber/AirBomber/AbstractMap.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace AirBomber { - internal abstract class AbstractMap + internal abstract class AbstractMap : IEquatable { private IDrawingObject _drawningObject = null; protected int[,] _map = null; @@ -113,5 +113,33 @@ namespace AirBomber protected abstract void GenerateMap(); protected abstract void DrawRoadPart(Graphics g, int i, int j); protected abstract void DrawBarrierPart(Graphics g, int i, int j); + + public bool Equals(AbstractMap? other) + { + if (_width != other._width) + { + return false; + } + if (_height != other._height) + { + return false; + } + if (_size_x != other._size_x) + { + return false; + } + if (_size_y != other._size_y) + { + return false; + } + for (int i = 0; i < _map.GetLength(0); i++) + { + for (int j = 0; j < _map.GetLength(1); j++) + { + if (other._map[i, j] != _map[j, i]) return false; + } + } + return true; + } } } diff --git a/AirBomber/AirBomber/AirBomberCompareByColor.cs b/AirBomber/AirBomber/AirBomberCompareByColor.cs new file mode 100644 index 0000000..daa514e --- /dev/null +++ b/AirBomber/AirBomber/AirBomberCompareByColor.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AirBomber +{ + internal class AirBomberCompareByColor : IComparer + { + public int Compare(IDrawingObject? x, IDrawingObject? y) + { + if (x == null && y == null) + { + return 0; + } + if (x == null && y != null) + { + return 1; + } + if (x != null && y == null) + { + return -1; + } + var xAirBomber = x as DrawingObjectAirBomber; + var yAirBomber = y as DrawingObjectAirBomber; + var rCompare = xAirBomber.GetAirBomber.AirBomber.BodyColor.R.CompareTo(yAirBomber.GetAirBomber.AirBomber.BodyColor.R); + if (rCompare != 0) + { + return rCompare; + } + var gCompare = xAirBomber.GetAirBomber.AirBomber.BodyColor.G.CompareTo(yAirBomber.GetAirBomber.AirBomber.BodyColor.G); + if (gCompare != 0) + { + return gCompare; + } + var bCompare = xAirBomber.GetAirBomber.AirBomber.BodyColor.B.CompareTo(yAirBomber.GetAirBomber.AirBomber.BodyColor.B); + if (bCompare != 0) + { + return bCompare; + } + if (xAirBomber.GetAirBomber.AirBomber is EntityHeavyAirBomber xHeavyAirBomber && yAirBomber.GetAirBomber.AirBomber is EntityHeavyAirBomber yHeavyAirBomber) + { + var rDopCompare = xHeavyAirBomber.DopColor.R.CompareTo(yHeavyAirBomber.DopColor.R); + if (rDopCompare != 0) + { + return rDopCompare; + } + var gDopCompare = xHeavyAirBomber.DopColor.G.CompareTo(yHeavyAirBomber.DopColor.G); + if (gDopCompare != 0) + { + return gDopCompare; + } + var bDopCompare = xHeavyAirBomber.DopColor.B.CompareTo(yHeavyAirBomber.DopColor.B); + if (bDopCompare != 0) + { + return bDopCompare; + } + return 0; + } + return 0; + } + } +} diff --git a/AirBomber/AirBomber/AirBomberCompareByType.cs b/AirBomber/AirBomber/AirBomberCompareByType.cs new file mode 100644 index 0000000..861575c --- /dev/null +++ b/AirBomber/AirBomber/AirBomberCompareByType.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AirBomber +{ + internal class AirBomberCompareByType : IComparer + { + public int Compare(IDrawingObject? x, IDrawingObject? y) + { + if (x == null && y == null) + { + return 0; + } + if (x == null && y != null) + { + return 1; + } + if (x != null && y == null) + { + return -1; + } + var xAirBomber = x as DrawingObjectAirBomber; + var yAirBomber = y as DrawingObjectAirBomber; + if (xAirBomber == null && yAirBomber == null) + { + return 0; + } + if (xAirBomber == null && yAirBomber != null) + { + return 1; + } + if (xAirBomber != null && yAirBomber == null) + { + return -1; + } + if (xAirBomber.GetAirBomber.GetType().Name != yAirBomber.GetAirBomber.GetType().Name) + { + if (xAirBomber.GetAirBomber.GetType().Name == "DrawingAirBomber") + { + return -1; + } + return 1; + } + var speedCompare = xAirBomber.GetAirBomber.AirBomber.Speed.CompareTo(yAirBomber.GetAirBomber.AirBomber.Speed); + if (speedCompare != 0) + { + return speedCompare; + } + return xAirBomber.GetAirBomber.AirBomber.Weight.CompareTo(yAirBomber.GetAirBomber.AirBomber.Weight); + } + } +} diff --git a/AirBomber/AirBomber/DrawingObjectAirBomber.cs b/AirBomber/AirBomber/DrawingObjectAirBomber.cs index 4099fe1..37101f0 100644 --- a/AirBomber/AirBomber/DrawingObjectAirBomber.cs +++ b/AirBomber/AirBomber/DrawingObjectAirBomber.cs @@ -17,6 +17,8 @@ namespace AirBomber public float Step => _airBomber?.AirBomber?.Step ?? 0; + public DrawingAirBomber GetAirBomber => _airBomber; + public (float Left, float Top, float Right, float Bottom) GetCurrentPosition() { return _airBomber?.GetCurrentPosition() ?? default; @@ -48,5 +50,53 @@ namespace AirBomber public string GetInfo() => _airBomber?.GetDataForSave(); public static IDrawingObject Create(string data) => new DrawingObjectAirBomber(data.CreateDrawningAirBomber()); + + public bool Equals(IDrawingObject? other) + { + if (other == null) + { + return false; + } + var otherAirBomber = other as DrawingObjectAirBomber; + if (otherAirBomber == null) + { + return false; + } + var airBomber = _airBomber.AirBomber; + var otherAirBomberAirBomber = otherAirBomber._airBomber.AirBomber; + if (airBomber.Speed != otherAirBomberAirBomber.Speed) + { + return false; + } + if (airBomber.Weight != otherAirBomberAirBomber.Weight) + { + return false; + } + if (airBomber.BodyColor != otherAirBomberAirBomber.BodyColor) + { + return false; + } + if (airBomber is EntityHeavyAirBomber heavyAirBomber && otherAirBomberAirBomber is EntityHeavyAirBomber otherHeavyAirBomber) + { + if (heavyAirBomber.DopColor != otherHeavyAirBomber.DopColor) + { + return false; + } + if (heavyAirBomber.Bombs != otherHeavyAirBomber.Bombs) + { + return false; + } + if (heavyAirBomber.FuelTank != otherHeavyAirBomber.FuelTank) + { + return false; + } + if (heavyAirBomber.TailLine != otherHeavyAirBomber.TailLine) + { + return false; + } + } + else if (airBomber is EntityHeavyAirBomber || otherAirBomberAirBomber is EntityHeavyAirBomber) return false; + return true; + } } } diff --git a/AirBomber/AirBomber/FormMapWithSetAirBombers.Designer.cs b/AirBomber/AirBomber/FormMapWithSetAirBombers.Designer.cs index 7af325c..92dfc1c 100644 --- a/AirBomber/AirBomber/FormMapWithSetAirBombers.Designer.cs +++ b/AirBomber/AirBomber/FormMapWithSetAirBombers.Designer.cs @@ -29,6 +29,8 @@ private void InitializeComponent() { this.groupBoxTools = new System.Windows.Forms.GroupBox(); + this.buttonSortByColor = new System.Windows.Forms.Button(); + this.buttonSortByType = new System.Windows.Forms.Button(); this.groupBoxMaps = new System.Windows.Forms.GroupBox(); this.buttonAddMap = new System.Windows.Forms.Button(); this.buttonDeleteMap = new System.Windows.Forms.Button(); @@ -59,6 +61,8 @@ // // groupBoxTools // + this.groupBoxTools.Controls.Add(this.buttonSortByColor); + this.groupBoxTools.Controls.Add(this.buttonSortByType); this.groupBoxTools.Controls.Add(this.groupBoxMaps); this.groupBoxTools.Controls.Add(this.buttonShowOnMap); this.groupBoxTools.Controls.Add(this.buttonRight); @@ -72,11 +76,31 @@ this.groupBoxTools.Dock = System.Windows.Forms.DockStyle.Right; this.groupBoxTools.Location = new System.Drawing.Point(621, 28); this.groupBoxTools.Name = "groupBoxTools"; - this.groupBoxTools.Size = new System.Drawing.Size(261, 695); + this.groupBoxTools.Size = new System.Drawing.Size(261, 744); this.groupBoxTools.TabIndex = 0; this.groupBoxTools.TabStop = false; this.groupBoxTools.Text = "Инструменты"; // + // buttonSortByColor + // + this.buttonSortByColor.Location = new System.Drawing.Point(6, 534); + this.buttonSortByColor.Name = "buttonSortByColor"; + this.buttonSortByColor.Size = new System.Drawing.Size(243, 29); + this.buttonSortByColor.TabIndex = 22; + this.buttonSortByColor.Text = "Сортировать по цвету"; + this.buttonSortByColor.UseVisualStyleBackColor = true; + this.buttonSortByColor.Click += new System.EventHandler(this.buttonSortByColor_Click); + // + // buttonSortByType + // + this.buttonSortByType.Location = new System.Drawing.Point(6, 499); + this.buttonSortByType.Name = "buttonSortByType"; + this.buttonSortByType.Size = new System.Drawing.Size(243, 29); + this.buttonSortByType.TabIndex = 21; + this.buttonSortByType.Text = "Сортировать по типу"; + this.buttonSortByType.UseVisualStyleBackColor = true; + this.buttonSortByType.Click += new System.EventHandler(this.buttonSortByType_Click); + // // groupBoxMaps // this.groupBoxMaps.Controls.Add(this.buttonAddMap); @@ -148,7 +172,7 @@ // // buttonShowOnMap // - this.buttonShowOnMap.Location = new System.Drawing.Point(6, 546); + this.buttonShowOnMap.Location = new System.Drawing.Point(6, 619); this.buttonShowOnMap.Name = "buttonShowOnMap"; this.buttonShowOnMap.Size = new System.Drawing.Size(243, 41); this.buttonShowOnMap.TabIndex = 19; @@ -161,7 +185,7 @@ this.buttonRight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonRight.BackgroundImage = global::AirBomber.Properties.Resources.arrowRight; this.buttonRight.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; - this.buttonRight.Location = new System.Drawing.Point(148, 653); + this.buttonRight.Location = new System.Drawing.Point(148, 702); this.buttonRight.Name = "buttonRight"; this.buttonRight.Size = new System.Drawing.Size(30, 30); this.buttonRight.TabIndex = 18; @@ -173,7 +197,7 @@ this.buttonDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonDown.BackgroundImage = global::AirBomber.Properties.Resources.arrowDown; this.buttonDown.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; - this.buttonDown.Location = new System.Drawing.Point(112, 653); + this.buttonDown.Location = new System.Drawing.Point(112, 702); this.buttonDown.Name = "buttonDown"; this.buttonDown.Size = new System.Drawing.Size(30, 30); this.buttonDown.TabIndex = 17; @@ -185,7 +209,7 @@ this.buttonLeft.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonLeft.BackgroundImage = global::AirBomber.Properties.Resources.arrowLeft; this.buttonLeft.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; - this.buttonLeft.Location = new System.Drawing.Point(76, 653); + this.buttonLeft.Location = new System.Drawing.Point(76, 702); this.buttonLeft.Name = "buttonLeft"; this.buttonLeft.Size = new System.Drawing.Size(30, 30); this.buttonLeft.TabIndex = 16; @@ -197,7 +221,7 @@ this.buttonUp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.buttonUp.BackgroundImage = global::AirBomber.Properties.Resources.arrowUp; this.buttonUp.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; - this.buttonUp.Location = new System.Drawing.Point(112, 617); + this.buttonUp.Location = new System.Drawing.Point(112, 666); this.buttonUp.Name = "buttonUp"; this.buttonUp.Size = new System.Drawing.Size(30, 30); this.buttonUp.TabIndex = 15; @@ -206,7 +230,7 @@ // // buttonShowStorage // - this.buttonShowStorage.Location = new System.Drawing.Point(6, 499); + this.buttonShowStorage.Location = new System.Drawing.Point(6, 572); this.buttonShowStorage.Name = "buttonShowStorage"; this.buttonShowStorage.Size = new System.Drawing.Size(243, 41); this.buttonShowStorage.TabIndex = 14; @@ -248,7 +272,7 @@ this.pictureBox.Dock = System.Windows.Forms.DockStyle.Fill; this.pictureBox.Location = new System.Drawing.Point(0, 28); this.pictureBox.Name = "pictureBox"; - this.pictureBox.Size = new System.Drawing.Size(621, 695); + this.pictureBox.Size = new System.Drawing.Size(621, 744); this.pictureBox.TabIndex = 1; this.pictureBox.TabStop = false; // @@ -299,7 +323,7 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(882, 723); + this.ClientSize = new System.Drawing.Size(882, 772); this.Controls.Add(this.pictureBox); this.Controls.Add(this.groupBoxTools); this.Controls.Add(this.menuStrip1); @@ -343,5 +367,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/AirBomber/AirBomber/FormMapWithSetAirBombers.cs b/AirBomber/AirBomber/FormMapWithSetAirBombers.cs index fc51939..527fe3d 100644 --- a/AirBomber/AirBomber/FormMapWithSetAirBombers.cs +++ b/AirBomber/AirBomber/FormMapWithSetAirBombers.cs @@ -58,6 +58,10 @@ namespace AirBomber MessageBox.Show(ex.Message); _logger.LogWarning($"Ошибка: {ex.Message}"); } + catch (ArgumentException ex) + { + MessageBox.Show(ex.Message); + } catch (StorageOverflowException ex) { MessageBox.Show(ex.Message); @@ -265,5 +269,25 @@ namespace AirBomber } } } + + private void buttonSortByType_Click(object sender, EventArgs e) + { + if (listBoxMaps.SelectedIndex == -1) + { + return; + } + _mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty].Sort(new AirBomberCompareByType()); + pictureBox.Image = _mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty].ShowSet(); + } + + private void buttonSortByColor_Click(object sender, EventArgs e) + { + if (listBoxMaps.SelectedIndex == -1) + { + return; + } + _mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty].Sort(new AirBomberCompareByColor()); + pictureBox.Image = _mapsCollection[listBoxMaps.SelectedItem?.ToString() ?? string.Empty].ShowSet(); + } } } diff --git a/AirBomber/AirBomber/IDrawingObject.cs b/AirBomber/AirBomber/IDrawingObject.cs index 7bdaa10..deb7de6 100644 --- a/AirBomber/AirBomber/IDrawingObject.cs +++ b/AirBomber/AirBomber/IDrawingObject.cs @@ -9,7 +9,7 @@ namespace AirBomber /// /// Интерфейс для работы с объектом, прорисовываемым на форме /// - internal interface IDrawingObject + internal interface IDrawingObject : IEquatable { /// /// Шаг перемещения объекта diff --git a/AirBomber/AirBomber/MapWithSetAirBombersGeneric.cs b/AirBomber/AirBomber/MapWithSetAirBombersGeneric.cs index 5c2ba88..90a81f2 100644 --- a/AirBomber/AirBomber/MapWithSetAirBombersGeneric.cs +++ b/AirBomber/AirBomber/MapWithSetAirBombersGeneric.cs @@ -137,6 +137,10 @@ namespace AirBomber _setAirBombers.Insert(DrawingObjectAirBomber.Create(rec) as T); } } + public void Sort(IComparer comparer) + { + _setAirBombers.SortSet(comparer); + } /// /// "Взбалтываем" набор, чтобы все элементы оказались в начале /// diff --git a/AirBomber/AirBomber/SetAirBombersGeneric.cs b/AirBomber/AirBomber/SetAirBombersGeneric.cs index f494dd8..b6fc2e6 100644 --- a/AirBomber/AirBomber/SetAirBombersGeneric.cs +++ b/AirBomber/AirBomber/SetAirBombersGeneric.cs @@ -44,7 +44,7 @@ namespace AirBomber { throw new StorageOverflowException(_maxCount); } - _places.Insert(0, airBomber); + Insert(airBomber, 0); return 0; } /// @@ -55,6 +55,10 @@ namespace AirBomber /// public int Insert(T airBomber, int position) { + foreach(var placedAirBomber in _places) + { + if ((placedAirBomber as DrawingObjectAirBomber).Equals(airBomber as DrawingObjectAirBomber)) throw new ArgumentException("Такой бомбардировщик уже существует!"); + } if (position < 0 || position >= _maxCount) { throw new AirBomberNotFoundException(position); @@ -117,5 +121,13 @@ namespace AirBomber } } } + public void SortSet(IComparer comparer) + { + if (comparer == null) + { + return; + } + _places.Sort(comparer); + } } }