From 0922c3809f88b80939c457c6387e3eca8d133ec2 Mon Sep 17 00:00:00 2001 From: olshab Date: Sun, 19 Nov 2023 17:11:10 +0400 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=81=D1=91=20=D0=B3=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AirBomber/BomberForm.Designer.cs | 14 ++ AirBomber/BomberForm.cs | 41 +++++- AirBomber/FormEntityCollection.Designer.cs | 127 ++++++++++++++++++ AirBomber/FormEntityCollection.cs | 61 +++++++++ AirBomber/FormEntityCollection.resx | 60 +++++++++ .../Generics/EntitiesGenericCollection.cs | 102 ++++++++++++++ AirBomber/Generics/SetGeneric.cs | 75 +++++++++++ AirBomber/Program.cs | 2 +- AirBomber/Rendering/BomberRendererBase.cs | 2 + 9 files changed, 477 insertions(+), 7 deletions(-) create mode 100644 AirBomber/FormEntityCollection.Designer.cs create mode 100644 AirBomber/FormEntityCollection.cs create mode 100644 AirBomber/FormEntityCollection.resx create mode 100644 AirBomber/Generics/EntitiesGenericCollection.cs create mode 100644 AirBomber/Generics/SetGeneric.cs diff --git a/AirBomber/BomberForm.Designer.cs b/AirBomber/BomberForm.Designer.cs index 3d0b1ab..263277a 100644 --- a/AirBomber/BomberForm.Designer.cs +++ b/AirBomber/BomberForm.Designer.cs @@ -37,6 +37,7 @@ MovementStrategyComboBox = new ComboBox(); ButtonCreateBomber = new Button(); ButtonPerformMove = new Button(); + SelectBomberButton = new Button(); ((System.ComponentModel.ISupportInitialize)BomberPictureBox).BeginInit(); SuspendLayout(); // @@ -142,11 +143,23 @@ ButtonPerformMove.UseVisualStyleBackColor = true; ButtonPerformMove.Click += ButtonPerformStep_Click; // + // SelectBomberButton + // + SelectBomberButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + SelectBomberButton.Location = new Point(354, 407); + SelectBomberButton.Name = "SelectBomberButton"; + SelectBomberButton.Size = new Size(159, 42); + SelectBomberButton.TabIndex = 9; + SelectBomberButton.Text = "Выбрать бомбардировщик"; + SelectBomberButton.UseVisualStyleBackColor = true; + SelectBomberButton.Click += ButtonSelectEntity_Click; + // // BomberForm // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(884, 461); + Controls.Add(SelectBomberButton); Controls.Add(ButtonPerformMove); Controls.Add(ButtonCreateBomber); Controls.Add(MovementStrategyComboBox); @@ -175,5 +188,6 @@ private ComboBox MovementStrategyComboBox; private Button ButtonCreateBomber; private Button ButtonPerformMove; + private Button SelectBomberButton; } } \ No newline at end of file diff --git a/AirBomber/BomberForm.cs b/AirBomber/BomberForm.cs index e99539f..b53fb63 100644 --- a/AirBomber/BomberForm.cs +++ b/AirBomber/BomberForm.cs @@ -8,9 +8,14 @@ namespace AirBomber private BomberRendererBase? _bomberRenderer; private AbstractStrategy? _strategy; + public BomberRendererBase? SelectedRenderer { get; private set; } + public BomberForm() { InitializeComponent(); + + _strategy = null; + SelectedRenderer = null; } private void Draw() @@ -29,11 +34,22 @@ namespace AirBomber { Random random = new Random(); + Color BodyColor = Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)); + Color AdditionalColor = Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)); + + ColorDialog BodyColorPicker = new ColorDialog(); + if (BodyColorPicker.ShowDialog() == DialogResult.OK) + BodyColor = BodyColorPicker.Color; + + ColorDialog AdditionalColorPicker = new ColorDialog(); + if (AdditionalColorPicker.ShowDialog() == DialogResult.OK) + AdditionalColor = AdditionalColorPicker.Color; + _bomberRenderer = new BomberRenderer( random.Next(100, 300), random.Next(1000, 3000), - Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), - Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), + BodyColor, + AdditionalColor, true, true, BomberPictureBox.Width, @@ -49,10 +65,17 @@ namespace AirBomber { Random random = new Random(); + Color color = Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)); + ColorDialog dialog = new(); + if (dialog.ShowDialog() == DialogResult.OK) + { + color = dialog.Color; + } + _bomberRenderer = new BomberRendererBase( random.Next(100, 200), random.Next(1000, 1800), - Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), + color, BomberPictureBox.Width, BomberPictureBox.Height ); @@ -110,17 +133,17 @@ namespace AirBomber return; _strategy.SetData( - new ObjectEntityRenderer(_bomberRenderer), + _bomberRenderer.MovableObject, BomberPictureBox.Width, BomberPictureBox.Height ); - - MovementStrategyComboBox.Enabled = false; } if (_strategy is null) return; + MovementStrategyComboBox.Enabled = false; + _strategy.MakeStep(); Draw(); @@ -130,5 +153,11 @@ namespace AirBomber _strategy = null; } } + + private void ButtonSelectEntity_Click(object sender, EventArgs e) + { + SelectedRenderer = _bomberRenderer; + DialogResult = DialogResult.OK; + } } } diff --git a/AirBomber/FormEntityCollection.Designer.cs b/AirBomber/FormEntityCollection.Designer.cs new file mode 100644 index 0000000..ffb0a01 --- /dev/null +++ b/AirBomber/FormEntityCollection.Designer.cs @@ -0,0 +1,127 @@ +namespace AirBomber +{ + partial class FormEntityCollection + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + CollectionPictureBox = new PictureBox(); + ToolGroupBox = new GroupBox(); + RefreshCollectionButton = new Button(); + RemoveBomberButton = new Button(); + NumberMaskedTextBox = new MaskedTextBox(); + AddBomberButton = new Button(); + ((System.ComponentModel.ISupportInitialize)CollectionPictureBox).BeginInit(); + ToolGroupBox.SuspendLayout(); + SuspendLayout(); + // + // CollectionPictureBox + // + CollectionPictureBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + CollectionPictureBox.Location = new Point(0, 0); + CollectionPictureBox.Name = "CollectionPictureBox"; + CollectionPictureBox.Size = new Size(812, 603); + CollectionPictureBox.TabIndex = 0; + CollectionPictureBox.TabStop = false; + // + // ToolGroupBox + // + ToolGroupBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; + ToolGroupBox.Controls.Add(RefreshCollectionButton); + ToolGroupBox.Controls.Add(RemoveBomberButton); + ToolGroupBox.Controls.Add(NumberMaskedTextBox); + ToolGroupBox.Controls.Add(AddBomberButton); + ToolGroupBox.Location = new Point(818, 12); + ToolGroupBox.Name = "ToolGroupBox"; + ToolGroupBox.Size = new Size(176, 579); + ToolGroupBox.TabIndex = 1; + ToolGroupBox.TabStop = false; + ToolGroupBox.Text = "Инструменты"; + // + // RefreshCollectionButton + // + RefreshCollectionButton.Location = new Point(6, 190); + RefreshCollectionButton.Name = "RefreshCollectionButton"; + RefreshCollectionButton.Size = new Size(164, 30); + RefreshCollectionButton.TabIndex = 3; + RefreshCollectionButton.Text = "Обновить коллекцию"; + RefreshCollectionButton.UseVisualStyleBackColor = true; + RefreshCollectionButton.Click += ButtonRefreshCollection_Click; + // + // RemoveBomberButton + // + RemoveBomberButton.Location = new Point(6, 141); + RemoveBomberButton.Name = "RemoveBomberButton"; + RemoveBomberButton.Size = new Size(164, 30); + RemoveBomberButton.TabIndex = 2; + RemoveBomberButton.Text = "Удалить бомбардировщик"; + RemoveBomberButton.UseVisualStyleBackColor = true; + RemoveBomberButton.Click += ButtonRemoveEntity_Click; + // + // NumberMaskedTextBox + // + NumberMaskedTextBox.Location = new Point(6, 102); + NumberMaskedTextBox.Mask = "00000"; + NumberMaskedTextBox.Name = "NumberMaskedTextBox"; + NumberMaskedTextBox.Size = new Size(164, 23); + NumberMaskedTextBox.TabIndex = 1; + NumberMaskedTextBox.ValidatingType = typeof(int); + // + // AddBomberButton + // + AddBomberButton.Location = new Point(6, 32); + AddBomberButton.Name = "AddBomberButton"; + AddBomberButton.Size = new Size(164, 43); + AddBomberButton.TabIndex = 0; + AddBomberButton.Text = "Добавить бомбардировщик"; + AddBomberButton.UseVisualStyleBackColor = true; + AddBomberButton.Click += ButtonAddEntity_Click; + // + // FormEntityCollection + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(1006, 603); + Controls.Add(ToolGroupBox); + Controls.Add(CollectionPictureBox); + Name = "FormEntityCollection"; + Text = "Набор бомбардировщиков"; + ((System.ComponentModel.ISupportInitialize)CollectionPictureBox).EndInit(); + ToolGroupBox.ResumeLayout(false); + ToolGroupBox.PerformLayout(); + ResumeLayout(false); + } + + #endregion + + private PictureBox CollectionPictureBox; + private GroupBox ToolGroupBox; + private Button RefreshCollectionButton; + private Button RemoveBomberButton; + private MaskedTextBox NumberMaskedTextBox; + private Button AddBomberButton; + } +} \ No newline at end of file diff --git a/AirBomber/FormEntityCollection.cs b/AirBomber/FormEntityCollection.cs new file mode 100644 index 0000000..387477c --- /dev/null +++ b/AirBomber/FormEntityCollection.cs @@ -0,0 +1,61 @@ +using AirBomber.Generics; +using AirBomber.MovementStrategy; +using AirBomber.Rendering; + +namespace AirBomber +{ + public partial class FormEntityCollection : Form + { + private readonly EntitiesGenericCollection _entities; + + + public FormEntityCollection() + { + InitializeComponent(); + + _entities = new EntitiesGenericCollection( + CollectionPictureBox.Width, CollectionPictureBox.Height + ); + } + + public void ButtonAddEntity_Click(object sender, EventArgs e) + { + BomberForm Form = new BomberForm(); + + if (Form.ShowDialog() == DialogResult.OK) + { + if (_entities + Form.SelectedRenderer != -1) + { + MessageBox.Show("Объект добавлен"); + CollectionPictureBox.Image = _entities.ShowEntities(); + } + else + { + MessageBox.Show("Не удалось добавить объект"); + } + } + } + + public void ButtonRemoveEntity_Click(object sender, EventArgs e) + { + if (MessageBox.Show("Удалить объект?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) + return; + + int Pos = Convert.ToInt32(NumberMaskedTextBox.Text); + if (_entities - Pos == true) + { + MessageBox.Show("Объект удален"); + CollectionPictureBox.Image = _entities.ShowEntities(); + } + else + { + MessageBox.Show("Не удалось удалить объект"); + } + } + + public void ButtonRefreshCollection_Click(object sender, EventArgs e) + { + CollectionPictureBox.Image = _entities.ShowEntities(); + } + } +} diff --git a/AirBomber/FormEntityCollection.resx b/AirBomber/FormEntityCollection.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/AirBomber/FormEntityCollection.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/AirBomber/Generics/EntitiesGenericCollection.cs b/AirBomber/Generics/EntitiesGenericCollection.cs new file mode 100644 index 0000000..5867cb3 --- /dev/null +++ b/AirBomber/Generics/EntitiesGenericCollection.cs @@ -0,0 +1,102 @@ +using AirBomber.MovementStrategy; +using AirBomber.Rendering; + +namespace AirBomber.Generics +{ + internal class EntitiesGenericCollection + where T : BomberRendererBase + where U : IMovableObject + { + private readonly int _pictureWidth; + private readonly int _pictureHeight; + + private readonly int _placeSizeWidth = 200; + private readonly int _placeSizeHeight = 200; + + private readonly SetGeneric _collection; + + public EntitiesGenericCollection(int PictureWidth, int PictureHeight) + { + int width = PictureWidth / _placeSizeWidth; + int height = PictureHeight / _placeSizeHeight; + _pictureWidth = PictureWidth; + _pictureHeight = PictureHeight; + _collection = new SetGeneric(width * height); + } + + public static int operator +(EntitiesGenericCollection collect, T? obj) + { + if (obj is null || collect is null) + return -1; + + return collect._collection.Insert(obj); + } + + public static bool operator -(EntitiesGenericCollection collect, int pos) + { + T? obj = collect._collection.Get(pos); + + if (obj != null) + return collect._collection.Remove(pos); + + return false; + } + + public U? GetU(int pos) + { + return (U?)_collection.Get(pos)?.MovableObject; + } + + public Bitmap ShowEntities() + { + Bitmap bmp = new(_pictureWidth, _pictureHeight); + Graphics gr = Graphics.FromImage(bmp); + + DrawBackground(gr); + DrawObjects(gr); + + return bmp; + } + + private void DrawBackground(Graphics g) + { + Pen pen = new(Color.Black, 3); + + for (int i = 0; i < _pictureWidth / _placeSizeWidth; i++) + { + for (int j = 0; j < _pictureHeight / _placeSizeHeight + 1; ++j) + g.DrawLine( + pen, + i * _placeSizeWidth, j * _placeSizeHeight, + i * _placeSizeWidth + _placeSizeWidth / 2, j * _placeSizeHeight + ); + + g.DrawLine( + pen, + i * _placeSizeWidth, 0, + i * _placeSizeWidth, _pictureHeight / _placeSizeHeight * _placeSizeHeight + ); + } + } + + private void DrawObjects(Graphics g) + { + for (int i = 0; i < _collection.Count; i++) + { + T? Entity = _collection.Get(i); + + if (Entity is null) + continue; + + /** Установка позиции */ + int NumX = _pictureWidth / _placeSizeWidth; + + int PosX = (NumX - 1 - i % NumX) * _placeSizeWidth; + int PosY = (i / NumX) * _placeSizeHeight; + + Entity.SetPosition(PosX, PosY); + Entity.DrawEntity(g); + } + } + } +} diff --git a/AirBomber/Generics/SetGeneric.cs b/AirBomber/Generics/SetGeneric.cs new file mode 100644 index 0000000..1fe3b22 --- /dev/null +++ b/AirBomber/Generics/SetGeneric.cs @@ -0,0 +1,75 @@ +namespace AirBomber.Generics +{ + internal class SetGeneric + { + private readonly T?[] _objects; + + public int Count => _objects.Length; + + public SetGeneric(int Count) + { + _objects = new T?[Count]; + } + + public int Insert(T Entity) + { + for (int i = 0; i < Count; i++) + if (_objects[i] is null) + { + _objects[i] = Entity; + return i; + } + + return -1; + } + + public int Insert(T Entity, int Position) + { + if (Position >= Count) + return -1; + + if (_objects[Position] is null) + { + _objects[Position] = Entity; + return Position; + } + + /** Сдвиг элементов вправо начиная с Position до ближайшего пустого места */ + int EmptyPos = -1; + + for (int i = Position + 1; i < Count; i++) + if (_objects[i] is null) + { + EmptyPos = i; + break; + } + + if (EmptyPos == -1) + return -1; + + /** Сдвиг */ + for (int i = EmptyPos; i > Position; i--) + _objects[i] = _objects[i - 1]; + + _objects[Position] = Entity; + return Position; + } + + public bool Remove(int Position) + { + if (Position >= Count) + return false; + + _objects[Position] = default(T); + return true; + } + + public T? Get(int Position) + { + if (Position >= Count) + return default(T); + + return _objects[Position]; + } + } +} diff --git a/AirBomber/Program.cs b/AirBomber/Program.cs index 75d57f9..7c6cc77 100644 --- a/AirBomber/Program.cs +++ b/AirBomber/Program.cs @@ -6,7 +6,7 @@ namespace AirBomber static void Main() { ApplicationConfiguration.Initialize(); - Application.Run(new BomberForm()); + Application.Run(new FormEntityCollection()); } } } \ No newline at end of file diff --git a/AirBomber/Rendering/BomberRendererBase.cs b/AirBomber/Rendering/BomberRendererBase.cs index ae5ceb0..0856feb 100644 --- a/AirBomber/Rendering/BomberRendererBase.cs +++ b/AirBomber/Rendering/BomberRendererBase.cs @@ -25,6 +25,8 @@ namespace AirBomber.Rendering public int EntityWidth => _bomberWidth; public int EntityHeight => _bomberHeight; + public IMovableObject MovableObject => new ObjectEntityRenderer(this); + public BomberRendererBase(int Speed, double Weight, Color BodyColor, int Width, int Height) { if (Width < _bomberWidth || Height < _bomberHeight)