diff --git a/DoubleDeckerBus/DoubleDeckerBus/DrawingDoubleDeckerBus.cs b/DoubleDeckerBus/DoubleDeckerBus/DrawingDoubleDeckerBus.cs
deleted file mode 100644
index 6d8f6ae..0000000
--- a/DoubleDeckerBus/DoubleDeckerBus/DrawingDoubleDeckerBus.cs
+++ /dev/null
@@ -1,268 +0,0 @@
-namespace DoubleDeckerBus;
-///
-///
-///
-public class DrawingDoubleDeckerBus
-{
- public EntityDoubleDeckerBus? EntityDoubleDeckerBus { get; private set; }
-
- private int? _pictureWidth;
-
- private int? _pictureHeight;
-
- private int? _startPosX;
-
- private int? _startPosY;
-
- private readonly int _DrawingBusWidth = 120;
-
- private readonly int _DrawingBusHight = 60;
-
- public void Init(int speed, double weight, Color bodyColor, Color additionalColor,bool secondFloor, bool stripes)
- {
- EntityDoubleDeckerBus = new EntityDoubleDeckerBus();
- EntityDoubleDeckerBus.Init(speed, weight, bodyColor, additionalColor, secondFloor, stripes);
- _pictureWidth = null;
- _pictureHeight = null;
- _startPosX = null;
- _startPosY = null;
- }
- ///
- /// размер окна
- ///
- ///
- ///
- ///
- public bool SetPictureSize(int width, int hight)
- {
- if (_DrawingBusWidth > width || _DrawingBusHight > hight)
- {
- return false;
- }
-
-
- _pictureWidth = width;
- _pictureHeight = hight;
-
- if (_startPosX.HasValue && (_startPosX.Value + _DrawingBusWidth > _pictureWidth))
- {
- _startPosX = _pictureWidth - _DrawingBusWidth;
- }
-
- if (_startPosY.HasValue && (_startPosY + _DrawingBusHight > _pictureHeight))
- {
- _startPosY = _pictureHeight - _DrawingBusHight;
- }
-
- return true;
-
- }
- ///
- /// установить начальную позицию
- ///
- ///
- ///
- public void SetPosition(int x, int y)
- {
- if (!_pictureHeight.HasValue || !_pictureWidth.HasValue)
- {
- return;
- }
-
- if (x < 0)
- {
- x = -x;
- }
- if (y < 0)
- {
- y = -y;
- }
-
- if (x + _DrawingBusWidth > _pictureWidth)
- {
- _startPosX = _pictureWidth - _DrawingBusWidth;
- }
- else
- {
- _startPosX = x;
- }
-
- if (y + _DrawingBusHight > _pictureHeight)
- {
- _startPosY = _pictureHeight - _DrawingBusHight;
- }
- else
- {
- _startPosY = y;
- }
- }
-
- public bool MoveTransport(DirectionType direction)
- {
- if (EntityDoubleDeckerBus == null || !_startPosX.HasValue || !_startPosY.HasValue)
- {
- return false;
- }
-
- switch (direction)
- {
- case DirectionType.Left:
- if (_startPosX.Value - EntityDoubleDeckerBus.Step > 0)
- {
- _startPosX -= (int)EntityDoubleDeckerBus.Step;
- }
- return true;
-
- case DirectionType.Up:
- if (_startPosY.Value - EntityDoubleDeckerBus.Step > 0)
- {
- _startPosY -= (int)EntityDoubleDeckerBus.Step;
- }
- return true;
- case DirectionType.Right:
- if (_startPosX.Value + _DrawingBusWidth + EntityDoubleDeckerBus.Step < _pictureWidth)
- {
- _startPosX += (int)EntityDoubleDeckerBus.Step;
- }
- return true;
- case DirectionType.Down:
- if (_startPosY.Value + _DrawingBusHight + EntityDoubleDeckerBus.Step < _pictureHeight)
- {
- _startPosY += (int)EntityDoubleDeckerBus.Step;
- }
- return true;
- default:
- return false;
-
- }
- }
-
- public void DrawTrasnport(Graphics g)
- {
- if (EntityDoubleDeckerBus == null || !_startPosX.HasValue || !_startPosY.HasValue)
- {
- return;
- }
-
- Pen pen = new(Color.Black);
- Brush additionalBrush = new SolidBrush(EntityDoubleDeckerBus.AdditionalColor);
- Brush mainBrush = new SolidBrush(EntityDoubleDeckerBus.BodyColor);
- Brush blueBr = new SolidBrush(Color.LightBlue);
-
-
- //кузов 1го этажа
- PointF[] bus = { new PointF((float)_startPosX + 5, (float)_startPosY + 20),
- new PointF((float)_startPosX + 5, (float)_startPosY + 45),
- new PointF((float)_startPosX + 105, (float)_startPosY + 45),
- new PointF((float)_startPosX + 105, (float)_startPosY + 25),
- new PointF((float)_startPosX + 102, (float)_startPosY + 20) };
- g.FillPolygon(mainBrush, bus);
- g.DrawPolygon(pen, bus);
-
- //полоски
- if (EntityDoubleDeckerBus.Stripes)
- {
- g.FillRectangle(additionalBrush, _startPosX.Value + 5, _startPosY.Value + 39, 100, 3);
- PointF[] stripe = { new PointF((float)_startPosX + 5, (float)_startPosY + 22), new PointF((float)_startPosX + 5, (float)_startPosY + 25), new PointF((float)_startPosX + 104, (float)_startPosY + 25), new PointF((float)_startPosX + 103, (float)_startPosY + 22) };
- g.FillPolygon(additionalBrush, stripe);
-
- }
-
- //окна 1ый этаж
- g.FillRectangle(blueBr, _startPosX.Value + 7, _startPosY.Value + 25, 12, 10);
- g.FillRectangle(blueBr, _startPosX.Value + 21, _startPosY.Value + 25, 12, 10);
- g.FillRectangle(blueBr, _startPosX.Value + 47, _startPosY.Value + 25, 6, 10);
- g.FillRectangle(blueBr, _startPosX.Value + 55, _startPosY.Value + 25, 13, 10);
- g.FillRectangle(blueBr, _startPosX.Value + 71, _startPosY.Value + 25, 14, 10);
-
- g.DrawRectangle(pen, _startPosX.Value + 7, _startPosY.Value + 25, 12, 10);
- g.DrawRectangle(pen, _startPosX.Value + 21, _startPosY.Value + 25, 12, 10);
- g.DrawRectangle(pen, _startPosX.Value + 47, _startPosY.Value + 25, 6, 10);
- g.DrawRectangle(pen, _startPosX.Value + 55, _startPosY.Value + 25, 13, 10);
- g.DrawRectangle(pen, _startPosX.Value + 71, _startPosY.Value + 25, 14, 10);
-
- //переднее окно первый этаж
- PointF[] window2 = { new PointF((float)_startPosX + 90, (float)_startPosY + 25),
- new PointF((float)_startPosX + 105, (float)_startPosY + 25),
- new PointF((float)_startPosX + 105, (float)_startPosY + 40),
- new PointF((float)_startPosX + 90, (float)_startPosY + 35) };
- g.FillPolygon(blueBr, window2);
- g.DrawPolygon(pen, window2);
-
- //дверь
- Brush brownBr = new SolidBrush(Color.Brown);
- g.FillRectangle(blueBr, _startPosX.Value + 35, _startPosY.Value + 25, 10, 15);
- g.FillRectangle(brownBr, _startPosX.Value + 35, _startPosY.Value + 40, 10, 5);
-
- g.DrawRectangle(pen, _startPosX.Value + 35, _startPosY.Value + 25, 10, 15);
- g.DrawRectangle(pen, _startPosX.Value + 35, _startPosY.Value + 40, 10, 5);
-
- //колёса
- g.FillEllipse(brownBr, _startPosX.Value + 11, _startPosY.Value + 37, 16, 16);
- g.FillEllipse(brownBr, _startPosX.Value + 83, _startPosY.Value + 37, 16, 16);
-
- g.DrawEllipse(pen, _startPosX.Value + 11, _startPosY.Value + 37, 16, 16);
- g.DrawEllipse(pen, _startPosX.Value + 83, _startPosY.Value + 37, 16, 16);
-
- //второй этаж с всякими зафуфрючками
- if (EntityDoubleDeckerBus.SecondFloor)
- {
- //верх кузова
- PointF[] bus_second_floor = { new PointF((float)_startPosX + 5, (float)_startPosY + 5),
- new PointF((float)_startPosX + 5, (float)_startPosY + 20),
- new PointF((float)_startPosX + 102, (float)_startPosY + 20),
- new PointF((float)_startPosX + 95, (float)_startPosY + 5)};
- g.FillPolygon(mainBrush, bus_second_floor);
- g.DrawPolygon(pen, bus_second_floor);
-
- //окна 2ой этаж
-
- g.FillRectangle(blueBr, _startPosX.Value + 7, _startPosY.Value + 10, 12, 10);
- g.FillRectangle(blueBr, _startPosX.Value + 21, _startPosY.Value + 10, 12, 10);
- g.FillRectangle(blueBr, _startPosX.Value + 35, _startPosY.Value + 10, 10, 10);
- g.FillRectangle(blueBr, _startPosX.Value + 47, _startPosY.Value + 10, 6, 10);
- g.FillRectangle(blueBr, _startPosX.Value + 55, _startPosY.Value + 10, 13, 10);
- g.FillRectangle(blueBr, _startPosX.Value + 71, _startPosY.Value + 10, 14, 10);
-
- g.DrawRectangle(pen, _startPosX.Value + 7, _startPosY.Value + 10, 12, 10);
- g.DrawRectangle(pen, _startPosX.Value + 21, _startPosY.Value + 10, 12, 10);
- g.DrawRectangle(pen, _startPosX.Value + 35, _startPosY.Value + 10, 10, 10);
- g.DrawRectangle(pen, _startPosX.Value + 47, _startPosY.Value + 10, 6, 10);
- g.DrawRectangle(pen, _startPosX.Value + 55, _startPosY.Value + 10, 13, 10);
- g.DrawRectangle(pen, _startPosX.Value + 71, _startPosY.Value + 10, 14, 10);
-
- //верхний отсек
- PointF[] section = { new PointF((float)_startPosX + 27, (float)_startPosY + 5),
- new PointF((float)_startPosX + 37, (float)_startPosY + 1),
- new PointF((float)_startPosX + 65, (float)_startPosY + 1),
- new PointF((float)_startPosX + 75, (float)_startPosY + 5) };
- g.FillPolygon(additionalBrush, section);
- g.DrawPolygon(pen, section);
-
- //переднее окно 2ой этаж
- PointF[] window1 = { new PointF((float)_startPosX + 90, (float)_startPosY + 10),
- new PointF((float)_startPosX + 97, (float)_startPosY + 10),
- new PointF((float)_startPosX + 102, (float)_startPosY + 20),
- new PointF((float)_startPosX + 90, (float)_startPosY + 20) };
- g.FillPolygon(blueBr, window1);
- g.DrawPolygon(pen, window1);
-
- //зеркала
- g.FillRectangle(mainBrush, _startPosX.Value + 95, _startPosY.Value + 5, 20, 5);
- g.FillRectangle(additionalBrush, _startPosX.Value + 110, _startPosY.Value + 10, 5, 5);
-
- g.DrawRectangle(pen, _startPosX.Value + 95, _startPosY.Value + 5, 20, 5);
- g.DrawRectangle(pen, _startPosX.Value + 110, _startPosY.Value + 10, 5, 5);
-
- //лестница
- g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 45), new Point(_startPosX.Value + 1, _startPosY.Value + 3));
- g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 45), new Point(_startPosX.Value + 5, _startPosY.Value + 43));
- g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 39), new Point(_startPosX.Value + 5, _startPosY.Value + 37));
- g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 31), new Point(_startPosX.Value + 5, _startPosY.Value + 29));
- g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 23), new Point(_startPosX.Value + 5, _startPosY.Value + 21));
- g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 15), new Point(_startPosX.Value + 5, _startPosY.Value + 13));
- g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 7), new Point(_startPosX.Value + 5, _startPosY.Value + 5));
- }
-
- }
-}
diff --git a/DoubleDeckerBus/DoubleDeckerBus/DirectionType.cs b/DoubleDeckerBus/DoubleDeckerBus/Drawnings/DirectionType.cs
similarity index 53%
rename from DoubleDeckerBus/DoubleDeckerBus/DirectionType.cs
rename to DoubleDeckerBus/DoubleDeckerBus/Drawnings/DirectionType.cs
index a05d391..347c4b9 100644
--- a/DoubleDeckerBus/DoubleDeckerBus/DirectionType.cs
+++ b/DoubleDeckerBus/DoubleDeckerBus/Drawnings/DirectionType.cs
@@ -1,8 +1,15 @@
-
-namespace DoubleDeckerBus;
-
+namespace DoubleDeckerBus.Drawnings;
+///
+/// Направление перемещения
+///
public enum DirectionType
-{ ///
+{
+ ///
+ /// Неизвестное направление
+ ///
+ Unknown = -1,
+
+ ///
/// вверх
///
Up = 1,
diff --git a/DoubleDeckerBus/DoubleDeckerBus/Drawnings/DrawingBus.cs b/DoubleDeckerBus/DoubleDeckerBus/Drawnings/DrawingBus.cs
new file mode 100644
index 0000000..92599a0
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/Drawnings/DrawingBus.cs
@@ -0,0 +1,280 @@
+using DoubleDeckerBus.Entities;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DoubleDeckerBus.Drawnings;
+
+///
+/// Класс, отвечающий за прорисовку и перемещение базового объекта-сущности
+///
+public class DrawingBus
+{
+ ///
+ /// Класс-сущность
+ ///
+ public EntityBus? EntityBus { get; protected set; }
+
+ ///
+ /// Ширина окна
+ ///
+ private int? _pictureWidth;
+
+ ///
+ /// Высота окна
+ ///
+ private int? _pictureHeight;
+
+ ///
+ /// Левая координата прорисовки автобуса
+ ///
+ protected int? _startPosX;
+
+ ///
+ /// Верхняя кооридната прорисовки автобуса
+ ///
+ protected int? _startPosY;
+
+ ///
+ /// Ширина прорисовки автобуса
+ ///
+ private readonly int _drawingBusWidth = 100;
+
+ ///
+ /// Высота прорисовки автобуса
+ ///
+ private readonly int _drawingBusHeight = 40;
+
+ ///
+ /// Координата X объекта
+ ///
+ public int? GetPosX => _startPosX;
+
+ ///
+ /// Координата Y объекта
+ ///
+ public int? GetPosY => _startPosY;
+
+ ///
+ /// Ширина объекта
+ ///
+ public int GetWidth => _drawingBusWidth;
+
+ ///
+ /// Высота объекта
+ ///
+ public int GetHeight => _drawingBusHeight;
+
+ ///
+ /// Пустой конструктор
+ ///
+ private DrawingBus()
+ {
+ _pictureWidth = null;
+ _pictureHeight = null;
+ _startPosX = null;
+ _startPosY = null;
+ }
+
+ ///
+ /// Конструктор
+ ///
+ /// Скорость
+ /// Вес
+ /// Основной цвет
+ public DrawingBus(int speed, int weight, Color bodyColor) : this()
+ {
+ EntityBus = new EntityBus(speed, weight, bodyColor);
+ }
+
+ ///
+ /// Конструктор для наследников
+ ///
+ /// Ширина прорисовки автобуса
+ /// Высота прорисовки автобуса
+ protected DrawingBus(int drawingBusWidth, int drawingBusHeight) : this()
+ {
+ _drawingBusWidth = drawingBusWidth;
+ _drawingBusHeight = drawingBusHeight;
+ }
+
+ ///
+ /// Установка границ поля
+ ///
+ /// Ширина поля
+ /// Высота поля
+ /// true - границы заданы, false - проверка не пройдена, нельзя разместить объект в этих размерах
+ public bool SetPictureSize(int width, int height)
+ {
+ if (_drawingBusWidth > width || _drawingBusHeight > height)
+ {
+ return false;
+ }
+
+
+ _pictureWidth = width;
+ _pictureHeight = height;
+
+ if (_startPosX.HasValue && _startPosX.Value + _drawingBusWidth > _pictureWidth)
+ {
+ _startPosX = _pictureWidth - _drawingBusWidth;
+ }
+
+ if (_startPosY.HasValue && _startPosY + _drawingBusHeight > _pictureHeight)
+ {
+ _startPosY = _pictureHeight - _drawingBusHeight;
+ }
+
+ return true;
+
+ }
+ ///
+ /// Установка позиции
+ ///
+ /// Координата X
+ /// Координа Y
+ public void SetPosition(int x, int y)
+ {
+ if (!_pictureHeight.HasValue || !_pictureWidth.HasValue)
+ {
+ return;
+ }
+
+ if (x < 0)
+ {
+ x = -x;
+ }
+ if (y < 0)
+ {
+ y = -y;
+ }
+
+ if (x + _drawingBusWidth > _pictureWidth)
+ {
+ _startPosX = _pictureWidth - _drawingBusWidth;
+ }
+ else
+ {
+ _startPosX = x;
+ }
+
+ if (y + _drawingBusHeight > _pictureHeight)
+ {
+ _startPosY = _pictureHeight - _drawingBusHeight;
+ }
+ else
+ {
+ _startPosY = y;
+ }
+ }
+
+ ///
+ /// Изменение направления перемещения
+ ///
+ /// Направление
+ /// true - перемещене выполнено, false - перемещение невозможно
+ public bool MoveTransport(DirectionType direction)
+ {
+ if (EntityBus == null || !_startPosX.HasValue || !_startPosY.HasValue)
+ {
+ return false;
+ }
+
+ switch (direction)
+ {
+ case DirectionType.Left:
+ if (_startPosX.Value - EntityBus.Step > 0)
+ {
+ _startPosX -= (int)EntityBus.Step;
+ }
+ return true;
+
+ case DirectionType.Up:
+ if (_startPosY.Value - EntityBus.Step > 0)
+ {
+ _startPosY -= (int)EntityBus.Step;
+ }
+ return true;
+ case DirectionType.Right:
+ if (_startPosX.Value + _drawingBusWidth + EntityBus.Step < _pictureWidth)
+ {
+ _startPosX += (int)EntityBus.Step;
+ }
+ return true;
+ case DirectionType.Down:
+ if (_startPosY.Value + _drawingBusHeight + EntityBus.Step < _pictureHeight)
+ {
+ _startPosY += (int)EntityBus.Step;
+ }
+ return true;
+ default:
+ return false;
+
+ }
+ }
+
+ ///
+ /// Прорисовка объекта
+ ///
+ ///
+ public virtual void DrawTrasnport(Graphics g)
+ {
+ if (EntityBus == null || !_startPosX.HasValue || !_startPosY.HasValue)
+ {
+ return;
+ }
+
+ Pen pen = new(Color.Black);
+ Brush mainBrush = new SolidBrush(EntityBus.BodyColor);
+ Brush blueBr = new SolidBrush(Color.LightBlue);
+
+
+ //кузов 1го этажа
+ PointF[] bus = { new PointF((float)_startPosX, (float)_startPosY),
+ new PointF((float)_startPosX, (float)_startPosY + 25),
+ new PointF((float)_startPosX + 100, (float)_startPosY + 25),
+ new PointF((float)_startPosX + 100, (float)_startPosY + 5),
+ new PointF((float)_startPosX + 97, (float)_startPosY) };
+ g.FillPolygon(mainBrush, bus);
+ g.DrawPolygon(pen, bus);
+
+ //окна 1ый этаж
+ g.FillRectangle(blueBr, _startPosX.Value + 2, _startPosY.Value + 5, 12, 10);
+ g.FillRectangle(blueBr, _startPosX.Value + 16, _startPosY.Value + 5, 12, 10);
+ g.FillRectangle(blueBr, _startPosX.Value + 42, _startPosY.Value + 5, 6, 10);
+ g.FillRectangle(blueBr, _startPosX.Value + 50, _startPosY.Value + 5, 13, 10);
+ g.FillRectangle(blueBr, _startPosX.Value + 66, _startPosY.Value + 5, 14, 10);
+
+ g.DrawRectangle(pen, _startPosX.Value + 2, _startPosY.Value + 5, 12, 10);
+ g.DrawRectangle(pen, _startPosX.Value + 16, _startPosY.Value + 5, 12, 10);
+ g.DrawRectangle(pen, _startPosX.Value + 42, _startPosY.Value + 5, 6, 10);
+ g.DrawRectangle(pen, _startPosX.Value + 50, _startPosY.Value + 5, 13, 10);
+ g.DrawRectangle(pen, _startPosX.Value + 66, _startPosY.Value + 5, 14, 10);
+
+ //переднее окно первый этаж
+ PointF[] window2 = { new PointF((float)_startPosX + 85, (float)_startPosY + 5),
+ new PointF((float)_startPosX + 100, (float)_startPosY + 5),
+ new PointF((float)_startPosX + 100, (float)_startPosY + 20),
+ new PointF((float)_startPosX + 85, (float)_startPosY + 15) };
+ g.FillPolygon(blueBr, window2);
+ g.DrawPolygon(pen, window2);
+
+ //дверь
+ Brush brownBr = new SolidBrush(Color.Brown);
+ g.FillRectangle(blueBr, _startPosX.Value + 30, _startPosY.Value + 5, 10, 15);
+ g.FillRectangle(brownBr, _startPosX.Value + 30, _startPosY.Value + 20, 10, 5);
+
+ g.DrawRectangle(pen, _startPosX.Value + 30, _startPosY.Value + 5, 10, 15);
+ g.DrawRectangle(pen, _startPosX.Value + 30, _startPosY.Value + 20, 10, 5);
+
+ //колёса
+ g.FillEllipse(brownBr, _startPosX.Value + 6, _startPosY.Value + 17, 16, 16);
+ g.FillEllipse(brownBr, _startPosX.Value + 78, _startPosY.Value + 17, 16, 16);
+
+ g.DrawEllipse(pen, _startPosX.Value + 6, _startPosY.Value + 17, 16, 16);
+ g.DrawEllipse(pen, _startPosX.Value + 78, _startPosY.Value + 17, 16, 16);
+
+ }
+}
diff --git a/DoubleDeckerBus/DoubleDeckerBus/Drawnings/DrawingDoubleDeckerBus.cs b/DoubleDeckerBus/DoubleDeckerBus/Drawnings/DrawingDoubleDeckerBus.cs
new file mode 100644
index 0000000..f3f2f04
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/Drawnings/DrawingDoubleDeckerBus.cs
@@ -0,0 +1,111 @@
+using DoubleDeckerBus.Entities;
+
+namespace DoubleDeckerBus.Drawnings;
+///
+/// Класс, отвечающий за прорисовку и перемещение продвинутого объекта сущности
+///
+public class DrawingDoubleDeckerBus : DrawingBus
+{
+ ///
+ /// Конструктор
+ ///
+ /// Скорость
+ /// Вес
+ /// Основной цвет
+ /// Доп цвет
+ /// Признак наличия второго этажа
+ /// Признак наличия полос на кузове
+ public DrawingDoubleDeckerBus(int speed, double weight, Color bodyColor, Color additionalColor, bool secondFloor, bool stripes) : base (115,55)
+ {
+ EntityBus = new EntityDoubleDeckerBus(speed, weight, bodyColor, additionalColor, secondFloor, stripes);
+ }
+
+ public override void DrawTrasnport(Graphics g)
+ {
+ if (EntityBus == null || EntityBus is not EntityDoubleDeckerBus doubleDeckerBus || !_startPosX.HasValue || !_startPosY.HasValue )
+ {
+ return;
+ }
+
+ Pen pen = new(Color.Black);
+ Brush additionalBrush = new SolidBrush(doubleDeckerBus.AdditionalColor);
+ Brush mainBrush = new SolidBrush(doubleDeckerBus.BodyColor);
+ Brush blueBr = new SolidBrush(Color.LightBlue);
+
+ _startPosX += 5;
+ _startPosY += 20;
+ base.DrawTrasnport(g);
+ _startPosX -= 5;
+ _startPosY -= 20;
+
+ //полоски
+ if (doubleDeckerBus.Stripes)
+ {
+ g.FillRectangle(additionalBrush, _startPosX.Value + 5, _startPosY.Value + 39, 100, 3);
+ PointF[] stripe = { new PointF((float)_startPosX + 5, (float)_startPosY + 22), new PointF((float)_startPosX + 5, (float)_startPosY + 25), new PointF((float)_startPosX + 104, (float)_startPosY + 25), new PointF((float)_startPosX + 103, (float)_startPosY + 22) };
+ g.FillPolygon(additionalBrush, stripe);
+
+ }
+
+ //второй этаж с всякими зафуфрючками
+ if (doubleDeckerBus.SecondFloor)
+ {
+ //верх кузова
+ PointF[] bus_second_floor = { new PointF((float)_startPosX + 5, (float)_startPosY + 5),
+ new PointF((float)_startPosX + 5, (float)_startPosY + 20),
+ new PointF((float)_startPosX + 102, (float)_startPosY + 20),
+ new PointF((float)_startPosX + 95, (float)_startPosY + 5)};
+ g.FillPolygon(mainBrush, bus_second_floor);
+ g.DrawPolygon(pen, bus_second_floor);
+
+ //окна 2ой этаж
+
+ g.FillRectangle(blueBr, _startPosX.Value + 7, _startPosY.Value + 10, 12, 10);
+ g.FillRectangle(blueBr, _startPosX.Value + 21, _startPosY.Value + 10, 12, 10);
+ g.FillRectangle(blueBr, _startPosX.Value + 35, _startPosY.Value + 10, 10, 10);
+ g.FillRectangle(blueBr, _startPosX.Value + 47, _startPosY.Value + 10, 6, 10);
+ g.FillRectangle(blueBr, _startPosX.Value + 55, _startPosY.Value + 10, 13, 10);
+ g.FillRectangle(blueBr, _startPosX.Value + 71, _startPosY.Value + 10, 14, 10);
+
+ g.DrawRectangle(pen, _startPosX.Value + 7, _startPosY.Value + 10, 12, 10);
+ g.DrawRectangle(pen, _startPosX.Value + 21, _startPosY.Value + 10, 12, 10);
+ g.DrawRectangle(pen, _startPosX.Value + 35, _startPosY.Value + 10, 10, 10);
+ g.DrawRectangle(pen, _startPosX.Value + 47, _startPosY.Value + 10, 6, 10);
+ g.DrawRectangle(pen, _startPosX.Value + 55, _startPosY.Value + 10, 13, 10);
+ g.DrawRectangle(pen, _startPosX.Value + 71, _startPosY.Value + 10, 14, 10);
+
+ //верхний отсек
+ PointF[] section = { new PointF((float)_startPosX + 27, (float)_startPosY + 5),
+ new PointF((float)_startPosX + 37, (float)_startPosY + 1),
+ new PointF((float)_startPosX + 65, (float)_startPosY + 1),
+ new PointF((float)_startPosX + 75, (float)_startPosY + 5) };
+ g.FillPolygon(additionalBrush, section);
+ g.DrawPolygon(pen, section);
+
+ //переднее окно 2ой этаж
+ PointF[] window1 = { new PointF((float)_startPosX + 90, (float)_startPosY + 10),
+ new PointF((float)_startPosX + 97, (float)_startPosY + 10),
+ new PointF((float)_startPosX + 102, (float)_startPosY + 20),
+ new PointF((float)_startPosX + 90, (float)_startPosY + 20) };
+ g.FillPolygon(blueBr, window1);
+ g.DrawPolygon(pen, window1);
+
+ //зеркала
+ g.FillRectangle(mainBrush, _startPosX.Value + 95, _startPosY.Value + 5, 20, 5);
+ g.FillRectangle(additionalBrush, _startPosX.Value + 110, _startPosY.Value + 10, 5, 5);
+
+ g.DrawRectangle(pen, _startPosX.Value + 95, _startPosY.Value + 5, 20, 5);
+ g.DrawRectangle(pen, _startPosX.Value + 110, _startPosY.Value + 10, 5, 5);
+
+ //лестница
+ g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 45), new Point(_startPosX.Value + 1, _startPosY.Value + 3));
+ g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 45), new Point(_startPosX.Value + 5, _startPosY.Value + 43));
+ g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 39), new Point(_startPosX.Value + 5, _startPosY.Value + 37));
+ g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 31), new Point(_startPosX.Value + 5, _startPosY.Value + 29));
+ g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 23), new Point(_startPosX.Value + 5, _startPosY.Value + 21));
+ g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 15), new Point(_startPosX.Value + 5, _startPosY.Value + 13));
+ g.DrawLine(pen, new Point(_startPosX.Value + 1, _startPosY.Value + 7), new Point(_startPosX.Value + 5, _startPosY.Value + 5));
+ }
+
+ }
+}
diff --git a/DoubleDeckerBus/DoubleDeckerBus/Entities/EntityBus.cs b/DoubleDeckerBus/DoubleDeckerBus/Entities/EntityBus.cs
new file mode 100644
index 0000000..e1ae78c
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/Entities/EntityBus.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DoubleDeckerBus.Entities;
+///
+/// Класс сущность "Автобус"
+///
+public class EntityBus
+{
+ ///
+ /// Скорость
+ ///
+ public int Speed { get; private set; }
+
+ ///
+ /// Вес
+ ///
+ public double Weight { get; private set; }
+
+ ///
+ /// Основной цвет
+ ///
+ public Color BodyColor { get; private set; }
+
+ ///
+ /// Расстояние перемещения за раз
+ ///
+ public double Step => Speed * 100 / Weight;
+
+ ///
+ /// Конструктор базовой сущности
+ ///
+ /// Скорость
+ /// Вес автобуса
+ /// Основной цвет
+ public EntityBus(int speed, double weight, Color bodyColor)
+ {
+ Speed = speed;
+ Weight = weight;
+ BodyColor = bodyColor;
+ }
+
+}
diff --git a/DoubleDeckerBus/DoubleDeckerBus/Entities/EntityDoubleDeckerBus.cs b/DoubleDeckerBus/DoubleDeckerBus/Entities/EntityDoubleDeckerBus.cs
new file mode 100644
index 0000000..d955e88
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/Entities/EntityDoubleDeckerBus.cs
@@ -0,0 +1,35 @@
+namespace DoubleDeckerBus.Entities;
+public class EntityDoubleDeckerBus : EntityBus
+{
+ ///
+ /// Дополнительный цвет
+ ///
+ public Color AdditionalColor { get; private set; }
+
+ ///
+ /// Признак (опция) наличия второго этажа
+ ///
+ public bool SecondFloor { get; private set; }
+
+ ///
+ /// Признак (опция) наличия полосок на автобусе
+ ///
+ public bool Stripes { get; private set; }
+
+ ///
+ /// Конструктор продвинутой сущности
+ ///
+ /// Скорость
+ /// Вес
+ /// Основной цвет
+ /// Дополнительный цвет
+ /// Признак наличия второго этажа
+ /// Призна наличия полос на кузове
+ public EntityDoubleDeckerBus(int speed, double weight, Color bodyColor, Color additionalColor, bool secondFloor, bool stripes) : base(speed, weight, bodyColor)
+ {
+ AdditionalColor = additionalColor;
+ SecondFloor = secondFloor;
+ Stripes = stripes;
+
+ }
+}
\ No newline at end of file
diff --git a/DoubleDeckerBus/DoubleDeckerBus/EntityDoubleDeckerBus.cs b/DoubleDeckerBus/DoubleDeckerBus/EntityDoubleDeckerBus.cs
deleted file mode 100644
index bdfa702..0000000
--- a/DoubleDeckerBus/DoubleDeckerBus/EntityDoubleDeckerBus.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-namespace DoubleDeckerBus;
- public class EntityDoubleDeckerBus
-{
- 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 SecondFloor { get; private set; }
- ///
- /// Признак (опция) наличия полосок на автобусе
- ///
- public bool Stripes { get; private set; }
- ///
- /// Шаг перемещения автобуса
- ///
- public double Step => Speed * 100 / Weight;
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool secondFloor, bool stripes)
- {
- Speed = speed;
- Weight = weight;
- BodyColor = bodyColor;
- AdditionalColor = additionalColor;
- SecondFloor = secondFloor;
- Stripes = stripes;
- }
-}
\ No newline at end of file
diff --git a/DoubleDeckerBus/DoubleDeckerBus/FormDoubleDeckerBus.Designer.cs b/DoubleDeckerBus/DoubleDeckerBus/FormDoubleDeckerBus.Designer.cs
index 752b2d6..a56dad7 100644
--- a/DoubleDeckerBus/DoubleDeckerBus/FormDoubleDeckerBus.Designer.cs
+++ b/DoubleDeckerBus/DoubleDeckerBus/FormDoubleDeckerBus.Designer.cs
@@ -34,6 +34,9 @@
buttonUp = new Button();
buttonDown = new Button();
buttonRight = new Button();
+ CreateBus = new Button();
+ comboBoxStrategy = new ComboBox();
+ buttonStrategyStep = new Button();
((System.ComponentModel.ISupportInitialize)pictureBoxDoubleDeckerBus).BeginInit();
SuspendLayout();
//
@@ -42,9 +45,9 @@
buttonCreateDoubleDeckerBus.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonCreateDoubleDeckerBus.Location = new Point(12, 415);
buttonCreateDoubleDeckerBus.Name = "buttonCreateDoubleDeckerBus";
- buttonCreateDoubleDeckerBus.Size = new Size(75, 23);
+ buttonCreateDoubleDeckerBus.Size = new Size(159, 23);
buttonCreateDoubleDeckerBus.TabIndex = 1;
- buttonCreateDoubleDeckerBus.Text = "Create";
+ buttonCreateDoubleDeckerBus.Text = "Create DoubleDeckerBus";
buttonCreateDoubleDeckerBus.UseVisualStyleBackColor = true;
buttonCreateDoubleDeckerBus.Click += buttonCreateDoubleDeckerBus_Click;
//
@@ -105,11 +108,47 @@
buttonRight.UseVisualStyleBackColor = true;
buttonRight.Click += buttonMove_Click;
//
+ // CreateBus
+ //
+ CreateBus.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
+ CreateBus.Location = new Point(188, 415);
+ CreateBus.Name = "CreateBus";
+ CreateBus.Size = new Size(159, 23);
+ CreateBus.TabIndex = 7;
+ CreateBus.Text = "Create Bus";
+ CreateBus.UseVisualStyleBackColor = true;
+ CreateBus.Click += buttonCreateBus_Click;
+ //
+ // comboBoxStrategy
+ //
+ comboBoxStrategy.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList;
+ comboBoxStrategy.FormattingEnabled = true;
+ comboBoxStrategy.Items.AddRange(new object[] { "To center", "To border" });
+ comboBoxStrategy.Location = new Point(667, 12);
+ comboBoxStrategy.Name = "comboBoxStrategy";
+ comboBoxStrategy.Size = new Size(121, 23);
+ comboBoxStrategy.TabIndex = 8;
+ //
+ // buttonStrategyStep
+ //
+ buttonStrategyStep.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ buttonStrategyStep.Location = new Point(713, 41);
+ buttonStrategyStep.Name = "buttonStrategyStep";
+ buttonStrategyStep.Size = new Size(75, 23);
+ buttonStrategyStep.TabIndex = 9;
+ buttonStrategyStep.Text = "Do step";
+ buttonStrategyStep.UseVisualStyleBackColor = true;
+ buttonStrategyStep.Click += buttonStrategyStep_Click;
+ //
// FormDoubleDeckerBus
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
+ Controls.Add(buttonStrategyStep);
+ Controls.Add(comboBoxStrategy);
+ Controls.Add(CreateBus);
Controls.Add(buttonRight);
Controls.Add(buttonDown);
Controls.Add(buttonUp);
@@ -130,5 +169,8 @@
private Button buttonUp;
private Button buttonDown;
private Button buttonRight;
+ private Button CreateBus;
+ private ComboBox comboBoxStrategy;
+ private Button buttonStrategyStep;
}
}
\ No newline at end of file
diff --git a/DoubleDeckerBus/DoubleDeckerBus/FormDoubleDeckerBus.cs b/DoubleDeckerBus/DoubleDeckerBus/FormDoubleDeckerBus.cs
index e44a6c5..e3168c9 100644
--- a/DoubleDeckerBus/DoubleDeckerBus/FormDoubleDeckerBus.cs
+++ b/DoubleDeckerBus/DoubleDeckerBus/FormDoubleDeckerBus.cs
@@ -7,50 +7,74 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
+using DoubleDeckerBus.Drawnings;
+using DoubleDeckerBus.MovementStrategy;
namespace DoubleDeckerBus
{
public partial class FormDoubleDeckerBus : Form
{
- private DrawingDoubleDeckerBus? _drawingDoubleDeckerBus;
+ private DrawingBus? _drawingBus;
+
+ private AbstractStrategy? _strategy;
public FormDoubleDeckerBus()
{
InitializeComponent();
+ _strategy = null;
+
}
private void Draw()
{
- if (_drawingDoubleDeckerBus == null)
+ if (_drawingBus == null)
{
return;
}
Bitmap bmp = new(pictureBoxDoubleDeckerBus.Width, pictureBoxDoubleDeckerBus.Height);
Graphics gr = Graphics.FromImage(bmp);
- _drawingDoubleDeckerBus.DrawTrasnport(gr);
+ _drawingBus.DrawTrasnport(gr);
pictureBoxDoubleDeckerBus.Image = bmp;
}
+ private void CreateObject(string type)
+ {
+ Random random = new();
+ switch (type)
+ {
+ case nameof(DrawingBus):
+ _drawingBus = new DrawingBus(random.Next(100, 300), random.Next(1000, 3000),
+ Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)));
+ break;
+ case nameof(DrawingDoubleDeckerBus):
+ _drawingBus = new DrawingDoubleDeckerBus(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)));
+ break;
+ default:
+ return;
+ }
+
+ _drawingBus.SetPictureSize(pictureBoxDoubleDeckerBus.Width, pictureBoxDoubleDeckerBus.Height);
+ _drawingBus.SetPosition(random.Next(10, 100), random.Next(10, 100));
+ _strategy = null;
+ comboBoxStrategy.Enabled = true;
+ Draw();
+ }
+
private void buttonCreateDoubleDeckerBus_Click(object sender, EventArgs e)
{
- Random random = new();
- _drawingDoubleDeckerBus = new DrawingDoubleDeckerBus();
- _drawingDoubleDeckerBus.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)), Convert.ToBoolean(random.Next(0, 2)));
- _drawingDoubleDeckerBus.SetPictureSize(pictureBoxDoubleDeckerBus.Width, pictureBoxDoubleDeckerBus.Height);
- _drawingDoubleDeckerBus.SetPosition(random.Next(10, 100), random.Next(10, 100));
-
- Draw();
-
-
-
+ CreateObject(nameof(DrawingDoubleDeckerBus));
+ }
+ private void buttonCreateBus_Click(object sender, EventArgs e)
+ {
+ CreateObject(nameof(DrawingBus));
}
private void buttonMove_Click(object sender, EventArgs e)
{
- if (_drawingDoubleDeckerBus == null)
+ if (_drawingBus == null)
{
return;
}
@@ -60,19 +84,19 @@ namespace DoubleDeckerBus
switch (name)
{
case "buttonLeft":
- result = _drawingDoubleDeckerBus.MoveTransport(DirectionType.Left);
+ result = _drawingBus.MoveTransport(DirectionType.Left);
break;
case "buttonRight":
- result = _drawingDoubleDeckerBus.MoveTransport(DirectionType.Right);
+ result = _drawingBus.MoveTransport(DirectionType.Right);
break;
case "buttonUp":
- result = _drawingDoubleDeckerBus.MoveTransport(DirectionType.Up);
+ result = _drawingBus.MoveTransport(DirectionType.Up);
break;
case "buttonDown":
- result = _drawingDoubleDeckerBus.MoveTransport(DirectionType.Down);
+ result = _drawingBus.MoveTransport(DirectionType.Down);
break;
}
@@ -81,5 +105,49 @@ namespace DoubleDeckerBus
Draw();
}
}
+
+ private void buttonStrategyStep_Click(object sender, EventArgs e)
+ {
+ if (_drawingBus == null)
+ {
+ return;
+ }
+
+ if (comboBoxStrategy.Enabled)
+ {
+ _strategy = comboBoxStrategy.SelectedIndex switch
+ {
+ 0 => new MoveToCenter(),
+ 1 => new MovetoBorder(),
+ _ => null,
+ };
+ if (_strategy == null)
+ {
+ return;
+ }
+ _strategy.SetData(new MoveableBus(_drawingBus), pictureBoxDoubleDeckerBus.Width, pictureBoxDoubleDeckerBus.Height);
+
+ comboBoxStrategy.Enabled = false;
+ _strategy.MakeStep();
+ Draw();
+
+
+ }
+ else
+ {
+ if (_strategy == null)
+ {
+ return;
+ }
+ _strategy.MakeStep();
+ Draw();
+ }
+
+ if (_strategy.GetStatus() == StrategyStatus.Finish)
+ {
+ comboBoxStrategy.Enabled = true;
+ _strategy = null;
+ }
+ }
}
}
diff --git a/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/AbstractStrategy.cs b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/AbstractStrategy.cs
new file mode 100644
index 0000000..fd85537
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/AbstractStrategy.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DoubleDeckerBus.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 movableObject, int width, int height)
+ {
+ if (movableObject == null)
+ {
+ _state = StrategyStatus.NotInit;
+ return;
+ }
+
+ _state = StrategyStatus.InProgress;
+ _moveableObject = movableObject;
+ FieldWidth = width;
+ FieldHeight = height;
+ }
+
+ ///
+ /// Шаг перемещения
+ ///
+ public void MakeStep()
+ {
+ if (_state != StrategyStatus.InProgress)
+ {
+ return;
+ }
+
+ if(IsTargetDestination())
+ {
+ _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 ObjectParametrs? GetObjectParaments => _moveableObject?.GetObjectPosition;
+
+ ///
+ /// Шаг объекта
+ ///
+ ///
+ protected int? GetStep()
+ {
+ if (_state != StrategyStatus.InProgress)
+ {
+ return null;
+ }
+
+ return _moveableObject?.GetStep;
+ }
+
+ ///
+ /// Перемещение к цели
+ ///
+ protected abstract void MoveToTarget();
+
+ ///
+ /// Достигнута ли цель
+ ///
+ ///
+ protected abstract bool IsTargetDestination();
+
+ ///
+ /// Попытка перемещения в требуемом направлении
+ ///
+ /// Направление
+ /// Результат попытки (true - удалось переместиться, false - неудача)
+ private bool MoveTo(MovementDirection movementDirection)
+ {
+ if (_state != StrategyStatus.InProgress)
+ {
+ return false;
+ }
+
+ return _moveableObject?.TryMoveObject(movementDirection) ?? false;
+ }
+}
\ No newline at end of file
diff --git a/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/IMoveableObject..cs b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/IMoveableObject..cs
new file mode 100644
index 0000000..b27cf22
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/IMoveableObject..cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DoubleDeckerBus.MovementStrategy;
+
+///
+/// Интерфейс для работы с перемещаемым объектом
+///
+public interface IMoveableObject
+{
+ ///
+ /// Получение координаты объекта
+ ///
+ ObjectParametrs? GetObjectPosition { get; }
+
+ ///
+ /// Шаг объекта
+ ///
+ int GetStep { get; }
+
+ ///
+ /// Попытка переместить объект в указанном направлении
+ ///
+ /// Направление
+ /// true - объект перемещен, false - перемещение невозможно
+ bool TryMoveObject(MovementDirection direction);
+}
diff --git a/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MoveToCenter.cs b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MoveToCenter.cs
new file mode 100644
index 0000000..17f1a2d
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MoveToCenter.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DoubleDeckerBus.MovementStrategy;
+
+///
+/// Стратегия перемещения объекта в центр экрана
+///
+public class MoveToCenter : AbstractStrategy
+{
+ protected override bool IsTargetDestination()
+ {
+ ObjectParametrs? objParams = GetObjectParaments;
+ 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()
+ {
+ ObjectParametrs? objParams = GetObjectParaments;
+ 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/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MoveableBus.cs b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MoveableBus.cs
new file mode 100644
index 0000000..3dc16bb
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MoveableBus.cs
@@ -0,0 +1,70 @@
+using DoubleDeckerBus.Drawnings;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DoubleDeckerBus.MovementStrategy;
+
+///
+/// Класс-реализация IMoveableObject с использованием DrawningBus
+///
+public class MoveableBus : IMoveableObject
+{
+ ///
+ /// Поле-объект класса DrawningBus или его наследника
+ ///
+ private DrawingBus? _bus = null;
+
+ ///
+ /// Конструктор
+ ///
+ /// Объект класса DrawningBus
+ public MoveableBus(DrawingBus bus)
+ {
+ _bus = bus;
+ }
+
+ public ObjectParametrs? GetObjectPosition
+ {
+ get
+ {
+ if (_bus == null || _bus.EntityBus == null || !_bus.GetPosX.HasValue || !_bus.GetPosY.HasValue)
+ {
+ return null;
+ }
+ return new ObjectParametrs(_bus.GetPosX.Value, _bus.GetPosY.Value, _bus.GetWidth, _bus.GetHeight);
+ }
+ }
+
+ public int GetStep => (int)(_bus?.EntityBus?.Step ?? 0);
+
+ public bool TryMoveObject(MovementDirection direction)
+ {
+ if (_bus == null || _bus.EntityBus == null)
+ {
+ return false;
+ }
+
+ return _bus.MoveTransport(GetDirectionType(direction));
+ }
+
+ ///
+ /// Конвертация из MovementDirection в DirectionType
+ ///
+ /// MovementDirection
+ /// DirectionType
+ private static DirectionType GetDirectionType(MovementDirection direction)
+ {
+ return direction switch
+ {
+ MovementDirection.Left => DirectionType.Left,
+ MovementDirection.Right => DirectionType.Right,
+ MovementDirection.Up => DirectionType.Up,
+ MovementDirection.Down => DirectionType.Down,
+ _ => DirectionType.Unknown,
+ } ;
+ }
+
+}
\ No newline at end of file
diff --git a/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MovementDirection.cs b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MovementDirection.cs
new file mode 100644
index 0000000..898f4c5
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MovementDirection.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DoubleDeckerBus.MovementStrategy;
+
+///
+/// Направление перемещения
+///
+public enum MovementDirection
+{
+ ///
+ /// вверх
+ ///
+ Up = 1,
+
+ ///
+ /// вниз
+ ///
+ Down = 2,
+
+ ///
+ /// влево
+ ///
+ Left = 3,
+
+ ///
+ /// вправо
+ ///
+ Right = 4
+}
diff --git a/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MovetoBorder.cs b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MovetoBorder.cs
new file mode 100644
index 0000000..e1eb81d
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/MovetoBorder.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DoubleDeckerBus.MovementStrategy;
+///
+/// Стратегия перемещения объекта в правый нижний угол
+///
+internal class MovetoBorder : AbstractStrategy
+{
+ protected override bool IsTargetDestination()
+ {
+ ObjectParametrs? objParams = GetObjectParaments;
+ if (objParams == null)
+ {
+ return false;
+ }
+ return objParams.DownBorder + GetStep() >= FieldHeight && objParams.RightBorder + GetStep() >= FieldWidth;
+ }
+
+ protected override void MoveToTarget()
+ {
+ ObjectParametrs? objParams = GetObjectParaments;
+ if (objParams == null)
+ {
+ return;
+ }
+
+ int diffX = objParams.RightBorder - FieldWidth;
+ if(Math.Abs(diffX) > GetStep())
+ {
+ MoveRight();
+ }
+
+ int diffY = objParams.DownBorder - FieldHeight;
+ if(Math.Abs(diffY) > GetStep())
+ {
+ MoveDown();
+ }
+ }
+}
diff --git a/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/ObjectParametrs.cs b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/ObjectParametrs.cs
new file mode 100644
index 0000000..0eb7c60
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/ObjectParametrs.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DoubleDeckerBus.MovementStrategy;
+
+public class ObjectParametrs
+{
+ ///
+ /// Координата X
+ ///
+ private readonly int _x;
+
+ ///
+ /// Координата Y
+ ///
+ 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 ObjectParametrs(int x, int y, int width, int height)
+ {
+ _x = x;
+ _y = y;
+ _width = width;
+ _height = height;
+ }
+}
diff --git a/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/StrategyStatus.cs b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/StrategyStatus.cs
new file mode 100644
index 0000000..85556b7
--- /dev/null
+++ b/DoubleDeckerBus/DoubleDeckerBus/MovementStrategy/StrategyStatus.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DoubleDeckerBus.MovementStrategy;
+
+///
+/// Статус выполнения операции перемещения
+///
+public enum StrategyStatus
+{
+ ///
+ /// Все готово к началу
+ ///
+ NotInit,
+
+ ///
+ /// Выполняется
+ ///
+ InProgress,
+
+ ///
+ /// Завершено
+ ///
+ Finish
+}