diff --git a/WarmlyShip/WarmlyShip/AbstractStrategy.cs b/WarmlyShip/WarmlyShip/AbstractStrategy.cs new file mode 100644 index 0000000..eab1b7a --- /dev/null +++ b/WarmlyShip/WarmlyShip/AbstractStrategy.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WarmlyShip.DrawingObjects; + + +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/WarmlyShip/DrawingObjectShip.cs b/WarmlyShip/WarmlyShip/DrawingObjectShip.cs new file mode 100644 index 0000000..e8716d2 --- /dev/null +++ b/WarmlyShip/WarmlyShip/DrawingObjectShip.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WarmlyShip.DrawingObjects; + +namespace WarmlyShip.MovementStrategy +{ + public class DrawingObjectShip : IMoveableObject + { + private readonly DrawingWarmlyShip? _drawingWarmlyShip = null; + public DrawingObjectShip(DrawingWarmlyShip drawingWarmlyShip) + { + _drawingWarmlyShip = drawingWarmlyShip; + } + public ObjectParameters? GetObjectPosition + { + get + { + if (_drawingWarmlyShip == null || _drawingWarmlyShip.EntityWarmlyShip == null) + { + return null; + } + return new ObjectParameters(_drawingWarmlyShip.GetPosX, + _drawingWarmlyShip.GetPosY, _drawingWarmlyShip.GetWidth, _drawingWarmlyShip.GetHeight); + } + } + public int GetStep => (int)(_drawingWarmlyShip?.EntityWarmlyShip?.Step ?? 0); + public bool CheckCanMove(DirectionType direction) => + _drawingWarmlyShip?.CanMove(direction) ?? false; + public void MoveObject(DirectionType direction) => + _drawingWarmlyShip?.MoveTransport(direction); + } +} diff --git a/WarmlyShip/WarmlyShip/DrawingWarmlyShip.cs b/WarmlyShip/WarmlyShip/DrawingWarmlyShip.cs index 12347d2..51b13e7 100644 --- a/WarmlyShip/WarmlyShip/DrawingWarmlyShip.cs +++ b/WarmlyShip/WarmlyShip/DrawingWarmlyShip.cs @@ -3,18 +3,16 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using WarmlyShip.Entities; -namespace WarmlyShip +namespace WarmlyShip.DrawingObjects { - /// - /// Класс, отвечающий за прорисовку и перемещение объекта-сущности - /// public class DrawingWarmlyShip { /// /// Класс-сущность /// - public EntityWarmlyShip? EntityWarmlyShip { get; private set; } + public EntityWarmlyShip? EntityWarmlyShip { get; protected set; } /// /// Ширина окна /// @@ -24,45 +22,63 @@ namespace WarmlyShip /// private int _pictureHeight; /// - /// Левая координата прорисовки теплохода + /// Левая координата прорисовки /// - private int _startPosX; + protected int _startPosX; /// - /// Верхняя кооридната прорисовки теплохода + /// Верхняя кооридната прорисовки /// - private int _startPosY; + protected int _startPosY; /// - /// Ширина прорисовки теплохода + /// Ширина прорисовки /// - private readonly int _WarmlyShipWidth = 180; + protected readonly int _WarmlyShipWidth = 185; /// - /// Высота прорисовки теплохода + /// Высота прорисовки /// - private readonly int _WarmlyShipHeight = 185; + protected readonly int _WarmlyShipHeight = 180; /// /// Инициализация свойств /// /// Скорость /// Вес - /// Цвет корпуса - /// Дополнительный цвет - /// Признак наличия труб - /// Признак наличия отсека для топлива + /// Цвет основы /// Ширина картинки /// Высота картинки - /// true - объект создан, false - проверка не пройдена,нельзя создать объект в этих размерах - public bool Init(int speed, double weight, Color bodyColor, Color additionalColor, bool pipes, bool section, - int width, int height) + /// true - объект создан, false - проверка не пройдена, + ///нельзя создать объект в этих размерах + + public DrawingWarmlyShip(int speed, double weight, Color bodyColor, int width, int height) { - if (width <_WarmlyShipWidth || height <_WarmlyShipHeight) + if (width < _WarmlyShipWidth || height < _WarmlyShipHeight) { - return false; + return; } _pictureWidth = width; _pictureHeight = height; - EntityWarmlyShip = new EntityWarmlyShip(); - EntityWarmlyShip.Init(speed, weight, bodyColor, additionalColor, pipes, section); - return true; + EntityWarmlyShip = new EntityWarmlyShip(speed, weight, bodyColor); + + } + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Ширина картинки + /// Высота картинки + /// Ширина прорисовки автомобиля + /// Высота прорисовки автомобиля + protected DrawingWarmlyShip(int speed, double weight, Color bodyColor, int + width, int height, int warmlyShipWidth, int warmlyShipHeight) + { + if (width <= _WarmlyShipWidth || height <= _WarmlyShipHeight) + return; + _pictureWidth = width; + _pictureHeight = height; + _WarmlyShipWidth = warmlyShipWidth; + _WarmlyShipHeight = warmlyShipHeight; + EntityWarmlyShip = new EntityWarmlyShip(speed, weight, bodyColor); } /// /// Установка позиции @@ -81,49 +97,12 @@ namespace WarmlyShip /// Изменение направления перемещения /// /// Направление - public void MoveTransport(DirectionType direction) - { - if (EntityWarmlyShip == null) - { - return; - } - switch (direction) - { - //влево - case DirectionType.Left: - if (_startPosX - EntityWarmlyShip.Step > 0) - { - _startPosX -= (int)EntityWarmlyShip.Step; - } - break; - //вверх - case DirectionType.Up: - if (_startPosY - EntityWarmlyShip.Step > 0) - { - _startPosY -= (int)EntityWarmlyShip.Step; - } - break; - // вправо - case DirectionType.Right: - if (_startPosX + _WarmlyShipWidth + EntityWarmlyShip.Step < _pictureWidth) - { - _startPosX += (int)EntityWarmlyShip.Step; - } - break; - //вниз - case DirectionType.Down: - if (_startPosY + _WarmlyShipHeight + EntityWarmlyShip.Step < _pictureHeight) - { - _startPosY += (int)EntityWarmlyShip.Step; - } - break; - } - } + /// /// Прорисовка объекта /// /// - public void DrawTransport(Graphics g) + public virtual void DrawTransport(Graphics g) { if (EntityWarmlyShip == null) { @@ -131,7 +110,7 @@ namespace WarmlyShip } Pen pen = new(Color.Black, 2); Pen anchor = new(Color.Black, 4); - Brush additionalBrush = new SolidBrush(EntityWarmlyShip.BodyColor); + Brush bodyBrush = new SolidBrush(EntityWarmlyShip.BodyColor); //корпус теплохода Point[] hull = new Point[] { @@ -140,31 +119,84 @@ namespace WarmlyShip new Point(_startPosX + 140, _startPosY + 185), new Point(_startPosX + 40, _startPosY + 185), }; - g.FillPolygon(additionalBrush, hull); + g.FillPolygon(bodyBrush, hull); g.DrawPolygon(pen, hull); - Brush bra = new SolidBrush(EntityWarmlyShip.AdditionalColor); //палуба - g.FillRectangle(bra, _startPosX + 25, _startPosY + 80, 130, 30); + g.FillRectangle(bodyBrush, _startPosX + 25, _startPosY + 80, 130, 30); g.DrawRectangle(pen, _startPosX + 25, _startPosY + 80, 130, 30); - //отсек для топлива - Brush brGray = new SolidBrush(Color.Gray); - if (EntityWarmlyShip.Section) - { - g.FillEllipse(brGray, _startPosX + 130, _startPosY + 130, 20, 20); - g.DrawEllipse(pen, _startPosX + 130, _startPosY + 130, 20, 20); - } - //трубы - if (EntityWarmlyShip.Pipes) - { - g.FillRectangle(brGray, _startPosX + 55, _startPosY, 25, 80); - g.DrawRectangle(pen, _startPosX + 55, _startPosY, 25, 80); - g.FillRectangle(brGray, _startPosX + 90, _startPosY + 20, 25, 60); - g.DrawRectangle(pen, _startPosX + 90, _startPosY + 20, 25, 60); - } + //якорь g.DrawLine(anchor, new Point(_startPosX + 50, _startPosY + 130), new Point(_startPosX + 50,_startPosY + 150)); g.DrawLine(anchor, new Point(_startPosX + 40, _startPosY + 140), new Point(_startPosX + 60, _startPosY + 140)); g.DrawLine(anchor, new Point(_startPosX + 45, _startPosY + 150), new Point(_startPosX + 55, _startPosY + 150)); } + public int GetPosX => _startPosX; + /// + /// Координата Y объекта + /// /// + public int GetPosY => _startPosY; + /// + /// Ширина объекта + /// + public int GetWidth => _WarmlyShipWidth; + /// + /// Высота объекта + /// + public int GetHeight => _WarmlyShipHeight; + /// + /// Проверка, что объект может переместится по указанному направлению + /// + /// Направление + /// true - можно переместится по указанному направлению + public bool CanMove(DirectionType direction) + { + if (EntityWarmlyShip == null) + { + return false; + } + return direction switch + { + //влево + DirectionType.Left => _startPosX - EntityWarmlyShip.Step > 0, + //вверх + DirectionType.Up => _startPosY - EntityWarmlyShip.Step > 0, + //вправо + DirectionType.Right => _startPosX + EntityWarmlyShip.Step + _WarmlyShipWidth < _pictureWidth, + //вниз + DirectionType.Down => _startPosY + EntityWarmlyShip.Step + _WarmlyShipHeight < _pictureHeight, + _ => false, + }; + } + /// + /// Изменение направления перемещения + /// + /// Направление + public void MoveTransport(DirectionType direction) + { + if (!CanMove(direction) || EntityWarmlyShip == null) + { + return; + } + switch (direction) + { + //влево + case DirectionType.Left: + _startPosX -= (int)EntityWarmlyShip.Step; + break; + //вверх + case DirectionType.Up: + _startPosY -= (int)EntityWarmlyShip.Step; + break; + // вправо + case DirectionType.Right: + _startPosX += (int)EntityWarmlyShip.Step; + break; + //вниз + case DirectionType.Down: + _startPosY += (int)EntityWarmlyShip.Step; + break; + } + } } } + diff --git a/WarmlyShip/WarmlyShip/DrawingWarmlyShipWithPipes.cs b/WarmlyShip/WarmlyShip/DrawingWarmlyShipWithPipes.cs new file mode 100644 index 0000000..a863924 --- /dev/null +++ b/WarmlyShip/WarmlyShip/DrawingWarmlyShipWithPipes.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WarmlyShip.Entities; + +namespace WarmlyShip.DrawingObjects +{ + public class DrawingWarmlyShipWithPipes : DrawingWarmlyShip + { + public DrawingWarmlyShipWithPipes(int speed, double weight, Color bodyColor, Color + additionalColor, bool pipes, bool section, int width, int height) + : base(speed, weight, bodyColor, width, height, 185, 180) + { + if (EntityWarmlyShip != null) + { + EntityWarmlyShip = new EntityWarmlyShipWithPipes(speed, weight, bodyColor, additionalColor, pipes, section); + } + } + public override void DrawTransport(Graphics g) + { + if (EntityWarmlyShip is not EntityWarmlyShipWithPipes warmlyShip) + { + return; + } + Pen pen = new(Color.Black, 2); + Pen anchor = new(Color.Black, 4); + Brush additionalBrush = new SolidBrush(EntityWarmlyShip.BodyColor); + //отсек для топлива + Brush brGray = new SolidBrush(Color.Gray); + if (EntityWarmlyShip.Section) + { + g.FillEllipse(brGray, _startPosX + 130, _startPosY + 130, 20, 20); + g.DrawEllipse(pen, _startPosX + 130, _startPosY + 130, 20, 20); + } + //трубы + if (EntityWarmlyShip.Pipes) + { + g.FillRectangle(brGray, _startPosX + 55, _startPosY, 25, 80); + g.DrawRectangle(pen, _startPosX + 55, _startPosY, 25, 80); + g.FillRectangle(brGray, _startPosX + 90, _startPosY + 20, 25, 60); + g.DrawRectangle(pen, _startPosX + 90, _startPosY + 20, 25, 60); + } + } + } +} diff --git a/WarmlyShip/WarmlyShip/EntityWarmlyShip.cs b/WarmlyShip/WarmlyShip/EntityWarmlyShip.cs index 6e78824..c7152c3 100644 --- a/WarmlyShip/WarmlyShip/EntityWarmlyShip.cs +++ b/WarmlyShip/WarmlyShip/EntityWarmlyShip.cs @@ -4,56 +4,19 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace WarmlyShip +namespace WarmlyShip.Entities { public class EntityWarmlyShip { - /// - /// Скорость - /// public int Speed { get; private set; } - /// - /// Вес - /// public double Weight { get; private set; } - /// - /// Основной цвет - /// public Color BodyColor { get; private set; } - /// - /// Дополнительный цвет (для опциональных элементов) - /// - public Color AdditionalColor { get; private set; } - /// - /// Признак (опция) наличия труб - /// - public bool Pipes { get; private set; } - /// - /// Признак (опция) наличия отсека для топлива - /// - public bool Section { get; private set; } - /// - /// Шаг перемещения теплохода - /// public double Step => (double)Speed * 100 / Weight; - /// - /// Инициализация полей объекта-класса теплохода - /// - /// Скорость - /// Вес теплохода - /// Основной цвет - /// Дополнительный цвет - /// Признак наличия труб - /// Признак наличия отсека для топлива - public void Init(int speed, double weight, Color bodyColor, Color - additionalColor, bool pipes, bool section) + public EntityWarmlyShip(int speed, double weight, Color bodyColor) { Speed = speed; Weight = weight; BodyColor = bodyColor; - AdditionalColor = additionalColor; - Pipes = pipes; - Section = section; } } } diff --git a/WarmlyShip/WarmlyShip/EntityWarmlyShipWithPipes.cs b/WarmlyShip/WarmlyShip/EntityWarmlyShipWithPipes.cs new file mode 100644 index 0000000..211be31 --- /dev/null +++ b/WarmlyShip/WarmlyShip/EntityWarmlyShipWithPipes.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WarmlyShip.Entities +{ + public class EntityWarmlyShipWithPipes : EntityWarmlyShip + { + public Color AdditionalColor { get; private set; } + public bool Pipes { get; private set; } + public bool Section { get; private set; } + public EntityWarmlyShipWithPipes(int speed, double weight, Color bodyColor, Color + additionalColor, bool pipes, bool section) + : base (speed, weight, bodyColor) + { + AdditionalColor = additionalColor; + Pipes = pipes; + Section = section; + } + } +} diff --git a/WarmlyShip/WarmlyShip/IMoveableObject.cs b/WarmlyShip/WarmlyShip/IMoveableObject.cs new file mode 100644 index 0000000..b9673f3 --- /dev/null +++ b/WarmlyShip/WarmlyShip/IMoveableObject.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WarmlyShip.DrawingObjects; + + +namespace WarmlyShip.MovementStrategy +{ + public interface IMoveableObject + { + ObjectParameters? GetObjectPosition { get; } + int GetStep { get; } + bool CheckCanMove(DirectionType direction); + void MoveObject(DirectionType direction); + } +} diff --git a/WarmlyShip/WarmlyShip/MoveToBorder.cs b/WarmlyShip/WarmlyShip/MoveToBorder.cs new file mode 100644 index 0000000..c005a16 --- /dev/null +++ b/WarmlyShip/WarmlyShip/MoveToBorder.cs @@ -0,0 +1,57 @@ +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/WarmlyShip/MoveToCenter.cs b/WarmlyShip/WarmlyShip/MoveToCenter.cs new file mode 100644 index 0000000..8f9a0e0 --- /dev/null +++ b/WarmlyShip/WarmlyShip/MoveToCenter.cs @@ -0,0 +1,56 @@ +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/WarmlyShip/ObjectParameters.cs b/WarmlyShip/WarmlyShip/ObjectParameters.cs new file mode 100644 index 0000000..512e373 --- /dev/null +++ b/WarmlyShip/WarmlyShip/ObjectParameters.cs @@ -0,0 +1,54 @@ +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/WarmlyShip/Status.cs b/WarmlyShip/WarmlyShip/Status.cs new file mode 100644 index 0000000..2fa54d6 --- /dev/null +++ b/WarmlyShip/WarmlyShip/Status.cs @@ -0,0 +1,15 @@ +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 + } +}