diff --git a/WarmlyLocomotive/MovementStrategy/AbstractStrategy.cs b/WarmlyLocomotive/MovementStrategy/AbstractStrategy.cs new file mode 100644 index 0000000..ac16bea --- /dev/null +++ b/WarmlyLocomotive/MovementStrategy/AbstractStrategy.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyLocomotive.MovementStrategy; + +public abstract class AbstractStrategy +{ + /// + /// Перемещаемый объект + /// + private IMoveableObject? _moveableObject; + + /// + /// Статус перемещения + /// + private StrategyStatus _state = StrategyStatus.NotInit; + + /// + /// Ширина поля + /// + protected int FieldWidth { get; private set; } + + /// + /// Высота поля + /// + protected int FieldHeight { get; private set; } + + /// + /// Статус перемещения + /// + public StrategyStatus GetStatus() { return _state; } + + /// + /// Установка данных + /// + /// Перемещаемый объект + /// Ширина поля + /// Высота поля + public void SetData(IMoveableObject moveableObject, int width, int height) + { + if (moveableObject == null) + { + _state = StrategyStatus.NotInit; + return; + } + + _state = StrategyStatus.InProgress; + _moveableObject = moveableObject; + FieldWidth = width; + FieldHeight = height; + } + + /// + /// Шаг перемещения + /// + public void MakeStep() + { + if (_state != StrategyStatus.InProgress) + { + return; + } + + if (IsTargetDestinaion()) + { + _state = StrategyStatus.Finish; + return; + } + + MoveToTarget(); + } + + /// + /// Перемещение влево + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveLeft() => MoveTo(MovementDirection.Left); + + /// + /// Перемещение вправо + /// + /// Результат перемещения (true - удалось переместиться, false -неудача) + protected bool MoveRight() => MoveTo(MovementDirection.Right); + + /// + /// Перемещение вверх + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveUp() => MoveTo(MovementDirection.Up); + + /// + /// Перемещение вниз + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveDown() => MoveTo(MovementDirection.Down); + + /// + /// Параметры объекта + /// + protected ObjectParameters? GetObjectParameters => _moveableObject?.GetObjectPosition; + + /// + /// Шаг объекта + /// + /// + protected int? GetStep() + { + if (_state != StrategyStatus.InProgress) + { + return null; + } + + return _moveableObject?.GetStep; + } + + /// + /// Перемещение к цели + /// + protected abstract void MoveToTarget(); + + /// + /// Достигнута ли цель + /// + /// + protected abstract bool IsTargetDestinaion(); + + /// + /// Попытка перемещения в требуемом направлении + /// + /// Направление + /// Результат попытки (true - удалось переместиться, false - неудача) + private bool MoveTo(MovementDirection movementDirection) + { + if (_state != StrategyStatus.InProgress) + { + return false; + } + + return _moveableObject?.TryMoveObject(movementDirection) ?? false; + } +} diff --git a/WarmlyLocomotive/MovementStrategy/IMoveableObject.cs b/WarmlyLocomotive/MovementStrategy/IMoveableObject.cs index 01cf264..0bfac00 100644 --- a/WarmlyLocomotive/MovementStrategy/IMoveableObject.cs +++ b/WarmlyLocomotive/MovementStrategy/IMoveableObject.cs @@ -4,9 +4,24 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace WarmlyLocomotive.MovementStrategy +namespace WarmlyLocomotive.MovementStrategy; + +public interface IMoveableObject { - internal interface IMoveableObject - { - } + /// + /// Получение координаты объекта + /// + ObjectParameters? GetObjectPosition { get; } + + /// + /// Шаг объекта + /// + int GetStep { get; } + + /// + /// Попытка переместить объект в указанном направлении + /// + /// Направление + /// true - объект перемещен, false - перемещение невозможно + bool TryMoveObject(MovementDirection direction); } diff --git a/WarmlyLocomotive/MovementStrategy/MoveToBorder.cs b/WarmlyLocomotive/MovementStrategy/MoveToBorder.cs new file mode 100644 index 0000000..41e3307 --- /dev/null +++ b/WarmlyLocomotive/MovementStrategy/MoveToBorder.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyLocomotive.MovementStrategy; + +public class MoveToBorder : AbstractStrategy +{ + protected override bool IsTargetDestinaion() + { + ObjectParameters? objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + + return objParams.ObjectMiddleHorizontal - GetStep() <= FieldWidth && objParams.ObjectMiddleHorizontal + GetStep() >= FieldWidth && + objParams.ObjectMiddleVertical - GetStep() <= FieldHeight && objParams.ObjectMiddleVertical + GetStep() >= FieldHeight; + + } + + protected override void MoveToTarget() + { + ObjectParameters? objParams = GetObjectParameters; + + if (objParams == null) + { + return; + } + + int diffX = objParams.ObjectMiddleHorizontal - FieldWidth; + + if (Math.Abs(diffX) > GetStep()) + { + if (diffX > 0) + { + MoveLeft(); + } + else + { + MoveRight(); + } + } + + int diffY = objParams.ObjectMiddleVertical - FieldHeight; + + if (Math.Abs(diffY) > GetStep()) + { + if (diffY > 0) + { + MoveUp(); + } + else + { + MoveDown(); + } + } + } +} diff --git a/WarmlyLocomotive/MovementStrategy/MoveToCenter.cs b/WarmlyLocomotive/MovementStrategy/MoveToCenter.cs new file mode 100644 index 0000000..fd0cce7 --- /dev/null +++ b/WarmlyLocomotive/MovementStrategy/MoveToCenter.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyLocomotive.MovementStrategy; + +public class MoveToCenter : AbstractStrategy +{ + protected override bool IsTargetDestinaion() + { + ObjectParameters? objParams = GetObjectParameters; + + if (objParams == null) + { + return false; + } + + return objParams.ObjectMiddleHorizontal - GetStep() <= FieldWidth / 2 && objParams.ObjectMiddleHorizontal + GetStep() >= FieldWidth / 2 && + objParams.ObjectMiddleVertical - GetStep() <= FieldHeight / 2 && objParams.ObjectMiddleVertical + GetStep() >= FieldHeight / 2; + } + + protected override void MoveToTarget() + { + ObjectParameters? objParams = GetObjectParameters; + + if (objParams == null) + { + return; + } + + int diffX = objParams.ObjectMiddleHorizontal - FieldWidth / 2; + + if (Math.Abs(diffX) > GetStep()) + { + if (diffX > 0) + { + MoveLeft(); + } + else + { + MoveRight(); + } + } + + int diffY = objParams.ObjectMiddleVertical - FieldHeight / 2; + + if (Math.Abs(diffY) > GetStep()) + { + if (diffY > 0) + { + MoveUp(); + } + else + { + MoveDown(); + } + } + } +} diff --git a/WarmlyLocomotive/MovementStrategy/StrategyStatus.cs b/WarmlyLocomotive/MovementStrategy/StrategyStatus.cs new file mode 100644 index 0000000..d98eebc --- /dev/null +++ b/WarmlyLocomotive/MovementStrategy/StrategyStatus.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyLocomotive.MovementStrategy; + +public enum StrategyStatus +{ + /// + /// Все готово к началу + /// + NotInit, + + /// + /// Выполняется + /// + InProgress, + + /// + /// Завершено + /// + Finish +}