From 08e784d05ad62e0f899c0abfcf84ef944af4c177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=9C=D0=B0=D0=BB?= =?UTF-8?q?=D0=B0=D1=84=D0=B5=D0=B5=D0=B2?= Date: Mon, 25 Sep 2023 14:09:42 +0400 Subject: [PATCH] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=D0=94=D0=B2=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cruiser/{ => Drawing}/DrawingCruiser.cs | 152 +++++++++--------- Cruiser/Drawing/DrawingProCruiser.cs | 41 +++++ Cruiser/{ => Entities}/EntityCruiser.cs | 19 +-- Cruiser/Entities/EntityProCruiser.cs | 41 +++++ Cruiser/FormCruiser.Designer.cs | 61 +++++-- Cruiser/FormCruiser.cs | 75 ++++++++- Cruiser/MovementStrategy/AbstractStrategy.cs | 138 ++++++++++++++++ .../MovementStrategy/DrawingObjectCruiser.cs | 40 +++++ Cruiser/MovementStrategy/IMoveableObject.cs | 31 ++++ Cruiser/MovementStrategy/MoveToBorder.cs | 56 +++++++ Cruiser/MovementStrategy/MoveToCenter.cs | 57 +++++++ Cruiser/MovementStrategy/ObjectParametrs.cs | 58 +++++++ Cruiser/MovementStrategy/Status.cs | 18 +++ 13 files changed, 682 insertions(+), 105 deletions(-) rename Cruiser/{ => Drawing}/DrawingCruiser.cs (57%) create mode 100644 Cruiser/Drawing/DrawingProCruiser.cs rename Cruiser/{ => Entities}/EntityCruiser.cs (61%) create mode 100644 Cruiser/Entities/EntityProCruiser.cs create mode 100644 Cruiser/MovementStrategy/AbstractStrategy.cs create mode 100644 Cruiser/MovementStrategy/DrawingObjectCruiser.cs create mode 100644 Cruiser/MovementStrategy/IMoveableObject.cs create mode 100644 Cruiser/MovementStrategy/MoveToBorder.cs create mode 100644 Cruiser/MovementStrategy/MoveToCenter.cs create mode 100644 Cruiser/MovementStrategy/ObjectParametrs.cs create mode 100644 Cruiser/MovementStrategy/Status.cs diff --git a/Cruiser/DrawingCruiser.cs b/Cruiser/Drawing/DrawingCruiser.cs similarity index 57% rename from Cruiser/DrawingCruiser.cs rename to Cruiser/Drawing/DrawingCruiser.cs index cec146d..9206af7 100644 --- a/Cruiser/DrawingCruiser.cs +++ b/Cruiser/Drawing/DrawingCruiser.cs @@ -1,17 +1,18 @@ -using System; +using Cruiser.Entities; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Cruiser +namespace Cruiser.Drawing { public class DrawingCruiser { /// /// Класс-сущность /// - public EntityCruiser? EntityCruiser { get; private set; } + public EntityCruiser? EntityCruiser { get; set; } /// /// Ширина окна /// @@ -23,11 +24,11 @@ namespace Cruiser /// /// Левая координата прорисовки Крейсера /// - private static int _startPosX; + protected static int _startPosX; /// /// Верхняя кооридната прорисовки Крейсера /// - private static int _startPosY; + protected static int _startPosY; /// /// Ширина прорисовки Крейсера /// @@ -37,56 +38,59 @@ namespace Cruiser /// private readonly int _cruiserHeight = 60; /// - /// Цвет для палубы + /// Координата X объекта /// - public Color PalubaColor { get; private set; } + public int GetPosX => _startPosX; /// - /// Цвет для элементов + /// Координата Y объекта /// - public Color ElementsColor { get; private set; } + public int GetPosY => _startPosY; /// - /// Цвет для дополнений + /// Ширина объекта /// - public Color DopColor { get; private set; } + public int GetWidth => _cruiserWidth; /// - /// Шахты + /// Высота объекта /// - public bool Mines { get; private set; } + public int GetHeight => _cruiserHeight; /// - /// Верт. площадка - /// - public bool HelicopPad { get; private set; } - /// - /// Инициализация свойств + /// Конструктор /// /// Скорость /// Вес автомобиля /// Основной цвет /// Элементов цвет - /// Дополнений цвет - /// Признак наличия ракетных шахт - /// Признак наличия вертолётной площадки /// Ширина картинки /// Высота картинки - /// true - объект создан, false - проверка не пройдена, - ///нельзя создать объект в этих размерах - public bool Init(int speed, double weight, Color bodyColor, Color secColor, Color dopColor, bool rocketMines, bool helipad, int width, int height) + public DrawingCruiser(int speed, double weight, Color bodyColor, Color secColor, int width, int height) { - if (width < _cruiserWidth || height < _cruiserHeight) + if (width < _cruiserWidth || height < _cruiserHeight) { _pictureHeight = _cruiserHeight + 100; _pictureWidth = _cruiserWidth + 100; } _pictureWidth = width; _pictureHeight = height; - PalubaColor = bodyColor; - ElementsColor = secColor; - DopColor = dopColor; - Mines = rocketMines; - HelicopPad = helipad; - EntityCruiser = new EntityCruiser(); - EntityCruiser.Init(speed, weight, bodyColor, secColor, rocketMines, helipad); - return true; + EntityCruiser = new EntityCruiser(speed, weight, bodyColor, secColor); + } + /// + /// Конструктор + /// + /// Скорость + /// Вес автомобиля + /// Основной цвет + /// Элементов цвет + /// Ширина картинки + /// Высота картинки + /// Ширина прорисовки крейсера + /// Высота прорисовки крейсера + public DrawingCruiser(int speed, double weight, Color bodyColor, Color secColor, int width, int height, int cruiserWidth, int cruiserHeight) + { + _pictureWidth = width; + _pictureHeight = height; + _cruiserHeight = cruiserHeight; + _cruiserWidth = cruiserWidth; + EntityCruiser = new EntityCruiser(speed, weight, bodyColor, secColor); } /// /// Установка позиции @@ -95,24 +99,47 @@ namespace Cruiser /// Координата Y public void SetPosition(int x, int y) { - if (x < 0 || y < 0) + if (x < 0 || y < 0) + { + return; + } + if (x > _pictureWidth || y > _pictureHeight) { return; } - if (x > _pictureWidth || y > _pictureHeight) - { - return; - } _startPosX = x; _startPosY = y; } /// + /// Проверка, что объект может переместится по указанному направлению + /// + /// Направление + /// true - можно переместится по указанному направлению + public bool CanMove(Direction direction) + { + if (EntityCruiser == null) + { + return false; + } + return direction switch + { + //влево + Direction.Left => _startPosX - EntityCruiser.Step > 0, + //вверх + Direction.Up => _startPosY - EntityCruiser.Step > 0, + // вправо + Direction.Right => _startPosX + EntityCruiser.Step + _cruiserWidth < _pictureWidth, + //вниз + Direction.Down => _startPosY + EntityCruiser.Step + _cruiserHeight < _pictureHeight, + }; + } + /// /// Изменение направления перемещения /// /// Направление public void MoveTransport(Direction direction) { - if (EntityCruiser == null) + if (!CanMove(direction) || EntityCruiser == null) { return; } @@ -120,41 +147,30 @@ namespace Cruiser { //влево case Direction.Left: - if (_startPosX - EntityCruiser.Step > 0) - { - _startPosX -= (int)EntityCruiser.Step; - } + _startPosX -= (int)EntityCruiser.Step; break; //вверх case Direction.Up: - if (_startPosY - EntityCruiser.Step > 0) - { - _startPosY -= (int)EntityCruiser.Step; - } + _startPosY -= (int)EntityCruiser.Step; break; // вправо case Direction.Right: - if (_startPosX + EntityCruiser.Step < _pictureWidth - _cruiserWidth) - { - _startPosX += (int)EntityCruiser.Step; - } + _startPosX += (int)EntityCruiser.Step; break; //вниз case Direction.Down: - if (_startPosY + EntityCruiser.Step < _pictureHeight - _cruiserHeight) - { - _startPosY += (int)EntityCruiser.Step; - } + _startPosY += (int)EntityCruiser.Step; break; } } - - + + + /// /// Прорисовка объекта /// /// - public void DrawTransport(Graphics g) + public virtual void DrawTransport(Graphics g) { if (EntityCruiser == null) { @@ -169,10 +185,10 @@ namespace Cruiser new Point(_startPosX + 110,_startPosY + 60), new Point(_startPosX + 10,_startPosY + 60) }; - Brush brush = new SolidBrush(PalubaColor); + Brush brush = new SolidBrush(EntityCruiser.BodyColor); g.FillPolygon(brush, Paluba); // элементы - Point[] Elements = new Point[8] + Point[] Elements = new Point[8] { new Point(_startPosX + 50,_startPosY + 20), new Point(_startPosX + 70,_startPosY + 20), @@ -183,27 +199,13 @@ namespace Cruiser new Point(_startPosX + 70,_startPosY + 40), new Point(_startPosX + 50,_startPosY + 40), }; - Brush brushElem = new SolidBrush(ElementsColor); + Brush brushElem = new SolidBrush(EntityCruiser.SecondColor); g.FillPolygon(brushElem, Elements); g.FillEllipse(brushElem, _startPosX + 100, _startPosY + 20, 20, 20); // турбины Brush Turbins = new SolidBrush(Color.Black); g.FillRectangle(Turbins, _startPosX, _startPosY + 10, 10, 20); g.FillRectangle(Turbins, _startPosX, _startPosY + 35, 10, 20); - // шахты - if (Mines) - { - Brush DopBrush = new SolidBrush(DopColor); - g.FillRectangle(DopBrush, _startPosX + 15, _startPosY + 10, 10, 15); - g.FillRectangle(DopBrush, _startPosX + 30, _startPosY + 10, 10, 15); - } - // верт площадка - if (HelicopPad) - { - Brush DopBrush = new SolidBrush(DopColor); - g.FillEllipse(DopBrush, _startPosX + 15, _startPosY + 25, 25, 25); - } } - } } diff --git a/Cruiser/Drawing/DrawingProCruiser.cs b/Cruiser/Drawing/DrawingProCruiser.cs new file mode 100644 index 0000000..6ba87f2 --- /dev/null +++ b/Cruiser/Drawing/DrawingProCruiser.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Cruiser.Entities; + +namespace Cruiser.Drawing +{ + public class DrawingProCruiser : DrawingCruiser + { + public DrawingProCruiser(int speed, double weight, Color bodyColor, Color secColor, Color elemColor, bool rocketMines, bool helipad, int width, int height) : + base (speed, weight, bodyColor, secColor, width, height, 150, 60) + { + if (EntityCruiser != null) + { + EntityCruiser = new EntityProCruiser(speed, weight, bodyColor, secColor, elemColor, rocketMines, helipad); + } + } + public override void DrawTransport(Graphics g) + { + if (EntityCruiser is not EntityProCruiser cruiser) + { + return; + } + base.DrawTransport(g); + Brush DopBrush = new SolidBrush(cruiser.ElementsColor); + // шахты + if (cruiser.RocketMines) + { + g.FillRectangle(DopBrush, _startPosX + 15, _startPosY + 10, 10, 15); + g.FillRectangle(DopBrush, _startPosX + 30, _startPosY + 10, 10, 15); + } + // верт площадка + if (cruiser.Helipad) + { + g.FillEllipse(DopBrush, _startPosX + 15, _startPosY + 25, 25, 25); + } + } + } +} diff --git a/Cruiser/EntityCruiser.cs b/Cruiser/Entities/EntityCruiser.cs similarity index 61% rename from Cruiser/EntityCruiser.cs rename to Cruiser/Entities/EntityCruiser.cs index 6566ecf..6e4dbd8 100644 --- a/Cruiser/EntityCruiser.cs +++ b/Cruiser/Entities/EntityCruiser.cs @@ -4,8 +4,11 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Cruiser +namespace Cruiser.Entities { + /// + /// Класс-сущность "Крейсер" + /// public class EntityCruiser { /// @@ -25,14 +28,6 @@ namespace Cruiser /// public Color SecondColor { get; private set; } /// - /// Признак (опция) наличия ракетных шахт - /// - public bool RocketMines { get; private set; } - /// - /// Признак (опция) наличия вертолётной площадки - /// - public bool Helipad { get; private set; } - /// /// Шаг перемещения Крейсера /// public double Step => (double)Speed * 100 / Weight; @@ -40,16 +35,12 @@ namespace Cruiser /// Вес Крейсера /// Основной цвет /// Второстепенный цвет - /// Признак наличия ракетных шахт - /// Признак наличия вертолётной площадки - public void Init(int speed, double weight, Color bodyColor, Color secColor, bool rocketMines, bool helipad) + public EntityCruiser(int speed, double weight, Color bodyColor, Color secColor) { Speed = speed; Weight = weight; BodyColor = bodyColor; SecondColor = secColor; - RocketMines = rocketMines; - Helipad = helipad; } } } diff --git a/Cruiser/Entities/EntityProCruiser.cs b/Cruiser/Entities/EntityProCruiser.cs new file mode 100644 index 0000000..6cd23d6 --- /dev/null +++ b/Cruiser/Entities/EntityProCruiser.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Cruiser.Entities +{ + public class EntityProCruiser : EntityCruiser + { + /// + /// Элементов цвет + /// + public Color ElementsColor { get; private set; } + /// + /// Признак (опция) наличия ракетных шахт + /// + public bool RocketMines { get; private set; } + /// + /// Признак (опция) наличия вертолётной площадки + /// + public bool Helipad { get; private set; } + /// + /// Инициализация полей объекта-класса спортивного крейсера + /// + /// Скорость + /// Вес Крейсера + /// Основной цвет + /// Второстепенный цвет + /// Элементов цвет + /// Признак наличия ракетных шахт + /// Признак наличия вертолётной площадки + public EntityProCruiser(int speed, double weight, Color bodyColor, Color secColor, Color elemColor, bool rocketMines, bool helipad) : + base(speed, weight, bodyColor, secColor) + { + RocketMines = rocketMines; + Helipad = helipad; + ElementsColor = elemColor; + } +} +} diff --git a/Cruiser/FormCruiser.Designer.cs b/Cruiser/FormCruiser.Designer.cs index fb2e247..2c2f206 100644 --- a/Cruiser/FormCruiser.Designer.cs +++ b/Cruiser/FormCruiser.Designer.cs @@ -29,11 +29,14 @@ private void InitializeComponent() { pictureBoxCruiser = new PictureBox(); - buttonCreate = new Button(); + buttonCreateLiner = new Button(); buttonRight = new Button(); buttonDown = new Button(); buttonLeft = new Button(); buttonUp = new Button(); + buttonCreateProLiner = new Button(); + comboBoxStrategy = new ComboBox(); + ButtonStep = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBoxCruiser).BeginInit(); SuspendLayout(); // @@ -46,15 +49,15 @@ pictureBoxCruiser.TabIndex = 0; pictureBoxCruiser.TabStop = false; // - // buttonCreate + // buttonCreateLiner // - buttonCreate.Location = new Point(12, 402); - buttonCreate.Name = "buttonCreate"; - buttonCreate.Size = new Size(125, 36); - buttonCreate.TabIndex = 1; - buttonCreate.Text = "Создать"; - buttonCreate.UseVisualStyleBackColor = true; - buttonCreate.Click += buttonCreate_Click; + buttonCreateLiner.Location = new Point(12, 396); + buttonCreateLiner.Name = "buttonCreateLiner"; + buttonCreateLiner.Size = new Size(125, 48); + buttonCreateLiner.TabIndex = 1; + buttonCreateLiner.Text = "Создать Лайнер"; + buttonCreateLiner.UseVisualStyleBackColor = true; + buttonCreateLiner.Click += buttonCreateLiner_Click; // // buttonRight // @@ -100,16 +103,49 @@ buttonUp.UseVisualStyleBackColor = true; buttonUp.Click += ButtonMove_Click; // + // buttonCreateProLiner + // + buttonCreateProLiner.Location = new Point(143, 396); + buttonCreateProLiner.Name = "buttonCreateProLiner"; + buttonCreateProLiner.Size = new Size(125, 48); + buttonCreateProLiner.TabIndex = 6; + buttonCreateProLiner.Text = "Создать Лютый Лайнер"; + buttonCreateProLiner.UseVisualStyleBackColor = true; + buttonCreateProLiner.Click += buttonCreateProLiner_Click; + // + // comboBoxStrategy + // + comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxStrategy.FormattingEnabled = true; + comboBoxStrategy.Items.AddRange(new object[] { "MoveToCenter", "MoveToBorder" }); + comboBoxStrategy.Location = new Point(667, 12); + comboBoxStrategy.Name = "comboBoxStrategy"; + comboBoxStrategy.Size = new Size(121, 23); + comboBoxStrategy.TabIndex = 7; + // + // ButtonStep + // + ButtonStep.Location = new Point(713, 41); + ButtonStep.Name = "ButtonStep"; + ButtonStep.Size = new Size(75, 23); + ButtonStep.TabIndex = 8; + ButtonStep.Text = "Шаг"; + ButtonStep.UseVisualStyleBackColor = true; + ButtonStep.Click += ButtonStep_Click; + // // FormCruiser // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(800, 450); + Controls.Add(ButtonStep); + Controls.Add(comboBoxStrategy); + Controls.Add(buttonCreateProLiner); Controls.Add(buttonUp); Controls.Add(buttonLeft); Controls.Add(buttonDown); Controls.Add(buttonRight); - Controls.Add(buttonCreate); + Controls.Add(buttonCreateLiner); Controls.Add(pictureBoxCruiser); Name = "FormCruiser"; Text = "Cruiser"; @@ -120,10 +156,13 @@ #endregion private PictureBox pictureBoxCruiser; - private Button buttonCreate; + private Button buttonCreateLiner; private Button buttonRight; private Button buttonDown; private Button buttonLeft; private Button buttonUp; + private Button buttonCreateProLiner; + private ComboBox comboBoxStrategy; + private Button ButtonStep; } } \ No newline at end of file diff --git a/Cruiser/FormCruiser.cs b/Cruiser/FormCruiser.cs index b6e285e..91f29d1 100644 --- a/Cruiser/FormCruiser.cs +++ b/Cruiser/FormCruiser.cs @@ -1,4 +1,7 @@ using System; +using Cruiser.Drawing; +using Cruiser.Entities; +using Cruiser.MovementStrategy; namespace Cruiser { @@ -10,6 +13,10 @@ namespace Cruiser /// private DrawingCruiser? _drawningCruiser; /// + /// + /// + private AbstractStrategy? _abstractStrategy; + /// /// /// public FormCruiser() @@ -36,6 +43,11 @@ namespace Cruiser } + /// + /// + /// + /// + /// private void ButtonMove_Click(object sender, EventArgs e) { if (_drawningCruiser == null) @@ -60,17 +72,70 @@ namespace Cruiser } Draw(); } - private void buttonCreate_Click(object sender, EventArgs e) + /// + /// "" + /// + /// + /// + private void ButtonStep_Click(object sender, EventArgs e) + { + if (_drawningCruiser == null) + { + return; + } + if (comboBoxStrategy.Enabled) + { + _abstractStrategy = comboBoxStrategy.SelectedIndex + switch + { + 0 => new MoveToCenter(), + 1 => new MoveToBorder(), + _ => null, + }; + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.SetData(new + DrawningObjectCar(_drawningCruiser), pictureBoxCruiser.Width, + pictureBoxCruiser.Height); + comboBoxStrategy.Enabled = false; + } + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.MakeStep(); + Draw(); + if (_abstractStrategy.GetStatus() == Status.Finish) + { + comboBoxStrategy.Enabled = true; + _abstractStrategy = null; + } + } + private void buttonCreateLiner_Click(object sender, EventArgs e) { Random random = new(); - _drawningCruiser = new DrawingCruiser(); - _drawningCruiser.Init(random.Next(100, 300), + _drawningCruiser = new DrawingCruiser(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)), + pictureBoxCruiser.Width, + pictureBoxCruiser.Height); + _drawningCruiser.SetPosition(random.Next(10, 100), random.Next(10, 100)); + Draw(); + } + + private void buttonCreateProLiner_Click(object sender, EventArgs e) + { + Random random = new(); + _drawningCruiser = new DrawingProCruiser(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)), 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)), + Convert.ToBoolean(random.Next(1, 2)), + Convert.ToBoolean(random.Next(1, 2)), pictureBoxCruiser.Width, pictureBoxCruiser.Height); _drawningCruiser.SetPosition(random.Next(10, 100), random.Next(10, 100)); diff --git a/Cruiser/MovementStrategy/AbstractStrategy.cs b/Cruiser/MovementStrategy/AbstractStrategy.cs new file mode 100644 index 0000000..d5730f4 --- /dev/null +++ b/Cruiser/MovementStrategy/AbstractStrategy.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Cruiser.Drawing; + +namespace Cruiser.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(Direction.Left); + /// + /// Перемещение вправо + /// + /// Результат перемещения (true - удалось переместиться, + ///false - неудача) + protected bool MoveRight() => MoveTo(Direction.Right); + /// + /// Перемещение вверх + /// + /// Результат перемещения (true - удалось переместиться, + ///false - неудача) + protected bool MoveUp() => MoveTo(Direction.Up); + /// + /// Перемещение вниз + /// + /// Результат перемещения (true - удалось переместиться, + ///false - неудача) + protected bool MoveDown() => MoveTo(Direction.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(Direction direction) + { + if (_state != Status.InProgress) + { + return false; + } + if (_moveableObject?.CheckCanMove(direction) ?? false) + { + _moveableObject.MoveObject(direction); + return true; + } + return false; + } + } +} diff --git a/Cruiser/MovementStrategy/DrawingObjectCruiser.cs b/Cruiser/MovementStrategy/DrawingObjectCruiser.cs new file mode 100644 index 0000000..b48e40d --- /dev/null +++ b/Cruiser/MovementStrategy/DrawingObjectCruiser.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Cruiser.Drawing; + +namespace Cruiser.MovementStrategy +{ + /// + /// Реализация интерфейса IDrawningObject для работы с объектом DrawningCar (паттерн Adapter) + /// + public class DrawningObjectCar : IMoveableObject + { + private readonly DrawingCruiser? _drawningCruiser = null; + public DrawningObjectCar(DrawingCruiser drawningCar) + { + _drawningCruiser = drawningCar; + } + public ObjectParameters? GetObjectPosition + { + get + { + if (_drawningCruiser == null || _drawningCruiser.EntityCruiser == + null) + { + return null; + } + return new ObjectParameters(_drawningCruiser.GetPosX, + _drawningCruiser.GetPosY, _drawningCruiser.GetWidth, _drawningCruiser.GetHeight); + } + } + public int GetStep => (int)(_drawningCruiser?.EntityCruiser?.Step ?? 0); + public bool CheckCanMove(Direction direction) => + _drawningCruiser?.CanMove(direction) ?? false; + public void MoveObject(Direction direction) => + _drawningCruiser?.MoveTransport(direction); + } + +} diff --git a/Cruiser/MovementStrategy/IMoveableObject.cs b/Cruiser/MovementStrategy/IMoveableObject.cs new file mode 100644 index 0000000..b2da552 --- /dev/null +++ b/Cruiser/MovementStrategy/IMoveableObject.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Cruiser.Drawing; +namespace Cruiser.MovementStrategy +{ + public interface IMoveableObject + { + /// + /// Получение координаты X объекта + /// + ObjectParameters? GetObjectPosition { get; } + /// + /// Шаг объекта + /// + int GetStep { get; } + /// + /// Проверка, можно ли переместиться по нужному направлению + /// + /// + /// + bool CheckCanMove(Direction direction); + /// + /// Изменение направления пермещения объекта + /// + /// Направление + void MoveObject(Direction direction); + } +} diff --git a/Cruiser/MovementStrategy/MoveToBorder.cs b/Cruiser/MovementStrategy/MoveToBorder.cs new file mode 100644 index 0000000..4770162 --- /dev/null +++ b/Cruiser/MovementStrategy/MoveToBorder.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Cruiser.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/Cruiser/MovementStrategy/MoveToCenter.cs b/Cruiser/MovementStrategy/MoveToCenter.cs new file mode 100644 index 0000000..2f54867 --- /dev/null +++ b/Cruiser/MovementStrategy/MoveToCenter.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Cruiser.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/Cruiser/MovementStrategy/ObjectParametrs.cs b/Cruiser/MovementStrategy/ObjectParametrs.cs new file mode 100644 index 0000000..aaca635 --- /dev/null +++ b/Cruiser/MovementStrategy/ObjectParametrs.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Cruiser.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/Cruiser/MovementStrategy/Status.cs b/Cruiser/MovementStrategy/Status.cs new file mode 100644 index 0000000..00d259e --- /dev/null +++ b/Cruiser/MovementStrategy/Status.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Cruiser.MovementStrategy +{ + /// + /// Статус выполнения операции перемещения + /// + public enum Status + { + NotInit, + InProgress, + Finish + } +}