diff --git a/Liner/Liner/AbstractStrategy.cs b/Liner/Liner/AbstractStrategy.cs new file mode 100644 index 0000000..627031f --- /dev/null +++ b/Liner/Liner/AbstractStrategy.cs @@ -0,0 +1,134 @@ +using Liner.MovementStrategy; +using Liner; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Liner.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/Liner/Liner/DrawingAdditionalDeck.cs b/Liner/Liner/DrawingAdditionalDeck.cs new file mode 100644 index 0000000..d640729 --- /dev/null +++ b/Liner/Liner/DrawingAdditionalDeck.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Liner.Entities; + +namespace Liner.DrawingObjects +{ + public class DrawingAdditionalDeck : DrawingLiner + { + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Цвет кузова + /// Дополнительный цвет + /// Признак наличия второй палубы + /// Признак наличия третьей палубы + /// Ширина картинки + /// Высота картинки + /// true - объект создан, false - проверка не пройдена, нельзя создать объект в этих размерах + public DrawingAdditionalDeck(int speed, double weight, Color bodyColor, Color additionalColor, bool doubleDeck, bool tripleDeck, int width, int height) : base(speed, weight, bodyColor, width, height, 150, 95) + { + if (EntityLiner != null) + { + EntityLiner = new EntityAdditionalDeck(speed, weight, bodyColor, additionalColor, doubleDeck, tripleDeck); + } + + } + public override void DrawTransport(Graphics g) + { + if (EntityLiner is not EntityAdditionalDeck additionalDeck) + { + return; + } + Brush additionalBrush = new SolidBrush(additionalDeck.AdditionalColor); + base.DrawTransport(g); + // 2 Палуба + if (additionalDeck.DoubleDeck) + { + Point point1 = new Point(_startPosX + 30, _startPosY + 35); + Point point2 = new Point(_startPosX + 110, _startPosY + 35); + Point point3 = new Point(_startPosX + 110, _startPosY + 60); + Point point4 = new Point(_startPosX + 30, _startPosY + 60); + Point[] curvePoints = { point1, point2, point3, point4 }; + g.FillPolygon(additionalBrush, curvePoints); + + } + // 3 Палуба + if (additionalDeck.TripleDeck) + { + Point point1 = new Point(_startPosX + 50, _startPosY + 35); + Point point2 = new Point(_startPosX + 50, _startPosY + 10); + Point point3 = new Point(_startPosX + 90, _startPosY + 10); + Point point4 = new Point(_startPosX + 90, _startPosY + 35); + Point point5 = new Point(_startPosX + 110, _startPosY + 35); + Point point6 = new Point(_startPosX + 110, _startPosY + 60); + Point point7 = new Point(_startPosX + 30, _startPosY + 60); + Point point8 = new Point(_startPosX + 30, _startPosY + 35); + Point[] curvePoints = { point1, point2, point3, point4, point5, point6, point7, point8 }; + g.FillPolygon(additionalBrush, curvePoints); + } + } + } +} + diff --git a/Liner/Liner/DrawingLiner.cs b/Liner/Liner/DrawingLiner.cs index 895bf79..43b905b 100644 --- a/Liner/Liner/DrawingLiner.cs +++ b/Liner/Liner/DrawingLiner.cs @@ -4,16 +4,19 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using System.Windows.Forms; +using Liner.Entities; -namespace Liner +namespace Liner.DrawingObjects { + /// + /// Класс, отвечающий за прорисовку и перемещение объекта-сущности + /// public class DrawingLiner { /// /// Класс-сущность /// - public EntityLiner? EntityLiner { get; private set; } + public EntityLiner? EntityLiner { get; protected set; } /// /// Ширина окна /// @@ -25,42 +28,75 @@ namespace Liner /// /// Левая координата прорисовки лайнера /// - private int _startPosX; + protected int _startPosX; /// /// Верхняя кооридната прорисовки лайнера /// - private int _startPosY; + protected int _startPosY; /// /// Ширина прорисовки лайнера /// - private readonly int _linerWidth = 150; + protected readonly int _linerWidth = 150; /// /// Высота прорисовки лайнера /// - private readonly int _linerHeight = 95; + protected readonly int _linerHeight = 95; /// - /// Инициализация свойств + /// Координата X объекта + /// + public int GetPosX => _startPosX; + /// + /// Координата Y объекта + /// + public int GetPosY => _startPosY; + /// + /// Ширина объекта + /// + public int GetWidth => _linerWidth; + /// + /// Высота объекта + /// + public int GetHeight => _linerHeight; + + /// + /// Конструктор /// /// Скорость /// Вес - /// Цвет кузова - /// Дополнительный цвет - /// Признак наличия второй палубы - /// Признак наличия третьей палубы + /// Основной цвет /// Ширина картинки /// Высота картинки - /// true - объект создан, false - проверка не пройдена, нельзя создать объект в этих размерах - public bool Init(int speed, double weight, Color bodyColor, Color additionalColor, bool doubleDeck, bool tripleDeck, int width, int height) + public DrawingLiner(int speed, double weight, Color bodyColor, int width, int height) { if (width < _linerWidth || height < _linerHeight) { - return false; + return; } _pictureWidth = width; _pictureHeight = height; - EntityLiner = new EntityLiner(); - EntityLiner.Init(speed, weight, bodyColor, additionalColor, doubleDeck, tripleDeck); - return true; + EntityLiner = new EntityLiner(speed, weight, bodyColor); + } + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Ширина картинки + /// Высота картинки + /// Ширина прорисовки лайнера + /// Высота прорисовки лайнера + protected DrawingLiner(int speed, double weight, Color bodyColor, int width, int height, int linerWidth, int linerHeight) + { + if (width < _linerWidth || height < _linerHeight) + { + return; + } + _pictureWidth = width; + _pictureHeight = height; + _linerWidth = linerWidth; + _linerHeight = linerHeight; + EntityLiner = new EntityLiner(speed, weight, bodyColor); } /// /// Установка позиции @@ -78,7 +114,7 @@ namespace Liner /// Направление public void MoveTransport(DirectionType direction) { - if (EntityLiner == null) + if (!CanMove(direction) || EntityLiner == null) { return; } @@ -105,7 +141,7 @@ namespace Liner _startPosX += (int)EntityLiner.Step; } break; - // вниз + //вниз case DirectionType.Down: if (_startPosY + _linerHeight + EntityLiner.Step < _pictureHeight) { @@ -118,7 +154,7 @@ namespace Liner /// Прорисовка объекта /// /// - public void DrawTransport(Graphics g) + public virtual void DrawTransport(Graphics g) { if (EntityLiner == null) { @@ -139,33 +175,31 @@ namespace Liner g.FillEllipse(brBlue, _startPosX + 60, _startPosY + 70, 10, 10); g.FillEllipse(brBlue, _startPosX + 80, _startPosY + 70, 10, 10); g.FillEllipse(brBlue, _startPosX + 100, _startPosY + 70, 10, 10); - Brush additionalBrush = new SolidBrush(EntityLiner.AdditionalColor); - // 2 Палуба - if (EntityLiner.DoubleDeck) - { - Point point5 = new Point(_startPosX + 30, _startPosY + 35); - Point point6 = new Point(_startPosX + 110, _startPosY + 35); - Point point7 = new Point(_startPosX + 110, _startPosY + 60); - Point point8 = new Point(_startPosX + 30, _startPosY + 60); - Point[] curvePoints2 = { point5, point6, point7, point8 }; - g.FillPolygon(additionalBrush, curvePoints2); + } - } - // 3 Палуба - if (EntityLiner.TripleDeck) + /// + /// Проверка, что объект может переместится по указанному направлению + /// + /// Направление + /// true - можно переместится по указанному направлению + public bool CanMove(DirectionType direction) + { + if (EntityLiner == null) { - Point point5 = new Point(_startPosX + 50, _startPosY + 35); - Point point6 = new Point(_startPosX + 50, _startPosY + 10); - Point point7 = new Point(_startPosX + 90, _startPosY + 10); - Point point8 = new Point(_startPosX + 90, _startPosY + 35); - Point point9 = new Point(_startPosX + 110, _startPosY + 35); - Point point10 = new Point(_startPosX + 110, _startPosY + 60); - Point point11 = new Point(_startPosX + 30, _startPosY + 60); - Point point12 = new Point(_startPosX + 30, _startPosY + 35); - Point[] curvePoints2 = { point5, point6, point7, point8, point9, point10, point11, point12 }; - g.FillPolygon(additionalBrush, curvePoints2); + return false; } + return direction switch + { + //влево + DirectionType.Left => _startPosX - EntityLiner.Step > 0, + //вверх + DirectionType.Up => _startPosY - EntityLiner.Step > 0, + // вправо + DirectionType.Right => _startPosX + _linerWidth + EntityLiner.Step < _pictureWidth, + //вниз + DirectionType.Down => _startPosY + _linerHeight + EntityLiner.Step < _pictureHeight, + _ => false, + }; } } } - diff --git a/Liner/Liner/DrawingObjectLiner.cs b/Liner/Liner/DrawingObjectLiner.cs new file mode 100644 index 0000000..75f9221 --- /dev/null +++ b/Liner/Liner/DrawingObjectLiner.cs @@ -0,0 +1,34 @@ +using Liner.MovementStrategy; +using Liner; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Liner.DrawingObjects; + +namespace Liner.MovementStrategy +{ + public class DrawingObjectLiner : IMoveableObject + { + private readonly DrawingLiner? _drawingLiner = null; + public DrawingObjectLiner(DrawingLiner drawingLiner) + { + _drawingLiner = drawingLiner; + } + public ObjectParameters? GetObjectPosition + { + get + { + if (_drawingLiner == null || _drawingLiner.EntityLiner == null) + { + return null; + } + return new ObjectParameters(_drawingLiner.GetPosX, _drawingLiner.GetPosY, _drawingLiner.GetWidth, _drawingLiner.GetHeight); + } + } + public int GetStep => (int)(_drawingLiner?.EntityLiner?.Step ?? 0); + public bool CheckCanMove(DirectionType direction) => _drawingLiner?.CanMove(direction) ?? false; + public void MoveObject(DirectionType direction) => _drawingLiner?.MoveTransport(direction); + } +} diff --git a/Liner/Liner/EntityAdditionalDeck.cs b/Liner/Liner/EntityAdditionalDeck.cs new file mode 100644 index 0000000..dc24c45 --- /dev/null +++ b/Liner/Liner/EntityAdditionalDeck.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Liner.Entities +{ + /// + /// Класс-сущность "Лайнер" + /// + public class EntityAdditionalDeck : EntityLiner + { + /// + /// Дополнительный цвет (для опциональных элементов) + /// + public Color AdditionalColor { get; private set; } + /// + /// Признак (опция) наличия второй палубы + /// + public bool DoubleDeck { get; private set; } + /// + /// Признак (опция) наличия третьей палубы + /// + public bool TripleDeck { get; private set; } + /// + /// Инициализация полей объекта-класса лайнер + /// + /// Скорость + /// Вес лайнера + /// Основной цвет + /// Дополнительный цвет + /// Признак наличия второй палубы + /// Признак наличия третьей палубы + public EntityAdditionalDeck(int speed, double weight, Color bodyColor, Color additionalColor, bool doubleDeck, bool tripleDeck) : base(speed, weight, bodyColor) + { + AdditionalColor = additionalColor; + DoubleDeck = doubleDeck; + TripleDeck = tripleDeck; + } + } +} + diff --git a/Liner/Liner/EntityLiner.cs b/Liner/Liner/EntityLiner.cs index d05a9f4..022ca27 100644 --- a/Liner/Liner/EntityLiner.cs +++ b/Liner/Liner/EntityLiner.cs @@ -4,8 +4,11 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Liner +namespace Liner.Entities { + /// + /// Класс-сущность "Лайнер" + /// public class EntityLiner { /// @@ -21,39 +24,20 @@ namespace Liner /// public Color BodyColor { get; private set; } /// - /// Дополнительный цвет (для опциональных элементов) - /// - public Color AdditionalColor { get; private set; } - /// - /// Признак (опция) наличия второй палубы - /// - public bool DoubleDeck { get; private set; } - /// - /// Признак (опция) наличия третьей палубы - /// - public bool TripleDeck { get; private set; } - /// /// Шаг перемещения лайнера /// public double Step => (double)Speed * 100 / Weight; /// - /// Инициализация полей объекта-класса лайнера + /// Конструктор с параметрами /// /// Скорость /// Вес лайнера /// Основной цвет - /// Дополнительный цвет - /// Признак наличия второй палубы - /// Признак наличия третьей палубы - public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool doubleDeck, bool tripleDeck) + public EntityLiner(int speed, double weight, Color bodyColor) { Speed = speed; Weight = weight; BodyColor = bodyColor; - AdditionalColor = additionalColor; - DoubleDeck = doubleDeck; - TripleDeck = tripleDeck; } } } - diff --git a/Liner/Liner/FormLiner.Designer.cs b/Liner/Liner/FormLiner.Designer.cs index d3cc6ed..1b8deae 100644 --- a/Liner/Liner/FormLiner.Designer.cs +++ b/Liner/Liner/FormLiner.Designer.cs @@ -33,11 +33,14 @@ namespace Liner private void InitializeComponent() { pictureBoxLiner = new PictureBox(); - buttonCreate = new Button(); + buttonCreateAdditionalDeck = new Button(); buttonUp = new Button(); buttonLeft = new Button(); buttonDown = new Button(); buttonRight = new Button(); + buttonCreateLiner = new Button(); + comboBoxStrategy = new ComboBox(); + buttonStep = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBoxLiner).BeginInit(); SuspendLayout(); // @@ -50,16 +53,16 @@ namespace Liner pictureBoxLiner.TabIndex = 5; pictureBoxLiner.TabStop = false; // - // buttonCreate + // buttonCreateAdditionalDeck // - buttonCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - buttonCreate.Location = new Point(12, 409); - buttonCreate.Name = "buttonCreate"; - buttonCreate.Size = new Size(90, 30); - buttonCreate.TabIndex = 6; - buttonCreate.Text = "Создать"; - buttonCreate.UseVisualStyleBackColor = true; - buttonCreate.Click += ButtonCreate_Click; + buttonCreateAdditionalDeck.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateAdditionalDeck.Location = new Point(12, 389); + buttonCreateAdditionalDeck.Name = "buttonCreateAdditionalDeck"; + buttonCreateAdditionalDeck.Size = new Size(120, 50); + buttonCreateAdditionalDeck.TabIndex = 6; + buttonCreateAdditionalDeck.Text = "Создать усложнённый лайнер"; + buttonCreateAdditionalDeck.UseVisualStyleBackColor = true; + buttonCreateAdditionalDeck.Click += ButtonCreateAdditionalDeck_Click; // // buttonUp // @@ -109,16 +112,52 @@ namespace Liner buttonRight.UseVisualStyleBackColor = true; buttonRight.Click += ButtonMove_Click; // + // buttonCreateLiner + // + buttonCreateLiner.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateLiner.Location = new Point(138, 389); + buttonCreateLiner.Name = "buttonCreateLiner"; + buttonCreateLiner.Size = new Size(120, 50); + buttonCreateLiner.TabIndex = 11; + buttonCreateLiner.Text = "Создать простой лайнер"; + buttonCreateLiner.UseVisualStyleBackColor = true; + buttonCreateLiner.Click += ButtonCreateLiner_Click; + // + // comboBoxStrategy + // + comboBoxStrategy.Anchor = AnchorStyles.Top | AnchorStyles.Right; + comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxStrategy.FormattingEnabled = true; + comboBoxStrategy.Items.AddRange(new object[] { "В центр", "В правый нижний угол" }); + comboBoxStrategy.Location = new Point(719, 12); + comboBoxStrategy.Name = "comboBoxStrategy"; + comboBoxStrategy.Size = new Size(151, 28); + comboBoxStrategy.TabIndex = 12; + // + // buttonStep + // + buttonStep.Anchor = AnchorStyles.Top | AnchorStyles.Right; + buttonStep.Location = new Point(748, 46); + buttonStep.Name = "buttonStep"; + buttonStep.Size = new Size(94, 29); + buttonStep.TabIndex = 13; + buttonStep.Text = "Шаг"; + buttonStep.UseVisualStyleBackColor = true; + buttonStep.Click += ButtonStep_Click; + // // FormLiner // AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(882, 453); + Controls.Add(buttonStep); + Controls.Add(comboBoxStrategy); + Controls.Add(buttonCreateLiner); Controls.Add(buttonRight); Controls.Add(buttonDown); Controls.Add(buttonLeft); Controls.Add(buttonUp); - Controls.Add(buttonCreate); + Controls.Add(buttonCreateAdditionalDeck); Controls.Add(pictureBoxLiner); Name = "FormLiner"; Text = "Лайнер"; @@ -129,10 +168,13 @@ namespace Liner #endregion private PictureBox pictureBoxLiner; - private Button buttonCreate; + private Button buttonCreateAdditionalDeck; private Button buttonUp; private Button buttonLeft; private Button buttonDown; private Button buttonRight; + private Button buttonCreateLiner; + private ComboBox comboBoxStrategy; + private Button buttonStep; } } \ No newline at end of file diff --git a/Liner/Liner/FormLiner.cs b/Liner/Liner/FormLiner.cs index d4e96be..6436a33 100644 --- a/Liner/Liner/FormLiner.cs +++ b/Liner/Liner/FormLiner.cs @@ -1,4 +1,6 @@ -using Liner; +using Liner.DrawingObjects; +using Liner.MovementStrategy; +using Liner; namespace Liner { @@ -11,13 +13,17 @@ namespace Liner /// Поле-объект для прорисовки объекта /// private DrawingLiner? _drawingLiner; + /// + /// Стратегия перемещения + /// + private AbstractStrategy? _abstractStrategy; public FormLiner() { InitializeComponent(); } /// /// Метод прорисовки лайнера - /// > + /// private void Draw() { if (_drawingLiner == null) @@ -30,15 +36,14 @@ namespace Liner pictureBoxLiner.Image = bmp; } /// - /// Обработка нажатия кнопки "Создать лайнер" + /// Обработка нажатия кнопки "Создать усложненный лайнер" /// /// /// - private void ButtonCreate_Click(object sender, EventArgs e) + private void ButtonCreateAdditionalDeck_Click(object sender, EventArgs e) { Random random = new(); - _drawingLiner = new DrawingLiner(); - _drawingLiner.Init(random.Next(100, 300), + _drawingLiner = new DrawingAdditionalDeck(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)), @@ -49,6 +54,22 @@ namespace Liner Draw(); } /// + /// Обработка нажатия кнопки "Создать простой лайнер" + /// + /// + /// + private void ButtonCreateLiner_Click(object sender, EventArgs e) + { + Random random = new(); + _drawingLiner = new DrawingLiner(random.Next(100, 300), + random.Next(1000, 3000), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), + random.Next(0, 256)), + pictureBoxLiner.Width, pictureBoxLiner.Height); + _drawingLiner.SetPosition(random.Next(10, 100), random.Next(10, 100)); + Draw(); + } + /// /// Обработка нажатия кнопок движения /// /// @@ -77,5 +98,44 @@ namespace Liner } Draw(); } + /// + /// Обработка нажатия кнопки "Шаг" + /// + /// + /// + private void ButtonStep_Click(object sender, EventArgs e) + { + if (_drawingLiner == null) + { + return; + } + if (comboBoxStrategy.Enabled) + { + _abstractStrategy = comboBoxStrategy.SelectedIndex + switch + { + 0 => new MoveToCenter(), + 1 => new MoveToBorder(), + _ => null, + }; + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.SetData(new DrawingObjectLiner(_drawingLiner), pictureBoxLiner.Width, pictureBoxLiner.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/Liner/Liner/IMoveableObject.cs b/Liner/Liner/IMoveableObject.cs new file mode 100644 index 0000000..fea6293 --- /dev/null +++ b/Liner/Liner/IMoveableObject.cs @@ -0,0 +1,37 @@ +using Liner.MovementStrategy; +using Liner; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Liner.DrawingObjects; + +namespace Liner.MovementStrategy +{ + /// + /// Интерфейс для работы с перемещаемым объектом + /// + public interface IMoveableObject + { + /// + /// Получение координаты X объекта + /// + ObjectParameters? GetObjectPosition { get; } + /// + /// Шаг объекта + /// + int GetStep { get; } + /// + /// Проверка, можно ли переместиться по нужному направлению + /// + /// + /// + bool CheckCanMove(DirectionType direction); + /// + /// Изменение направления пермещения объекта + /// + /// Направление + void MoveObject(DirectionType direction); + } +} diff --git a/Liner/Liner/MoveToBorder.cs b/Liner/Liner/MoveToBorder.cs new file mode 100644 index 0000000..c1a1878 --- /dev/null +++ b/Liner/Liner/MoveToBorder.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace Liner.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/Liner/Liner/MoveToCenter.cs b/Liner/Liner/MoveToCenter.cs new file mode 100644 index 0000000..5f8cc05 --- /dev/null +++ b/Liner/Liner/MoveToCenter.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Liner.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/Liner/Liner/ObjectParameters.cs b/Liner/Liner/ObjectParameters.cs new file mode 100644 index 0000000..930dfff --- /dev/null +++ b/Liner/Liner/ObjectParameters.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Liner.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/Liner/Liner/Status.cs b/Liner/Liner/Status.cs new file mode 100644 index 0000000..0b193bf --- /dev/null +++ b/Liner/Liner/Status.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Liner.MovementStrategy +{ + public enum Status + { + NotInit, + InProgress, + Finish + } +}