From fcf35359c75f0961d3e833780fe3280375385859 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=D0=98=D0=BB=D1=8C=D1=8F?= <Илья@WIN-RANNDDD>
Date: Tue, 26 Sep 2023 16:06:43 +0400
Subject: [PATCH] =?UTF-8?q?=D0=93=D0=BE=D1=82=D0=BE=D0=B2=D0=B0=D1=8F=202?=
=?UTF-8?q?=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=BD?=
=?UTF-8?q?=D0=B0=D1=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../ProjectMonorail/AbstractStrategy.cs | 141 +++++++++++++
.../DrawingExtendedMonorail.cs | 99 +++++++++
.../ProjectMonorail/DrawingMonorail.cs | 173 ++++++++--------
.../ProjectMonorail/DrawingObjectMonorail.cs | 38 ++++
.../ProjectMonorail/EntityExtendedMonorail.cs | 40 ++++
.../ProjectMonorail/EntityMonorail.cs | 34 +--
.../ProjectMonorail/FormMonorail.Designer.cs | 195 +++++++++++-------
.../ProjectMonorail/FormMonorail.cs | 75 ++++++-
.../ProjectMonorail/IMoveableObject.cs | 31 +++
.../ProjectMonorail/MoveToBorder.cs | 46 +++++
.../ProjectMonorail/MoveToCenter.cs | 54 +++++
.../ProjectMonorail/ObjectParameters.cs | 61 ++++++
ProjectMonorail/ProjectMonorail/Status.cs | 14 ++
13 files changed, 803 insertions(+), 198 deletions(-)
create mode 100644 ProjectMonorail/ProjectMonorail/AbstractStrategy.cs
create mode 100644 ProjectMonorail/ProjectMonorail/DrawingExtendedMonorail.cs
create mode 100644 ProjectMonorail/ProjectMonorail/DrawingObjectMonorail.cs
create mode 100644 ProjectMonorail/ProjectMonorail/EntityExtendedMonorail.cs
create mode 100644 ProjectMonorail/ProjectMonorail/IMoveableObject.cs
create mode 100644 ProjectMonorail/ProjectMonorail/MoveToBorder.cs
create mode 100644 ProjectMonorail/ProjectMonorail/MoveToCenter.cs
create mode 100644 ProjectMonorail/ProjectMonorail/ObjectParameters.cs
create mode 100644 ProjectMonorail/ProjectMonorail/Status.cs
diff --git a/ProjectMonorail/ProjectMonorail/AbstractStrategy.cs b/ProjectMonorail/ProjectMonorail/AbstractStrategy.cs
new file mode 100644
index 0000000..dba68d6
--- /dev/null
+++ b/ProjectMonorail/ProjectMonorail/AbstractStrategy.cs
@@ -0,0 +1,141 @@
+namespace ProjectMonorail.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/ProjectMonorail/ProjectMonorail/DrawingExtendedMonorail.cs b/ProjectMonorail/ProjectMonorail/DrawingExtendedMonorail.cs
new file mode 100644
index 0000000..dbfe664
--- /dev/null
+++ b/ProjectMonorail/ProjectMonorail/DrawingExtendedMonorail.cs
@@ -0,0 +1,99 @@
+using ProjectMonorail.Entities;
+
+namespace ProjectMonorail.DrawingObjects
+{
+ ///
+ /// Класс, отвечающий за прорисовку и перемещение объекта-сущности
+ ///
+ public class DrawingExtendedMonorail : DrawingMonorail
+ {
+ ///
+ /// Конструктор
+ ///
+ /// Скорость
+ /// Вес
+ /// Основной цвет
+ /// Дополнительный цвет
+ /// Признак наличия магнитной рельсы
+ /// Признак наличия дополнительной кабины
+ /// Ширина картинки
+ /// Высота картинки
+ public DrawingExtendedMonorail(int speed, double weight, Color mainColor, Color additionalColor, bool magneticRail,
+ bool extraCabin, int width, int height) : base(speed, weight, mainColor, width, height, 186, 92)
+ {
+ if (!magneticRail && !extraCabin)
+ {
+ _monorailWidth = 117;
+ _monorailHeight = 56;
+ }
+ if (!magneticRail && extraCabin)
+ {
+ _monorailWidth = 183;
+ _monorailHeight = 56;
+ }
+ if (EntityMonorail != null)
+ {
+ EntityMonorail = new EntityExtendedMonorail(speed, weight, mainColor,
+ additionalColor, magneticRail, extraCabin);
+ }
+ }
+
+ public override void DrawTransport(Graphics g)
+ {
+ if (EntityMonorail is not EntityExtendedMonorail extendedMonorail)
+ {
+ return;
+ }
+ Pen mainPen = new Pen(Color.Black, 2);
+ Pen additionalPen = new(Color.Blue);
+ Brush additionalBrush = new SolidBrush(extendedMonorail.AdditionalColor);
+ Brush brBlue = new SolidBrush(Color.Blue);
+ Brush brBlack = new SolidBrush(Color.Black);
+ Brush brWhite = new SolidBrush(Color.White);
+ Brush brGray = new SolidBrush(Color.Gray);
+
+ base.DrawTransport(g);
+
+ //магнитная рельса
+ if (extendedMonorail.MagneticRail)
+ {
+ g.DrawRectangle(mainPen, _startPosX + 2, _startPosY + 58, 184, 18);
+ g.FillRectangle(brGray, _startPosX + 2, _startPosY + 58, 184, 18);
+ for (int i = 0; i < 4; i++)
+ {
+ g.DrawRectangle(mainPen, _startPosX + 35 + 35 * i, _startPosY + 77, 8, 15);
+ g.FillRectangle(brGray, _startPosX + 35 + 35 * i, _startPosY + 77, 8, 15);
+ }
+ }
+
+ //дополнительная кабина
+ if (extendedMonorail.ExtraCabin)
+ {
+ //корпус дополнительной кабины
+ g.FillRectangle(additionalBrush, _startPosX + 118, _startPosY + 15, 65, 31);
+ g.DrawRectangle(mainPen, _startPosX + 118, _startPosY + 15, 65, 31);
+ g.DrawLine(additionalPen, _startPosX + 118, _startPosY + 31, _startPosX + 183, _startPosY + 31);
+
+ //дверь дополнительной кабины
+ g.FillRectangle(brBlue, _startPosX + 146, _startPosY + 21, 7, 20);
+ g.DrawRectangle(mainPen, _startPosX + 146, _startPosY + 21, 7, 20);
+
+ //окна дополнительной кабины
+ g.FillRectangle(brBlue, _startPosX + 130, _startPosY + 18, 6, 9);
+ g.DrawRectangle(mainPen, _startPosX + 130, _startPosY + 18, 6, 9);
+ g.FillRectangle(brBlue, _startPosX + 169, _startPosY + 18, 6, 9);
+ g.DrawRectangle(mainPen, _startPosX + 169, _startPosY + 18, 6, 9);
+
+ //колеса и тележка дополнительной кабины
+ g.FillRectangle(brBlack, _startPosX + 126, _startPosY + 47, 15, 6);
+ g.DrawRectangle(mainPen, _startPosX + 126, _startPosY + 47, 15, 6);
+ g.FillRectangle(brBlack, _startPosX + 159, _startPosY + 47, 15, 6);
+ g.DrawRectangle(mainPen, _startPosX + 159, _startPosY + 47, 15, 6);
+ g.FillEllipse(brWhite, _startPosX + 128, _startPosY + 47, 10, 9);
+ g.DrawEllipse(mainPen, _startPosX + 128, _startPosY + 47, 10, 9);
+ g.FillEllipse(brWhite, _startPosX + 161, _startPosY + 47, 10, 9);
+ g.DrawEllipse(mainPen, _startPosX + 161, _startPosY + 47, 10, 9);
+ }
+ }
+ }
+}
diff --git a/ProjectMonorail/ProjectMonorail/DrawingMonorail.cs b/ProjectMonorail/ProjectMonorail/DrawingMonorail.cs
index 4910ccc..d5a2e5f 100644
--- a/ProjectMonorail/ProjectMonorail/DrawingMonorail.cs
+++ b/ProjectMonorail/ProjectMonorail/DrawingMonorail.cs
@@ -1,4 +1,6 @@
-namespace ProjectMonorail
+using ProjectMonorail.Entities;
+
+namespace ProjectMonorail.DrawingObjects
{
///
/// Класс, отвечающий за прорисовку и перемещение объекта-сущности
@@ -8,7 +10,7 @@
///
/// Класс-сущность
///
- public EntityMonorail? EntityMonorail { get; private set; }
+ public EntityMonorail? EntityMonorail { get; protected set; }
///
/// Ширина окна
@@ -23,55 +25,78 @@
///
/// Левая координата прорисовки монорельса
///
- private int _startPosX;
+ protected int _startPosX;
///
/// Верхняя координата прорисовки монорельса
///
- private int _startPosY;
+ protected int _startPosY;
///
/// Ширина прорисовки монорельса
///
- private int _monorailWidth = 117;
+ protected int _monorailWidth = 117;
///
/// Высота прорисовки монорельса
///
- private int _monorailHeight = 56;
+ protected int _monorailHeight = 56;
///
- /// Инициализация свойств
+ /// Координата X объекта
+ ///
+ public int GetPosX => _startPosX;
+
+ ///
+ /// Координата Y объекта
+ ///
+ public int GetPosY => _startPosY;
+
+ ///
+ /// Ширина объекта
+ ///
+ public int GetWidth => _monorailWidth;
+
+ ///
+ /// Высота объекта
+ ///
+ public int GetHeight => _monorailHeight;
+
+ ///
+ /// Конструктор
///
/// Скорость
/// Вес
/// Основной цвет
- /// Дополнительный цвет
- /// Признак наличия магнитной рельсы
- /// Признак наличия дополнительной кабины
/// Ширина картинки
/// Высота картинки
- /// true - объект создан, false - проверка не пройдена,
- ///нельзя создать объект в этих размерах
- public bool Init(int speed, double weight, Color mainColor, Color
- additionalColor, bool magneticRail, bool extraCabin, int width, int height)
+ public DrawingMonorail(int speed, double weight, Color mainColor, int width, int height)
{
- if (extraCabin)
- {
- _monorailWidth = 183;
- }
- if (magneticRail)
- {
- _monorailWidth = 186;
- _monorailHeight = 92;
- }
- if (width < _monorailWidth || height < _monorailHeight) { return false; }
+ if (width < _monorailWidth || height < _monorailHeight) { return; }
_pictureWidth = width;
_pictureHeight = height;
- EntityMonorail = new EntityMonorail();
- EntityMonorail.Init(speed, weight, mainColor, additionalColor,
- magneticRail, extraCabin);
- return true;
+ EntityMonorail = new EntityMonorail(speed, weight, mainColor);
+ }
+
+ ///
+ /// Конструктор
+ ///
+ /// Скорость
+ /// Вес
+ /// Основной цвет
+ /// Ширина картинки
+ /// Высота картинки
+ /// Ширина прорисовки монорельса
+ /// Высота прорисовки монорельса
+ protected DrawingMonorail(int speed, double weight, Color mainColor, int width,
+ int height, int monorailWidth, int monorailHeight)
+ {
+ if (width < monorailWidth || height < monorailHeight) { return; }
+ _pictureWidth = width;
+ _pictureHeight = height;
+ _monorailWidth = monorailWidth;
+ _monorailHeight = monorailHeight;
+ EntityMonorail = new EntityMonorail(speed, weight, mainColor);
}
///
@@ -88,13 +113,39 @@
_startPosY = y;
}
+ ///
+ /// Проверка, что объект может переместится по указанному направлению
+ ///
+ /// Направление
+ /// true - можно переместится по указанному направлению
+ public bool CanMove(DirectionType direction)
+ {
+ if (EntityMonorail == null)
+ {
+ return false;
+ }
+
+ return direction switch
+ {
+ //влево
+ DirectionType.Left => _startPosX - EntityMonorail.Step > 0,
+ //вверх
+ DirectionType.Up => _startPosY - EntityMonorail.Step > 0,
+ //вправо
+ DirectionType.Right => _startPosX + _monorailWidth + EntityMonorail.Step < _pictureWidth,
+ //вниз
+ DirectionType.Down => _startPosY + _monorailHeight + EntityMonorail.Step < _pictureHeight,
+ _ => false
+ };
+ }
+
///
/// Изменение направления перемещения
///
/// Направление
public void MoveTransport(DirectionType direction)
{
- if (EntityMonorail == null)
+ if (!CanMove(direction) || EntityMonorail == null)
{
return;
}
@@ -102,31 +153,19 @@
{
//влево
case DirectionType.Left:
- if (_startPosX - EntityMonorail.Step > 0)
- {
- _startPosX -= (int)EntityMonorail.Step;
- }
+ _startPosX -= (int)EntityMonorail.Step;
break;
//вверх
case DirectionType.Up:
- if (_startPosY - EntityMonorail.Step > 0)
- {
- _startPosY -= (int)EntityMonorail.Step;
- }
+ _startPosY -= (int)EntityMonorail.Step;
break;
//вправо
case DirectionType.Right:
- if (_startPosX + _monorailWidth + EntityMonorail.Step < _pictureWidth)
- {
- _startPosX += (int)EntityMonorail.Step;
- }
+ _startPosX += (int)EntityMonorail.Step;
break;
//вниз
case DirectionType.Down:
- if (_startPosY + _monorailHeight + EntityMonorail.Step < _pictureHeight)
- {
- _startPosY += (int)EntityMonorail.Step;
- }
+ _startPosY += (int)EntityMonorail.Step;
break;
}
}
@@ -135,7 +174,7 @@
/// Прорисовка объекта
///
///
- public void DrawTransport(Graphics g)
+ public virtual void DrawTransport(Graphics g)
{
if (EntityMonorail == null)
{
@@ -144,7 +183,6 @@
Pen mainPen = new Pen(Color.Black, 2);
Pen additionalPen = new(Color.Blue);
Brush mainBrush = new SolidBrush(EntityMonorail.MainColor);
- Brush additionalBrush = new SolidBrush(EntityMonorail.AdditionalColor);
Brush brBlue = new SolidBrush(Color.Blue);
Brush brBlack = new SolidBrush(Color.Black);
Brush brWhite = new SolidBrush(Color.White);
@@ -190,47 +228,6 @@
//соединение между кабинами
g.DrawRectangle(mainPen, _startPosX + 112, _startPosY + 18, 5, 28);
g.FillRectangle(brBlack, _startPosX + 112, _startPosY + 18, 5, 28);
-
- //магнитная рельса
- if (EntityMonorail.MagneticRail)
- {
- g.DrawRectangle(mainPen, _startPosX + 2, _startPosY + 58, 184, 18);
- g.FillRectangle(brGray, _startPosX + 2, _startPosY + 58, 184, 18);
- for (int i = 0; i < 4; i++)
- {
- g.DrawRectangle(mainPen, _startPosX + 35 + 35 * i, _startPosY + 77, 8, 15);
- g.FillRectangle(brGray, _startPosX + 35 + 35 * i, _startPosY + 77, 8, 15);
- }
- }
-
- //дополнительная кабина
- if (EntityMonorail.ExtraCabin)
- {
- //корпус дополнительной кабины
- g.FillRectangle(mainBrush, _startPosX + 118, _startPosY + 15, 65, 31);
- g.DrawRectangle(mainPen, _startPosX + 118, _startPosY + 15, 65, 31);
- g.DrawLine(additionalPen, _startPosX + 118, _startPosY + 31, _startPosX + 183, _startPosY + 31);
-
- //дверь дополнительной кабины
- g.FillRectangle(additionalBrush, _startPosX + 146, _startPosY + 21, 7, 20);
- g.DrawRectangle(mainPen, _startPosX + 146, _startPosY + 21, 7, 20);
-
- //окна дополнительной кабины
- g.FillRectangle(brBlue, _startPosX + 130, _startPosY + 18, 6, 9);
- g.DrawRectangle(mainPen, _startPosX + 130, _startPosY + 18, 6, 9);
- g.FillRectangle(brBlue, _startPosX + 169, _startPosY + 18, 6, 9);
- g.DrawRectangle(mainPen, _startPosX + 169, _startPosY + 18, 6, 9);
-
- //колеса и тележка дополнительной кабины
- g.FillRectangle(brBlack, _startPosX + 126, _startPosY + 47, 15, 6);
- g.DrawRectangle(mainPen, _startPosX + 126, _startPosY + 47, 15, 6);
- g.FillRectangle(brBlack, _startPosX + 159, _startPosY + 47, 15, 6);
- g.DrawRectangle(mainPen, _startPosX + 159, _startPosY + 47, 15, 6);
- g.FillEllipse(brWhite, _startPosX + 128, _startPosY + 47, 10, 9);
- g.DrawEllipse(mainPen, _startPosX + 128, _startPosY + 47, 10, 9);
- g.FillEllipse(brWhite, _startPosX + 161, _startPosY + 47, 10, 9);
- g.DrawEllipse(mainPen, _startPosX + 161, _startPosY + 47, 10, 9);
- }
}
}
}
diff --git a/ProjectMonorail/ProjectMonorail/DrawingObjectMonorail.cs b/ProjectMonorail/ProjectMonorail/DrawingObjectMonorail.cs
new file mode 100644
index 0000000..5d5d33e
--- /dev/null
+++ b/ProjectMonorail/ProjectMonorail/DrawingObjectMonorail.cs
@@ -0,0 +1,38 @@
+using ProjectMonorail.DrawingObjects;
+
+namespace ProjectMonorail.MovementStrategy
+{
+ ///
+ /// Реализация интерфейса IMoveableObject для работы с объектом DrawingMonorail (паттерн Adapter)
+ ///
+ public class DrawingObjectMonorail : IMoveableObject
+ {
+ private readonly DrawingMonorail? _drawingMonorail = null;
+
+ public DrawingObjectMonorail(DrawingMonorail drawingMonorail)
+ {
+ _drawingMonorail = drawingMonorail;
+ }
+
+ public ObjectParameters? GetObjectPosition
+ {
+ get
+ {
+ if (_drawingMonorail == null || _drawingMonorail.EntityMonorail == null)
+ {
+ return null;
+ }
+ return new ObjectParameters(_drawingMonorail.GetPosX, _drawingMonorail.GetPosY,
+ _drawingMonorail.GetWidth, _drawingMonorail.GetHeight);
+ }
+ }
+
+ public int GetStep => (int)(_drawingMonorail?.EntityMonorail?.Step ?? 0);
+
+ public bool CheckCanMove(DirectionType direction) =>
+ _drawingMonorail?.CanMove(direction) ?? false;
+
+ public void MoveObject(DirectionType direction) =>
+ _drawingMonorail?.MoveTransport(direction);
+ }
+}
diff --git a/ProjectMonorail/ProjectMonorail/EntityExtendedMonorail.cs b/ProjectMonorail/ProjectMonorail/EntityExtendedMonorail.cs
new file mode 100644
index 0000000..b0540ea
--- /dev/null
+++ b/ProjectMonorail/ProjectMonorail/EntityExtendedMonorail.cs
@@ -0,0 +1,40 @@
+namespace ProjectMonorail.Entities
+{
+ ///
+ /// Класс-сущность "Расширенный монорельс"
+ ///
+ public class EntityExtendedMonorail : EntityMonorail
+ {
+ ///
+ /// Дополнительный цвет (для опциональных элементов)
+ ///
+ public Color AdditionalColor { get; private set; }
+
+ ///
+ /// Признак (опция) наличия магнитной рельсы
+ ///
+ public bool MagneticRail { get; private set; }
+
+ ///
+ /// Признак (опция) наличия дополнительной кабины
+ ///
+ public bool ExtraCabin { get; private set; }
+
+ ///
+ /// Инициализация полей объекта-класса расширенного монорельса
+ ///
+ /// Скорость
+ /// Вес монорельса
+ /// Основной цвет
+ /// Дополнительный цвет
+ /// Признак наличия магнитной рельсы
+ /// Признак наличия дополнительной кабины
+ public EntityExtendedMonorail(int speed, double weight, Color mainColor, Color
+ additionalColor, bool magneticRail, bool extraCabin) : base(speed, weight, mainColor)
+ {
+ AdditionalColor = additionalColor;
+ MagneticRail = magneticRail;
+ ExtraCabin = extraCabin;
+ }
+ }
+}
diff --git a/ProjectMonorail/ProjectMonorail/EntityMonorail.cs b/ProjectMonorail/ProjectMonorail/EntityMonorail.cs
index 4b99444..fdf2f69 100644
--- a/ProjectMonorail/ProjectMonorail/EntityMonorail.cs
+++ b/ProjectMonorail/ProjectMonorail/EntityMonorail.cs
@@ -1,5 +1,8 @@
-namespace ProjectMonorail
+namespace ProjectMonorail.Entities
{
+ ///
+ /// Класс-сущность "Монорельс"
+ ///
public class EntityMonorail
{
///
@@ -17,44 +20,23 @@
///
public Color MainColor { get; private set; }
- ///
- /// Дополнительный цвет (для опциональных элементов)
- ///
- public Color AdditionalColor { get; private set; }
-
- ///
- /// Признак (опция) наличия магнитной рельсы
- ///
- public bool MagneticRail { get; private set; }
-
- ///
- /// Признак (опция) наличия дополнительной кабины
- ///
- public bool ExtraCabin { get; private set; }
-
///
/// Шаг перемещения монорельса
///
public double Step => (double)Speed * 100 / Weight;
///
- /// Инициализация полей объекта-класса монорельса
+ /// Конструктор с параметрами
///
/// Скорость
/// Вес монорельса
- /// Основной цвет
- /// Дополнительный цвет
- /// Признак наличия магнитной рельсы
- /// Признак наличия дополнительной кабины
- public void Init(int speed, double weight, Color mainColor, Color
- additionalColor, bool magneticRail, bool extraCabin)
+ /// Основной цвет
+ public EntityMonorail(int speed, double weight, Color mainColor)
{
Speed = speed;
Weight = weight;
MainColor = mainColor;
- AdditionalColor = additionalColor;
- MagneticRail = magneticRail;
- ExtraCabin = extraCabin;
}
}
}
+
diff --git a/ProjectMonorail/ProjectMonorail/FormMonorail.Designer.cs b/ProjectMonorail/ProjectMonorail/FormMonorail.Designer.cs
index 382f7fa..081b234 100644
--- a/ProjectMonorail/ProjectMonorail/FormMonorail.Designer.cs
+++ b/ProjectMonorail/ProjectMonorail/FormMonorail.Designer.cs
@@ -28,111 +28,152 @@
///
private void InitializeComponent()
{
- this.pictureBoxMonorail = new System.Windows.Forms.PictureBox();
- this.buttonCreateMonorail = new System.Windows.Forms.Button();
- this.buttonLeft = new System.Windows.Forms.Button();
- this.buttonDown = new System.Windows.Forms.Button();
- this.buttonRight = new System.Windows.Forms.Button();
- this.buttonUp = new System.Windows.Forms.Button();
- ((System.ComponentModel.ISupportInitialize)(this.pictureBoxMonorail)).BeginInit();
- this.SuspendLayout();
+ pictureBoxMonorail = new PictureBox();
+ buttonCreateExtendedMonorail = new Button();
+ buttonLeft = new Button();
+ buttonDown = new Button();
+ buttonRight = new Button();
+ buttonUp = new Button();
+ comboBoxStrategy = new ComboBox();
+ buttonCreateMonorail = new Button();
+ buttonStep = new Button();
+ ((System.ComponentModel.ISupportInitialize)pictureBoxMonorail).BeginInit();
+ SuspendLayout();
//
// pictureBoxMonorail
//
- this.pictureBoxMonorail.Dock = System.Windows.Forms.DockStyle.Fill;
- this.pictureBoxMonorail.Location = new System.Drawing.Point(0, 0);
- this.pictureBoxMonorail.Name = "pictureBoxMonorail";
- this.pictureBoxMonorail.Size = new System.Drawing.Size(884, 461);
- this.pictureBoxMonorail.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
- this.pictureBoxMonorail.TabIndex = 0;
- this.pictureBoxMonorail.TabStop = false;
+ pictureBoxMonorail.Dock = DockStyle.Fill;
+ pictureBoxMonorail.Location = new Point(0, 0);
+ pictureBoxMonorail.Name = "pictureBoxMonorail";
+ pictureBoxMonorail.Size = new Size(884, 461);
+ pictureBoxMonorail.SizeMode = PictureBoxSizeMode.AutoSize;
+ pictureBoxMonorail.TabIndex = 0;
+ pictureBoxMonorail.TabStop = false;
//
- // buttonCreateMonorail
+ // buttonCreateExtendedMonorail
//
- this.buttonCreateMonorail.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
- this.buttonCreateMonorail.Location = new System.Drawing.Point(12, 419);
- this.buttonCreateMonorail.Name = "buttonCreateMonorail";
- this.buttonCreateMonorail.Size = new System.Drawing.Size(75, 23);
- this.buttonCreateMonorail.TabIndex = 1;
- this.buttonCreateMonorail.Text = "Create";
- this.buttonCreateMonorail.UseVisualStyleBackColor = true;
- this.buttonCreateMonorail.Click += new System.EventHandler(this.buttonCreateMonorail_Click);
+ buttonCreateExtendedMonorail.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
+ buttonCreateExtendedMonorail.Location = new Point(12, 403);
+ buttonCreateExtendedMonorail.Name = "buttonCreateExtendedMonorail";
+ buttonCreateExtendedMonorail.Size = new Size(140, 39);
+ buttonCreateExtendedMonorail.TabIndex = 1;
+ buttonCreateExtendedMonorail.Text = "Create extended monorail";
+ buttonCreateExtendedMonorail.UseVisualStyleBackColor = true;
+ buttonCreateExtendedMonorail.Click += buttonCreateExtendedMonorail_Click;
//
// buttonLeft
//
- this.buttonLeft.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.buttonLeft.BackgroundImage = global::ProjectMonorail.Properties.Resources.arrowLeft;
- this.buttonLeft.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
- this.buttonLeft.Location = new System.Drawing.Point(770, 419);
- this.buttonLeft.Name = "buttonLeft";
- this.buttonLeft.Size = new System.Drawing.Size(30, 30);
- this.buttonLeft.TabIndex = 2;
- this.buttonLeft.UseVisualStyleBackColor = true;
- this.buttonLeft.Click += new System.EventHandler(this.buttonMove_Click);
+ buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+ buttonLeft.BackgroundImage = Properties.Resources.arrowLeft;
+ buttonLeft.BackgroundImageLayout = ImageLayout.Zoom;
+ buttonLeft.Location = new Point(770, 419);
+ buttonLeft.Name = "buttonLeft";
+ buttonLeft.Size = new Size(30, 30);
+ buttonLeft.TabIndex = 2;
+ buttonLeft.UseVisualStyleBackColor = true;
+ buttonLeft.Click += buttonMove_Click;
//
// buttonDown
//
- this.buttonDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.buttonDown.BackgroundImage = global::ProjectMonorail.Properties.Resources.arrowDown;
- this.buttonDown.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
- this.buttonDown.Location = new System.Drawing.Point(806, 419);
- this.buttonDown.Name = "buttonDown";
- this.buttonDown.Size = new System.Drawing.Size(30, 30);
- this.buttonDown.TabIndex = 3;
- this.buttonDown.UseVisualStyleBackColor = true;
- this.buttonDown.Click += new System.EventHandler(this.buttonMove_Click);
+ buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+ buttonDown.BackgroundImage = Properties.Resources.arrowDown;
+ buttonDown.BackgroundImageLayout = ImageLayout.Zoom;
+ buttonDown.Location = new Point(806, 419);
+ buttonDown.Name = "buttonDown";
+ buttonDown.Size = new Size(30, 30);
+ buttonDown.TabIndex = 3;
+ buttonDown.UseVisualStyleBackColor = true;
+ buttonDown.Click += buttonMove_Click;
//
// buttonRight
//
- this.buttonRight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.buttonRight.BackgroundImage = global::ProjectMonorail.Properties.Resources.arrowRight;
- this.buttonRight.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
- this.buttonRight.Location = new System.Drawing.Point(842, 419);
- this.buttonRight.Name = "buttonRight";
- this.buttonRight.Size = new System.Drawing.Size(30, 30);
- this.buttonRight.TabIndex = 4;
- this.buttonRight.UseVisualStyleBackColor = true;
- this.buttonRight.Click += new System.EventHandler(this.buttonMove_Click);
+ buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+ buttonRight.BackgroundImage = Properties.Resources.arrowRight;
+ buttonRight.BackgroundImageLayout = ImageLayout.Zoom;
+ buttonRight.Location = new Point(842, 419);
+ buttonRight.Name = "buttonRight";
+ buttonRight.Size = new Size(30, 30);
+ buttonRight.TabIndex = 4;
+ buttonRight.UseVisualStyleBackColor = true;
+ buttonRight.Click += buttonMove_Click;
//
// buttonUp
//
- this.buttonUp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
- this.buttonUp.BackgroundImage = global::ProjectMonorail.Properties.Resources.arrowUp;
- this.buttonUp.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
- this.buttonUp.Location = new System.Drawing.Point(806, 383);
- this.buttonUp.Name = "buttonUp";
- this.buttonUp.Size = new System.Drawing.Size(30, 30);
- this.buttonUp.TabIndex = 5;
- this.buttonUp.UseVisualStyleBackColor = true;
- this.buttonUp.Click += new System.EventHandler(this.buttonMove_Click);
+ buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
+ buttonUp.BackgroundImage = Properties.Resources.arrowUp;
+ buttonUp.BackgroundImageLayout = ImageLayout.Zoom;
+ buttonUp.Location = new Point(806, 383);
+ buttonUp.Name = "buttonUp";
+ buttonUp.Size = new Size(30, 30);
+ buttonUp.TabIndex = 5;
+ buttonUp.UseVisualStyleBackColor = true;
+ buttonUp.Click += buttonMove_Click;
+ //
+ // comboBoxStrategy
+ //
+ comboBoxStrategy.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList;
+ comboBoxStrategy.FormattingEnabled = true;
+ comboBoxStrategy.Items.AddRange(new object[] { "Form center", "Form border" });
+ comboBoxStrategy.Location = new Point(751, 12);
+ comboBoxStrategy.Name = "comboBoxStrategy";
+ comboBoxStrategy.Size = new Size(121, 23);
+ comboBoxStrategy.TabIndex = 6;
+ //
+ // buttonCreateMonorail
+ //
+ buttonCreateMonorail.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
+ buttonCreateMonorail.Location = new Point(168, 403);
+ buttonCreateMonorail.Name = "buttonCreateMonorail";
+ buttonCreateMonorail.Size = new Size(140, 39);
+ buttonCreateMonorail.TabIndex = 7;
+ buttonCreateMonorail.Text = "Create monorail";
+ buttonCreateMonorail.UseVisualStyleBackColor = true;
+ buttonCreateMonorail.Click += buttonCreateMonorail_Click;
+ //
+ // buttonStep
+ //
+ buttonStep.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ buttonStep.Location = new Point(797, 50);
+ buttonStep.Name = "buttonStep";
+ buttonStep.Size = new Size(75, 28);
+ buttonStep.TabIndex = 8;
+ buttonStep.Text = "Step";
+ buttonStep.UseVisualStyleBackColor = true;
+ buttonStep.Click += buttonStep_Click;
//
// FormMonorail
//
- this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(884, 461);
- this.Controls.Add(this.buttonUp);
- this.Controls.Add(this.buttonRight);
- this.Controls.Add(this.buttonDown);
- this.Controls.Add(this.buttonLeft);
- this.Controls.Add(this.buttonCreateMonorail);
- this.Controls.Add(this.pictureBoxMonorail);
- this.Name = "FormMonorail";
- this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
- this.Text = "Monorail";
- ((System.ComponentModel.ISupportInitialize)(this.pictureBoxMonorail)).EndInit();
- this.ResumeLayout(false);
- this.PerformLayout();
-
+ AutoScaleDimensions = new SizeF(7F, 15F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(884, 461);
+ Controls.Add(buttonStep);
+ Controls.Add(buttonCreateMonorail);
+ Controls.Add(comboBoxStrategy);
+ Controls.Add(buttonUp);
+ Controls.Add(buttonRight);
+ Controls.Add(buttonDown);
+ Controls.Add(buttonLeft);
+ Controls.Add(buttonCreateExtendedMonorail);
+ Controls.Add(pictureBoxMonorail);
+ Name = "FormMonorail";
+ StartPosition = FormStartPosition.CenterScreen;
+ Text = "Monorail";
+ ((System.ComponentModel.ISupportInitialize)pictureBoxMonorail).EndInit();
+ ResumeLayout(false);
+ PerformLayout();
}
#endregion
private PictureBox pictureBoxMonorail;
- private Button buttonCreateMonorail;
+ private Button buttonCreateExtendedMonorail;
private Button buttonLeft;
private Button buttonDown;
private Button buttonRight;
private Button buttonUp;
+ private ComboBox comboBoxStrategy;
+ private Button buttonCreateMonorail;
+ private Button buttonStep;
}
}
\ No newline at end of file
diff --git a/ProjectMonorail/ProjectMonorail/FormMonorail.cs b/ProjectMonorail/ProjectMonorail/FormMonorail.cs
index a723ad3..2e84ddb 100644
--- a/ProjectMonorail/ProjectMonorail/FormMonorail.cs
+++ b/ProjectMonorail/ProjectMonorail/FormMonorail.cs
@@ -1,4 +1,7 @@
-namespace ProjectMonorail
+using ProjectMonorail.DrawingObjects;
+using ProjectMonorail.MovementStrategy;
+
+namespace ProjectMonorail
{
///
/// Форма работы с объектом "Монорельс"
@@ -10,6 +13,11 @@
///
private DrawingMonorail? _drawingMonorail;
+ ///
+ /// Стратегия перемещения
+ ///
+ private AbstractStrategy? _abstractStrategy;
+
///
/// Инициализация формы
///
@@ -34,23 +42,36 @@
}
///
- /// Обработка нажатия кнопки "Создать"
+ /// Обработка нажатия кнопки "Создать расширенный монорельс"
+ ///
+ ///
+ ///
+ private void buttonCreateExtendedMonorail_Click(object sender, EventArgs e)
+ {
+ Random random = new();
+ _drawingMonorail = new DrawingExtendedMonorail(random.Next(200, 400), 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)), pictureBoxMonorail.Width, pictureBoxMonorail.Height);
+ _drawingMonorail.SetPosition(random.Next(10, 100), random.Next(10, 100));
+ Draw();
+ }
+
+ ///
+ /// Обработка нажатия кнопки "Создать монорельс"
///
///
///
private void buttonCreateMonorail_Click(object sender, EventArgs e)
{
Random random = new();
- _drawingMonorail = new DrawingMonorail();
- _drawingMonorail.Init(random.Next(300, 500), 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)),
- pictureBoxMonorail.Width, pictureBoxMonorail.Height);
+ _drawingMonorail = new DrawingMonorail(random.Next(200, 400), random.Next(1000, 3000), Color.FromArgb(random.Next(0, 256), random.Next(0, 256),
+ random.Next(0, 256)), pictureBoxMonorail.Width, pictureBoxMonorail.Height);
_drawingMonorail.SetPosition(random.Next(10, 100), random.Next(10, 100));
Draw();
}
///
- /// Обработка нажатия кнопок управления движением
+ /// Изменение положения монорельса
///
///
///
@@ -78,5 +99,45 @@
}
Draw();
}
+
+ ///
+ /// Обработка нажатия кнопки "Шаг"
+ ///
+ ///
+ ///
+ private void buttonStep_Click(object sender, EventArgs e)
+ {
+ if (_drawingMonorail == null)
+ {
+ return;
+ }
+ if (comboBoxStrategy.Enabled)
+ {
+ _abstractStrategy = comboBoxStrategy.SelectedIndex
+ switch
+ {
+ 0 => new MoveToCenter(),
+ 1 => new MoveToBorder(),
+ _ => null,
+ };
+ if (_abstractStrategy == null)
+ {
+ return;
+ }
+ _abstractStrategy.SetData(new DrawingObjectMonorail(_drawingMonorail), pictureBoxMonorail.Width, pictureBoxMonorail.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/ProjectMonorail/ProjectMonorail/IMoveableObject.cs b/ProjectMonorail/ProjectMonorail/IMoveableObject.cs
new file mode 100644
index 0000000..3470471
--- /dev/null
+++ b/ProjectMonorail/ProjectMonorail/IMoveableObject.cs
@@ -0,0 +1,31 @@
+namespace ProjectMonorail.MovementStrategy
+{
+ ///
+ /// Интерфейс для работы с перемещаемым объектом
+ ///
+ public interface IMoveableObject
+ {
+ ///
+ /// Получение координаты X объекта
+ ///
+ ObjectParameters? GetObjectPosition { get; }
+
+ ///
+ /// Шаг объекта
+ ///
+ int GetStep { get; }
+
+ ///
+ /// Проверка, можно ли переместиться по нужному направлению
+ ///
+ ///
+ ///
+ bool CheckCanMove(DirectionType direction);
+
+ ///
+ /// Изменение направления перемещения объекта
+ ///
+ /// Направление
+ void MoveObject(DirectionType direction);
+ }
+}
diff --git a/ProjectMonorail/ProjectMonorail/MoveToBorder.cs b/ProjectMonorail/ProjectMonorail/MoveToBorder.cs
new file mode 100644
index 0000000..b1f9997
--- /dev/null
+++ b/ProjectMonorail/ProjectMonorail/MoveToBorder.cs
@@ -0,0 +1,46 @@
+namespace ProjectMonorail.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.ObjectMiddleHorizontal - FieldWidth;
+ if (Math.Abs(diffX) > GetStep())
+ {
+ if (diffX < 0)
+ {
+ MoveRight();
+ }
+ }
+ var diffY = objParams.ObjectMiddleVertical - FieldHeight;
+ if (Math.Abs(diffY) > GetStep())
+ {
+ if (diffY < 0)
+ {
+ MoveDown();
+ }
+ }
+ }
+ }
+}
diff --git a/ProjectMonorail/ProjectMonorail/MoveToCenter.cs b/ProjectMonorail/ProjectMonorail/MoveToCenter.cs
new file mode 100644
index 0000000..453a839
--- /dev/null
+++ b/ProjectMonorail/ProjectMonorail/MoveToCenter.cs
@@ -0,0 +1,54 @@
+namespace ProjectMonorail.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/ProjectMonorail/ProjectMonorail/ObjectParameters.cs b/ProjectMonorail/ProjectMonorail/ObjectParameters.cs
new file mode 100644
index 0000000..bc9b7d2
--- /dev/null
+++ b/ProjectMonorail/ProjectMonorail/ObjectParameters.cs
@@ -0,0 +1,61 @@
+namespace ProjectMonorail.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/ProjectMonorail/ProjectMonorail/Status.cs b/ProjectMonorail/ProjectMonorail/Status.cs
new file mode 100644
index 0000000..e478c58
--- /dev/null
+++ b/ProjectMonorail/ProjectMonorail/Status.cs
@@ -0,0 +1,14 @@
+namespace ProjectMonorail.MovementStrategy
+{
+ ///
+ /// Статус выполнения операции перемещения
+ ///
+ public enum Status
+ {
+ NotInit,
+
+ InProgress,
+
+ Finish
+ }
+}