From c4e6dfff504beda1dc8fd7a5b77314072d9026f4 Mon Sep 17 00:00:00 2001 From: Dasha Date: Fri, 1 Dec 2023 18:41:28 +0400 Subject: [PATCH] done --- .../DrawningShip.cs} | 165 ++++++++++-------- .../DrawningObjects/DrawningWarmlyShip.cs | 84 +++++++++ WarmlyShip/Entities/EntityShip.cs | 45 +++++ WarmlyShip/{ => Entities}/EntityWarmlyShip.cs | 31 +--- WarmlyShip/FormWarmlyShip.Designer.cs | 70 ++++++-- WarmlyShip/FormWarmlyShip.cs | 113 ++++++++---- .../MovementStrategy/AbstractStrategy.cs | 148 ++++++++++++++++ .../MovementStrategy/DrawningObjectShip.cs | 43 +++++ .../MovementStrategy/IMoveableObject.cs | 37 ++++ WarmlyShip/MovementStrategy/MoveToBorder.cs | 61 +++++++ WarmlyShip/MovementStrategy/MoveToCenter.cs | 60 +++++++ .../MovementStrategy/ObjectParameters.cs | 67 +++++++ WarmlyShip/MovementStrategy/Status.cs | 18 ++ 13 files changed, 803 insertions(+), 139 deletions(-) rename WarmlyShip/{DrawningWarmlyShip.cs => DrawningObjects/DrawningShip.cs} (54%) create mode 100644 WarmlyShip/DrawningObjects/DrawningWarmlyShip.cs create mode 100644 WarmlyShip/Entities/EntityShip.cs rename WarmlyShip/{ => Entities}/EntityWarmlyShip.cs (63%) create mode 100644 WarmlyShip/MovementStrategy/AbstractStrategy.cs create mode 100644 WarmlyShip/MovementStrategy/DrawningObjectShip.cs create mode 100644 WarmlyShip/MovementStrategy/IMoveableObject.cs create mode 100644 WarmlyShip/MovementStrategy/MoveToBorder.cs create mode 100644 WarmlyShip/MovementStrategy/MoveToCenter.cs create mode 100644 WarmlyShip/MovementStrategy/ObjectParameters.cs create mode 100644 WarmlyShip/MovementStrategy/Status.cs diff --git a/WarmlyShip/DrawningWarmlyShip.cs b/WarmlyShip/DrawningObjects/DrawningShip.cs similarity index 54% rename from WarmlyShip/DrawningWarmlyShip.cs rename to WarmlyShip/DrawningObjects/DrawningShip.cs index 0a483c2..7113b93 100644 --- a/WarmlyShip/DrawningWarmlyShip.cs +++ b/WarmlyShip/DrawningObjects/DrawningShip.cs @@ -3,19 +3,19 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Windows.Forms.Design.Behavior; +using WarmlyShip.Entities; -namespace WarmlyShip +namespace WarmlyShip.DrawningObjects { /// /// Класс, отвечающий за прорисовку и перемещение объекта-сущности /// - internal class DrawningWarmlyShip + public class DrawningShip { /// /// Класс-сущность /// - public EntityWarmlyShip? EntityWarmlyShip { get; private set; } + public EntityShip? EntityShip { get; protected set; } /// /// Ширина окна /// @@ -27,44 +27,81 @@ namespace WarmlyShip /// /// Левая координата прорисовки корабля /// - private int _startPosX; + protected int _startPosX; /// /// Верхняя кооридната прорисовки корабля /// - private int _startPosY; + protected int _startPosY; /// /// Ширина прорисовки корабля /// - private readonly int _shipWidth = 140; + protected readonly int _shipWidth = 140; /// /// Высота прорисовки корабля /// - private readonly int _shipHeight = 60; + protected readonly int _shipHeight = 60; /// - /// Инициализация свойств + /// Координата X объекта + /// + public int GetPosX => _startPosX; + /// + /// Координата Y объекта + /// + public int GetPosY => _startPosY; + /// + /// Ширина объекта + /// + public int GetWidth => _shipWidth; + /// + /// Высота объекта + /// + public int GetHeight => _shipHeight; + + /// + /// Конструктор /// /// Скорость /// Вес - /// Цвет корпуса - /// Дополнительный цвет - /// Признак наличия труб - /// Признак наличия отсека для топлива + /// Основной цвет /// Ширина картинки /// Высота картинки - /// true - объект создан, false - проверка не пройдена, нельзя создать объект в этих размерах - public bool Init(int speed, double weight, Color bodyColor, Color additionalColor, bool pipe, bool fuelCompartment, int width, int height) + + public DrawningShip(int speed, double weight, Color bodyColor, int + width, int height) { if (width < _shipWidth || height < _shipHeight) { - return false; + return; } _pictureWidth = width; _pictureHeight = height; - - EntityWarmlyShip = new EntityWarmlyShip(); - EntityWarmlyShip.Init(speed, weight, bodyColor, additionalColor, pipe, fuelCompartment); - return true; + EntityShip = new EntityShip(speed, weight, bodyColor); } + + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Ширина картинки + /// Высота картинки + /// Ширина прорисовки корабля + /// Высота прорисовки корабля + protected DrawningShip(int speed, double weight, Color bodyColor, int + width, int height, int shipWidth, int shipHeight) + { + if (width < _shipWidth || height < _shipHeight) + { + return; + } + _pictureWidth = width; + _pictureHeight = height; + _shipWidth = shipWidth; + _shipHeight = shipHeight; + EntityShip = new EntityShip(speed, weight, bodyColor); + } + /// /// Установка позиции /// @@ -83,13 +120,39 @@ namespace WarmlyShip _startPosX = x; _startPosY = y; } + + /// + /// Проверка, что объект может переместится по указанному направлению + /// + /// Направление + /// true - можно переместится по указанному направлению + public bool CanMove(DirectionType direction) + { + if (EntityShip == null) + { + return false; + } + return direction switch + { + //влево + DirectionType.Left => _startPosX - EntityShip.Step > 0, + //вверх + DirectionType.Up => _startPosY - EntityShip.Step > 0, + //вправо + DirectionType.Right => _startPosX + _shipWidth + EntityShip.Step < _pictureWidth, + //вниз + DirectionType.Down => _startPosY + _shipHeight + EntityShip.Step < _pictureHeight, + _ => false, + }; + } + /// /// Изменение направления перемещения /// /// Направление public void MoveTransport(DirectionType direction) { - if (EntityWarmlyShip == null) + if (!CanMove(direction) || EntityShip == null) { return; } @@ -97,47 +160,37 @@ namespace WarmlyShip { //влево case DirectionType.Left: - if (_startPosX - EntityWarmlyShip.Step > 0) - { - _startPosX -= (int)EntityWarmlyShip.Step; - } + _startPosX -= (int)EntityShip.Step; break; //вверх case DirectionType.Up: - if (_startPosY - EntityWarmlyShip.Step > 0) - { - _startPosY -= (int)EntityWarmlyShip.Step; - } + _startPosY -= (int)EntityShip.Step; break; // вправо case DirectionType.Right: - if (_startPosX + _shipWidth + EntityWarmlyShip.Step < _pictureWidth) - { - _startPosX += (int)EntityWarmlyShip.Step; - } + _startPosX += (int)EntityShip.Step; break; //вниз case DirectionType.Down: - if (_startPosY + _shipHeight + EntityWarmlyShip.Step < _pictureHeight) - { - _startPosY += (int)EntityWarmlyShip.Step; - } + _startPosY += (int)EntityShip.Step; break; } } + /// /// Прорисовка объекта /// /// - public void DrawTransport(Graphics g) + public virtual void DrawTransport(Graphics g) { - if (EntityWarmlyShip == null) + if (EntityShip == null) { return; } + Pen pen = new(Color.Black); - Brush BodyBrush = new SolidBrush(EntityWarmlyShip.BodyColor); - Brush additionalBrush = new SolidBrush(EntityWarmlyShip.AdditionalColor); + Brush BodyBrush = new SolidBrush(EntityShip.BodyColor); + // корпус Point point1 = new Point(_startPosX, _startPosY + 30); Point point2 = new Point(_startPosX + 140, _startPosY + 30); @@ -163,34 +216,6 @@ namespace WarmlyShip Point point_7 = new Point(_startPosX + 129, _startPosY + 35); Point point_8 = new Point(_startPosX + 131, _startPosY + 35); g.DrawLine(pen, point_7, point_8); - if (EntityWarmlyShip.Pipe) - { - //трубы - g.FillRectangle(additionalBrush, _startPosX + 20, _startPosY + 5, 10, 15); - g.DrawRectangle(pen, _startPosX + 20, _startPosY + 5, 10, 15); - g.FillRectangle(additionalBrush, _startPosX + 60, _startPosY + 5, 10, 15); - g.DrawRectangle(pen, _startPosX + 60, _startPosY + 5, 10, 15); - g.FillRectangle(additionalBrush, _startPosX + 100, _startPosY + 5, 10, 15); - g.DrawRectangle(pen, _startPosX + 100, _startPosY + 5, 10, 15); - - Brush brBlack = new SolidBrush(Color.Black); - g.FillRectangle(brBlack, _startPosX + 20, _startPosY, 10, 5); - g.DrawRectangle(pen, _startPosX + 20, _startPosY, 10, 5); - g.FillRectangle(brBlack, _startPosX + 60, _startPosY, 10, 5); - g.DrawRectangle(pen, _startPosX + 60, _startPosY, 10, 5); - g.FillRectangle(brBlack, _startPosX + 100, _startPosY, 10, 5); - g.DrawRectangle(pen, _startPosX + 100, _startPosY, 10, 5); - } - if (EntityWarmlyShip.FuelCompartment) - { - // отсек под топливо - g.FillRectangle(additionalBrush, _startPosX + 30, _startPosY + 45, 20, 15); - g.DrawRectangle(pen, _startPosX + 30, _startPosY + 45, 20, 15); - g.FillRectangle(additionalBrush, _startPosX + 50, _startPosY + 45, 20, 15); - g.DrawRectangle(pen, _startPosX + 50, _startPosY + 45, 20, 15); - g.FillRectangle(additionalBrush, _startPosX + 70, _startPosY + 45, 20, 15); - g.DrawRectangle(pen, _startPosX + 70, _startPosY + 45, 20, 15); - } } } -} +} \ No newline at end of file diff --git a/WarmlyShip/DrawningObjects/DrawningWarmlyShip.cs b/WarmlyShip/DrawningObjects/DrawningWarmlyShip.cs new file mode 100644 index 0000000..b449df7 --- /dev/null +++ b/WarmlyShip/DrawningObjects/DrawningWarmlyShip.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WarmlyShip.Entities; + +namespace WarmlyShip.DrawningObjects +{ + /// + /// Класс, отвечающий за прорисовку и перемещение объекта-сущности + /// + public class DrawningWarmlyShip : DrawningShip + { + /// + /// Инициализация свойств + /// + /// Скорость + /// Вес + /// Цвет корпуса + /// Дополнительный цвет + /// Признак наличия труб + /// Признак наличия отсека для топлива + /// Ширина картинки + /// Высота картинки + /// true - объект создан, false - проверка не пройдена, нельзя создать объект в этих размерах + public DrawningWarmlyShip(int speed, double weight, Color bodyColor, Color +additionalColor, bool pipe, bool fuelCompartment, int width, int height) : + base(speed, weight, bodyColor, width, height, 140, 60) + { + if (EntityShip != null) + { + EntityShip = new EntityWarmlyShip(speed, weight, bodyColor, + additionalColor, pipe, fuelCompartment); + } + } + + /// + /// Прорисовка объекта + /// + /// + public override void DrawTransport(Graphics g) + { + if (EntityShip is not EntityWarmlyShip warmlyShip) + { + return; + } + Pen pen = new(Color.Black); + Brush additionalBrush = new SolidBrush(warmlyShip.AdditionalColor); + + if (warmlyShip.Pipe) + { + //трубы + g.FillRectangle(additionalBrush, _startPosX + 20, _startPosY + 5, 10, 15); + g.DrawRectangle(pen, _startPosX + 20, _startPosY + 5, 10, 15); + g.FillRectangle(additionalBrush, _startPosX + 60, _startPosY + 5, 10, 15); + g.DrawRectangle(pen, _startPosX + 60, _startPosY + 5, 10, 15); + g.FillRectangle(additionalBrush, _startPosX + 100, _startPosY + 5, 10, 15); + g.DrawRectangle(pen, _startPosX + 100, _startPosY + 5, 10, 15); + + Brush brBlack = new SolidBrush(Color.Black); + g.FillRectangle(brBlack, _startPosX + 20, _startPosY, 10, 5); + g.DrawRectangle(pen, _startPosX + 20, _startPosY, 10, 5); + g.FillRectangle(brBlack, _startPosX + 60, _startPosY, 10, 5); + g.DrawRectangle(pen, _startPosX + 60, _startPosY, 10, 5); + g.FillRectangle(brBlack, _startPosX + 100, _startPosY, 10, 5); + g.DrawRectangle(pen, _startPosX + 100, _startPosY, 10, 5); + } + + base.DrawTransport(g); + + if (warmlyShip.FuelCompartment) + { + // отсек под топливо + g.FillRectangle(additionalBrush, _startPosX + 30, _startPosY + 45, 20, 15); + g.DrawRectangle(pen, _startPosX + 30, _startPosY + 45, 20, 15); + g.FillRectangle(additionalBrush, _startPosX + 50, _startPosY + 45, 20, 15); + g.DrawRectangle(pen, _startPosX + 50, _startPosY + 45, 20, 15); + g.FillRectangle(additionalBrush, _startPosX + 70, _startPosY + 45, 20, 15); + g.DrawRectangle(pen, _startPosX + 70, _startPosY + 45, 20, 15); + } + } + } +} diff --git a/WarmlyShip/Entities/EntityShip.cs b/WarmlyShip/Entities/EntityShip.cs new file mode 100644 index 0000000..26231f3 --- /dev/null +++ b/WarmlyShip/Entities/EntityShip.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyShip.Entities +{ + /// + /// Класс-сущность "Корабль" + /// + public class EntityShip + { + /// + /// Скорость + /// + public int Speed { get; private set; } + /// + /// Вес + /// + public double Weight { get; private set; } + /// + /// Основной цвет + /// + public Color BodyColor { get; private set; } + + /// + /// Шаг перемещения корабля + /// + public double Step => (double)Speed * 100 / Weight; + + /// + /// Конструктор с параметрами + /// + /// Скорость + /// Вес корабля + /// Основной цвет + public EntityShip(int speed, double weight, Color bodyColor) + { + Speed = speed; + Weight = weight; + BodyColor = bodyColor; + } + } +} diff --git a/WarmlyShip/EntityWarmlyShip.cs b/WarmlyShip/Entities/EntityWarmlyShip.cs similarity index 63% rename from WarmlyShip/EntityWarmlyShip.cs rename to WarmlyShip/Entities/EntityWarmlyShip.cs index 9330e5a..e3994ab 100644 --- a/WarmlyShip/EntityWarmlyShip.cs +++ b/WarmlyShip/Entities/EntityWarmlyShip.cs @@ -4,22 +4,13 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace WarmlyShip +namespace WarmlyShip.Entities { - internal class EntityWarmlyShip + /// + /// Класс-сущность "Теплоход" + /// + public class EntityWarmlyShip : EntityShip { - /// - /// Скорость - /// - public int Speed { get; private set; } - /// - /// Вес - /// - public double Weight { get; private set; } - /// - /// Основной цвет - /// - public Color BodyColor { get; private set; } /// /// Дополнительный цвет (для опциональных элементов) /// @@ -33,10 +24,6 @@ namespace WarmlyShip /// public bool FuelCompartment { get; private set; } - /// - /// Шаг перемещения теплохода - /// - public double Step => (double)Speed * 100 / Weight; /// /// Инициализация полей объекта-класса теплохода /// @@ -46,16 +33,12 @@ namespace WarmlyShip /// Дополнительный цвет /// Признак наличия труб /// Признак наличия отсека под топливо - public void Init(int speed, double weight, Color bodyColor, Color - additionalColor, bool pipe, bool fuelCompartment) + public EntityWarmlyShip(int speed, double weight, Color bodyColor, Color + additionalColor, bool pipe, bool fuelCompartment) : base(speed, weight, bodyColor) { - Speed = speed; - Weight = weight; - BodyColor = bodyColor; AdditionalColor = additionalColor; Pipe = pipe; FuelCompartment = fuelCompartment; } } } - diff --git a/WarmlyShip/FormWarmlyShip.Designer.cs b/WarmlyShip/FormWarmlyShip.Designer.cs index 21be522..7d45a4f 100644 --- a/WarmlyShip/FormWarmlyShip.Designer.cs +++ b/WarmlyShip/FormWarmlyShip.Designer.cs @@ -29,11 +29,14 @@ private void InitializeComponent() { pictureBoxWarmlyShip = new PictureBox(); - buttonCreate = new Button(); buttonLeft = new Button(); buttonRight = new Button(); buttonUp = new Button(); buttonDown = new Button(); + comboBoxStrategy = new ComboBox(); + buttonCreateShip = new Button(); + buttonStep = new Button(); + buttonCreateWarmlyShip = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBoxWarmlyShip).BeginInit(); SuspendLayout(); // @@ -47,17 +50,6 @@ pictureBoxWarmlyShip.TabIndex = 0; pictureBoxWarmlyShip.TabStop = false; // - // buttonCreate - // - buttonCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - buttonCreate.Location = new Point(12, 426); - buttonCreate.Name = "buttonCreate"; - buttonCreate.Size = new Size(75, 23); - buttonCreate.TabIndex = 1; - buttonCreate.Text = "Создать"; - buttonCreate.UseVisualStyleBackColor = true; - buttonCreate.Click += ButtonCreate_Click; - // // buttonLeft // buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; @@ -106,16 +98,63 @@ buttonDown.UseVisualStyleBackColor = true; buttonDown.Click += ButtonMove_Click; // + // comboBoxStrategy + // + comboBoxStrategy.Anchor = AnchorStyles.Top | AnchorStyles.Right; + comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxStrategy.FormattingEnabled = true; + comboBoxStrategy.Items.AddRange(new object[] { "к центру", "к краю" }); + comboBoxStrategy.Location = new Point(751, 24); + comboBoxStrategy.Name = "comboBoxStrategy"; + comboBoxStrategy.Size = new Size(121, 23); + comboBoxStrategy.TabIndex = 6; + // + // buttonCreateShip + // + buttonCreateShip.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateShip.Location = new Point(108, 407); + buttonCreateShip.Name = "buttonCreateShip"; + buttonCreateShip.Size = new Size(80, 42); + buttonCreateShip.TabIndex = 7; + buttonCreateShip.Text = "Создать корабль"; + buttonCreateShip.UseVisualStyleBackColor = true; + buttonCreateShip.Click += buttonCreateShip_Click; + // + // buttonStep + // + buttonStep.Anchor = AnchorStyles.Top | AnchorStyles.Right; + buttonStep.Location = new Point(797, 53); + buttonStep.Name = "buttonStep"; + buttonStep.Size = new Size(75, 23); + buttonStep.TabIndex = 8; + buttonStep.Text = "Шаг"; + buttonStep.UseVisualStyleBackColor = true; + buttonStep.Click += buttonStep_Click; + // + // buttonCreateWarmlyShip + // + buttonCreateWarmlyShip.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateWarmlyShip.Location = new Point(12, 407); + buttonCreateWarmlyShip.Name = "buttonCreateWarmlyShip"; + buttonCreateWarmlyShip.Size = new Size(80, 42); + buttonCreateWarmlyShip.TabIndex = 9; + buttonCreateWarmlyShip.Text = "Создать теплоход"; + buttonCreateWarmlyShip.UseVisualStyleBackColor = true; + buttonCreateWarmlyShip.Click += buttonCreateWarmlyShip_Click; + // // FormWarmlyShip // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(884, 461); + Controls.Add(buttonCreateWarmlyShip); + Controls.Add(buttonStep); + Controls.Add(buttonCreateShip); + Controls.Add(comboBoxStrategy); Controls.Add(buttonDown); Controls.Add(buttonUp); Controls.Add(buttonRight); Controls.Add(buttonLeft); - Controls.Add(buttonCreate); Controls.Add(pictureBoxWarmlyShip); Name = "FormWarmlyShip"; StartPosition = FormStartPosition.CenterScreen; @@ -129,10 +168,13 @@ #endregion private PictureBox pictureBoxWarmlyShip; - private Button buttonCreate; private Button buttonLeft; private Button buttonRight; private Button buttonUp; private Button buttonDown; + private ComboBox comboBoxStrategy; + private Button buttonCreateShip; + private Button buttonStep; + private Button buttonCreateWarmlyShip; } } \ No newline at end of file diff --git a/WarmlyShip/FormWarmlyShip.cs b/WarmlyShip/FormWarmlyShip.cs index 7c9e35f..ae61f1c 100644 --- a/WarmlyShip/FormWarmlyShip.cs +++ b/WarmlyShip/FormWarmlyShip.cs @@ -1,24 +1,19 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; +using WarmlyShip.DrawningObjects; +using WarmlyShip.MovementStrategy; namespace WarmlyShip { - /// - /// Форма работы с объектом "Теплоход" - /// public partial class FormWarmlyShip : Form { /// - /// Поле-объект для прорисовки объекта + /// Форма работы с объектом "Теплоход" /// - private DrawningWarmlyShip? _drawningWarmlyShip; + private DrawningShip? _drawningShip; + + /// + /// Стратегия перемещения + /// + private AbstractStrategy? _abstractStrategy; /// /// Инициализация формы /// @@ -27,45 +22,59 @@ namespace WarmlyShip InitializeComponent(); } /// - /// Метод прорисовки теплохода + /// Метод прорисовки корабля /// private void Draw() { - if (_drawningWarmlyShip == null) + if (_drawningShip == null) { return; } Bitmap bmp = new(pictureBoxWarmlyShip.Width, pictureBoxWarmlyShip.Height); Graphics gr = Graphics.FromImage(bmp); - _drawningWarmlyShip.DrawTransport(gr); + _drawningShip.DrawTransport(gr); pictureBoxWarmlyShip.Image = bmp; } /// - /// Обработка нажатия кнопки "Создать" + /// Обработка нажатия кнопки "Создать теплоход" /// /// /// - private void ButtonCreate_Click(object sender, EventArgs e) + private void buttonCreateWarmlyShip_Click(object sender, EventArgs e) { Random random = new(); - _drawningWarmlyShip = new DrawningWarmlyShip(); - _drawningWarmlyShip.Init(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)), - Convert.ToBoolean(random.Next(0, 2)), + _drawningShip = new DrawningWarmlyShip(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)), Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2)), pictureBoxWarmlyShip.Width, pictureBoxWarmlyShip.Height); - _drawningWarmlyShip.SetPosition(random.Next(10, 100), random.Next(10, 100)); + _drawningShip.SetPosition(random.Next(10, 100), random.Next(10, 100)); Draw(); } /// - /// Изменение размеров формы + /// Обработка нажатия кнопки "Создать корабль" + /// + /// + /// + private void buttonCreateShip_Click(object sender, EventArgs e) + { + Random random = new(); + _drawningShip = new DrawningShip(random.Next(100, 300), random.Next(1000, 3000), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), + pictureBoxWarmlyShip.Width, pictureBoxWarmlyShip.Height); + _drawningShip.SetPosition(random.Next(10, 100), random.Next(10, 100)); + Draw(); + } + + /// + /// Изменение положения корабля /// /// /// private void ButtonMove_Click(object sender, EventArgs e) { - if (_drawningWarmlyShip == null) + if (_drawningShip == null) { return; } @@ -73,19 +82,61 @@ namespace WarmlyShip switch (name) { case "buttonUp": - _drawningWarmlyShip.MoveTransport(DirectionType.Up); + _drawningShip.MoveTransport(DirectionType.Up); break; case "buttonDown": - _drawningWarmlyShip.MoveTransport(DirectionType.Down); + _drawningShip.MoveTransport(DirectionType.Down); break; case "buttonLeft": - _drawningWarmlyShip.MoveTransport(DirectionType.Left); + _drawningShip.MoveTransport(DirectionType.Left); break; case "buttonRight": - _drawningWarmlyShip.MoveTransport(DirectionType.Right); + _drawningShip.MoveTransport(DirectionType.Right); break; } Draw(); } + + /// + /// Обработка нажатия кнопки "Шаг" + /// + /// + /// + private void buttonStep_Click(object sender, EventArgs e) + { + if (_drawningShip == null) + { + return; + } + if (comboBoxStrategy.Enabled) + { + _abstractStrategy = comboBoxStrategy.SelectedIndex + switch + { + 0 => new MoveToCenter(), + 1 => new MoveToBorder(), + _ => null, + }; + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.SetData(new + DrawningObjectShip(_drawningShip), pictureBoxWarmlyShip.Width, + pictureBoxWarmlyShip.Height); + comboBoxStrategy.Enabled = false; + } + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.MakeStep(); + Draw(); + if (_abstractStrategy.GetStatus() == Status.Finish) + { + comboBoxStrategy.Enabled = true; + _abstractStrategy = null; + } + } } } \ No newline at end of file diff --git a/WarmlyShip/MovementStrategy/AbstractStrategy.cs b/WarmlyShip/MovementStrategy/AbstractStrategy.cs new file mode 100644 index 0000000..23ca96f --- /dev/null +++ b/WarmlyShip/MovementStrategy/AbstractStrategy.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyShip.MovementStrategy +{ + /// + /// Класс-стратегия перемещения объекта + /// + public abstract class AbstractStrategy + { + /// + /// Перемещаемый объект + /// + private IMoveableObject? _moveableObject; + + /// + /// Статус перемещения + /// + private Status _state = Status.NotInit; + + /// + /// Ширина поля + /// + protected int FieldWidth { get; private set; } + + /// + /// Высота поля + /// + protected int FieldHeight { get; private set; } + + /// + /// Статус перемещения + /// + public Status GetStatus() { return _state; } + + /// + /// Установка данных + /// + /// Перемещаемый объект + /// Ширина поля + /// Высота поля + public void SetData(IMoveableObject moveableObject, int width, int height) + { + if (moveableObject == null) + { + _state = Status.NotInit; + return; + } + _state = Status.InProgress; + _moveableObject = moveableObject; + FieldWidth = width; + FieldHeight = height; + } + + /// + /// Шаг перемещения + /// + public void MakeStep() + { + if (_state != Status.InProgress) + { + return; + } + if (IsTargetDestinaion()) + { + _state = Status.Finish; + return; + } + MoveToTarget(); + } + + /// + /// Перемещение влево + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveLeft() => MoveTo(DirectionType.Left); + + /// + /// Перемещение вправо + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveRight() => MoveTo(DirectionType.Right); + + /// + /// Перемещение вверх + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveUp() => MoveTo(DirectionType.Up); + + /// + /// Перемещение вниз + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveDown() => MoveTo(DirectionType.Down); + + /// + /// Параметры объекта + /// + protected ObjectParameters? GetObjectParameters => + _moveableObject?.GetObjectPosition; + + /// + /// Шаг объекта + /// + /// + protected int? GetStep() + { + if (_state != Status.InProgress) + { + return null; + } + return _moveableObject?.GetStep; + } + + /// + /// Перемещение к цели + /// + protected abstract void MoveToTarget(); + + /// + /// Достигнута ли цель + /// + /// + protected abstract bool IsTargetDestinaion(); + + /// + /// Попытка перемещения в требуемом направлении + /// + /// Направление + /// Результат попытки (true - удалось переместиться, false - неудача) + private bool MoveTo(DirectionType directionType) + { + if (_state != Status.InProgress) + { + return false; + } + if (_moveableObject?.CheckCanMove(directionType) ?? false) + { + _moveableObject.MoveObject(directionType); + return true; + } + return false; + } + } +} diff --git a/WarmlyShip/MovementStrategy/DrawningObjectShip.cs b/WarmlyShip/MovementStrategy/DrawningObjectShip.cs new file mode 100644 index 0000000..19fe246 --- /dev/null +++ b/WarmlyShip/MovementStrategy/DrawningObjectShip.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WarmlyShip.DrawningObjects; + +namespace WarmlyShip.MovementStrategy +{ + /// + /// Реализация интерфейса IDrawningObject для работы с объектом DrawningShip (паттерн Adapter) + /// + public class DrawningObjectShip : IMoveableObject + { + private readonly DrawningShip? _drawningShip = null; + + public DrawningObjectShip(DrawningShip drawningShip) + { + _drawningShip = drawningShip; + } + + public ObjectParameters? GetObjectPosition + { + get + { + if (_drawningShip == null || _drawningShip.EntityShip == null) + { + return null; + } + return new ObjectParameters(_drawningShip.GetPosX, + _drawningShip.GetPosY, _drawningShip.GetWidth, _drawningShip.GetHeight); + } + } + + public int GetStep => (int)(_drawningShip?.EntityShip?.Step ?? 0); + + public bool CheckCanMove(DirectionType direction) => + _drawningShip?.CanMove(direction) ?? false; + + public void MoveObject(DirectionType direction) => + _drawningShip?.MoveTransport(direction); + } +} diff --git a/WarmlyShip/MovementStrategy/IMoveableObject.cs b/WarmlyShip/MovementStrategy/IMoveableObject.cs new file mode 100644 index 0000000..44bccff --- /dev/null +++ b/WarmlyShip/MovementStrategy/IMoveableObject.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyShip.MovementStrategy +{ + /// + /// Интерфейс для работы с перемещаемым объектом + /// + public interface IMoveableObject + { + /// + /// Получение координаты X объекта + /// + ObjectParameters? GetObjectPosition { get; } + + /// + /// Шаг объекта + /// + int GetStep { get; } + + /// + /// Проверка, можно ли переместиться по нужному направлению + /// + /// + /// + bool CheckCanMove(DirectionType direction); + + /// + /// Изменение направления пермещения объекта + /// + /// Направление + void MoveObject(DirectionType direction); + } +} diff --git a/WarmlyShip/MovementStrategy/MoveToBorder.cs b/WarmlyShip/MovementStrategy/MoveToBorder.cs new file mode 100644 index 0000000..a0c2c0a --- /dev/null +++ b/WarmlyShip/MovementStrategy/MoveToBorder.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyShip.MovementStrategy +{ + /// + /// Стратегия перемещения объекта в правый нижний край экрана + /// + public class MoveToBorder : AbstractStrategy + { + protected override bool IsTargetDestinaion() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + + return objParams.RightBorder <= FieldWidth && + objParams.RightBorder + GetStep() >= FieldWidth && + objParams.DownBorder <= FieldHeight && + objParams.DownBorder + GetStep() >= FieldHeight; + } + + protected override void MoveToTarget() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return; + } + var diffX = objParams.RightBorder - FieldWidth; + if (Math.Abs(diffX) > GetStep()) + { + if (diffX > 0) + { + MoveLeft(); + } + else + { + MoveRight(); + } + } + var diffY = objParams.DownBorder - FieldHeight; + if (Math.Abs(diffY) > GetStep()) + { + if (diffY > 0) + { + MoveUp(); + } + else + { + MoveDown(); + } + } + } + } +} diff --git a/WarmlyShip/MovementStrategy/MoveToCenter.cs b/WarmlyShip/MovementStrategy/MoveToCenter.cs new file mode 100644 index 0000000..1c6756b --- /dev/null +++ b/WarmlyShip/MovementStrategy/MoveToCenter.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyShip.MovementStrategy +{ + /// + /// Стратегия перемещения объекта в центр экрана + /// + public class MoveToCenter : AbstractStrategy + { + protected override bool IsTargetDestinaion() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + return objParams.ObjectMiddleHorizontal <= FieldWidth / 2 && + objParams.ObjectMiddleHorizontal + GetStep() >= FieldWidth / 2 && + objParams.ObjectMiddleVertical <= FieldHeight / 2 && + objParams.ObjectMiddleVertical + GetStep() >= FieldHeight / 2; + } + + protected override void MoveToTarget() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return; + } + var diffX = objParams.ObjectMiddleHorizontal - FieldWidth / 2; + if (Math.Abs(diffX) > GetStep()) + { + if (diffX > 0) + { + MoveLeft(); + } + else + { + MoveRight(); + } + } + var diffY = objParams.ObjectMiddleVertical - FieldHeight / 2; + if (Math.Abs(diffY) > GetStep()) + { + if (diffY > 0) + { + MoveUp(); + } + else + { + MoveDown(); + } + } + } + } +} diff --git a/WarmlyShip/MovementStrategy/ObjectParameters.cs b/WarmlyShip/MovementStrategy/ObjectParameters.cs new file mode 100644 index 0000000..633bcf6 --- /dev/null +++ b/WarmlyShip/MovementStrategy/ObjectParameters.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyShip.MovementStrategy +{ + /// + /// Параметры-координаты объекта + /// + public class ObjectParameters + { + private readonly int _x; + + private readonly int _y; + + private readonly int _width; + + private readonly int _height; + + /// + /// Левая граница + /// + public int LeftBorder => _x; + + /// + /// Верхняя граница + /// + public int TopBorder => _y; + + /// + /// Правая граница + /// + public int RightBorder => _x + _width; + + /// + /// Нижняя граница + /// + public int DownBorder => _y + _height; + + /// + /// Середина объекта + /// + public int ObjectMiddleHorizontal => _x + _width / 2; + + /// + /// Середина объекта + /// + public int ObjectMiddleVertical => _y + _height / 2; + + /// + /// Конструктор + /// + /// Координата X + /// Координата Y + /// Ширина + /// Высота + public ObjectParameters(int x, int y, int width, int height) + { + _x = x; + _y = y; + _width = width; + _height = height; + } + } +} diff --git a/WarmlyShip/MovementStrategy/Status.cs b/WarmlyShip/MovementStrategy/Status.cs new file mode 100644 index 0000000..a9b4fe8 --- /dev/null +++ b/WarmlyShip/MovementStrategy/Status.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyShip.MovementStrategy +{ + /// + /// Статус выполнения операции перемещения + /// + public enum Status + { + NotInit, + InProgress, + Finish + } +}