From 77ea779c6b44dd1079af0daa94e56bbe77bd4b01 Mon Sep 17 00:00:00 2001 From: ujijrujijr Date: Sat, 21 Oct 2023 21:27:46 +0300 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=BB=D0=B8=D0=BB=20=D0=BB=D0=B0?= =?UTF-8?q?=D0=B12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Trolleybus/Trolleybus/AbstractStrategy.cs | 132 +++++++++++ Trolleybus/Trolleybus/DrawingBus.cs | 215 ++++++++++++++++++ Trolleybus/Trolleybus/DrawingObjectBus.cs | 32 +++ Trolleybus/Trolleybus/DrawingTrolleybus.cs | 149 ++---------- Trolleybus/Trolleybus/EntityBus.cs | 43 ++++ Trolleybus/Trolleybus/EntityTrolleybus.cs | 28 +-- .../Trolleybus/FormTrolleybus.Designer.cs | 66 +++++- Trolleybus/Trolleybus/FormTrolleybus.cs | 89 ++++++-- Trolleybus/Trolleybus/IMoveableObject.cs | 35 +++ Trolleybus/Trolleybus/MoveToBorder.cs | 57 +++++ Trolleybus/Trolleybus/MoveToCenter.cs | 60 +++++ Trolleybus/Trolleybus/ObjectParameters.cs | 58 +++++ Trolleybus/Trolleybus/Status.cs | 15 ++ 13 files changed, 798 insertions(+), 181 deletions(-) create mode 100644 Trolleybus/Trolleybus/AbstractStrategy.cs create mode 100644 Trolleybus/Trolleybus/DrawingBus.cs create mode 100644 Trolleybus/Trolleybus/DrawingObjectBus.cs create mode 100644 Trolleybus/Trolleybus/EntityBus.cs create mode 100644 Trolleybus/Trolleybus/IMoveableObject.cs create mode 100644 Trolleybus/Trolleybus/MoveToBorder.cs create mode 100644 Trolleybus/Trolleybus/MoveToCenter.cs create mode 100644 Trolleybus/Trolleybus/ObjectParameters.cs create mode 100644 Trolleybus/Trolleybus/Status.cs diff --git a/Trolleybus/Trolleybus/AbstractStrategy.cs b/Trolleybus/Trolleybus/AbstractStrategy.cs new file mode 100644 index 0000000..0664a05 --- /dev/null +++ b/Trolleybus/Trolleybus/AbstractStrategy.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Trolleybus.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/Trolleybus/Trolleybus/DrawingBus.cs b/Trolleybus/Trolleybus/DrawingBus.cs new file mode 100644 index 0000000..a89bc36 --- /dev/null +++ b/Trolleybus/Trolleybus/DrawingBus.cs @@ -0,0 +1,215 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Trolleybus.Entities; + +namespace Trolleybus.DrawingObjects +{ + /// + /// Класс, отвечающий за прорисовку и перемещение объекта-сущности + /// + public class DrawingBus + { + /// + /// Класс-сущность + /// + public EntityBus? EntityBus { get; protected set; } + /// + /// Ширина окна + /// + private int _pictureWidth; + /// + /// Высота окна + /// + private int _pictureHeight; + /// + /// Левая координата прорисовки автобуса + /// + protected int _startPosX; + /// + /// Верхняя кооридната прорисовки автобуса + /// + protected int _startPosY; + /// + /// Ширина прорисовки автобуса + /// + protected readonly int _busWidth = 150; + /// + /// Высота прорисовки автобуса + /// + protected readonly int _busHeight = 95; + /// + /// Координата X объекта + /// + public int GetPosX => _startPosX; + /// + /// Координата Y объекта + /// + public int GetPosY => _startPosY; + /// + /// Ширина объекта + /// + public int GetWidth => _busWidth; + /// + /// Высота объекта + /// + public int GetHeight => _busHeight; + + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Ширина картинки + /// Высота картинки + public DrawingBus(int speed, double weight, Color bodyColor, int width, int height) + { + if (width < _busWidth || height < _busHeight) + { + return; + } + _pictureWidth = width; + _pictureHeight = height; + EntityBus = new EntityBus(speed, weight, bodyColor); + } + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Ширина картинки + /// Высота картинки + /// Ширина прорисовки автобуса + /// Высота прорисовки автобус + protected DrawingBus(int speed, double weight, Color bodyColor, int width, int height, int busWidth, int busHeight) + { + if (width < _busWidth || height < _busHeight) + { + return; + } + _pictureWidth = width; + _pictureHeight = height; + _busWidth = busWidth; + _busHeight = busHeight; + EntityBus = new EntityBus(speed, weight, bodyColor); + } + /// + /// Установка позиции + /// + /// Координата X + /// Координата Y + public void SetPosition(int x, int y) + { + _startPosX = Math.Min(Math.Max(x, 0), _pictureWidth - _busWidth); + _startPosY = Math.Min(Math.Max(y, 0), _pictureHeight - _busHeight); + } + /// + /// Изменение направления перемещения + /// + /// Направление + public void MoveTransport(DirectionType direction) + { + if (!CanMove(direction) || EntityBus == null) + { + return; + } + switch (direction) + { + //влево + case DirectionType.Left: + if (_startPosX - EntityBus.Step > 0) + { + _startPosX -= (int)EntityBus.Step; + } + break; + //вверх + case DirectionType.Up: + if (_startPosY - EntityBus.Step > 0) + { + _startPosY -= (int)EntityBus.Step; + } + break; + // вправо + case DirectionType.Right: + if (_startPosX + _busWidth + EntityBus.Step < _pictureWidth) + { + _startPosX += (int)EntityBus.Step; + } + break; + //вниз + case DirectionType.Down: + if (_startPosY + _busHeight + EntityBus.Step < _pictureHeight) + { + _startPosY += (int)EntityBus.Step; + } + break; + } + } + /// + /// Прорисовка объекта + /// + /// + public virtual void DrawTransport(Graphics g) + { + Pen pen = new(Color.Black); //чёрный цвет для колёс + Pen bodyPen = new(EntityBus.BodyColor); + Pen windowPen = new(Color.Cyan); //цвет окон + //РИСОВАНИЕ САМОГО АВТОБУСА + //корпус + g.DrawLine(bodyPen, _startPosX, _startPosY + 30, _startPosX, _startPosY + 80); + g.DrawLine(bodyPen, _startPosX, _startPosY + 80, _startPosX + 20, _startPosY + 80); + g.DrawLine(bodyPen, _startPosX + 45, _startPosY + 80, _startPosX + 105, _startPosY + 80); + g.DrawLine(bodyPen, _startPosX + 130, _startPosY + 80, _startPosX + 150, _startPosY + 80); + g.DrawLine(bodyPen, _startPosX + 150, _startPosY + 80, _startPosX + 150, _startPosY + 30); + g.DrawLine(bodyPen, _startPosX + 150, _startPosY + 30, _startPosX, _startPosY + 30); + + //колёса + g.DrawEllipse(pen, _startPosX + 20, _startPosY + 70, 25, 25); + g.DrawEllipse(pen, _startPosX + 105, _startPosY + 70, 25, 25); + + //дверь + g.DrawRectangle(bodyPen, _startPosX + 55, _startPosY + 50, 15, 30); + + //окна + //окна до двери + for (int i = 0; i < 2; i++) + { + g.DrawEllipse(windowPen, _startPosX + 5 + 25 * i, _startPosY + 35, 16, 24); + } + //окна после двери + for (int i = 0; i < 3; i++) + { + g.DrawEllipse(windowPen, _startPosX + 75 + 25 * i, _startPosY + 35, 16, 24); + } + } + + /// + /// Проверка, что объект может переместится по указанному направлению + /// + /// Направление + /// true - можно переместится по указанному направлению + public bool CanMove(DirectionType direction) + { + if (EntityBus == null) + { + return false; + } + return direction switch + { + //влево + DirectionType.Left => _startPosX - EntityBus.Step > 0, + //вверх + DirectionType.Up => _startPosY - EntityBus.Step > 0, + // вправо + DirectionType.Right => _startPosX + _busWidth + EntityBus.Step < _pictureWidth, + //вниз + DirectionType.Down => _startPosY + _busHeight + EntityBus.Step < _pictureHeight, + _ => false, + }; + } + } +} diff --git a/Trolleybus/Trolleybus/DrawingObjectBus.cs b/Trolleybus/Trolleybus/DrawingObjectBus.cs new file mode 100644 index 0000000..d990e98 --- /dev/null +++ b/Trolleybus/Trolleybus/DrawingObjectBus.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Trolleybus.DrawingObjects; + +namespace Trolleybus.MovementStrategy +{ + public class DrawingObjectBus : IMoveableObject + { + private readonly DrawingBus? _drawingBus = null; + public DrawingObjectBus(DrawingBus drawingBus) + { + _drawingBus = drawingBus; + } + public ObjectParameters? GetObjectPosition + { + get + { + if (_drawingBus == null || _drawingBus.EntityBus == null) + { + return null; + } + return new ObjectParameters(_drawingBus.GetPosX, _drawingBus.GetPosY, _drawingBus.GetWidth, _drawingBus.GetHeight); + } + } + public int GetStep => (int)(_drawingBus?.EntityBus?.Step ?? 0); + public bool CheckCanMove(DirectionType direction) => _drawingBus?.CanMove(direction) ?? false; + public void MoveObject(DirectionType direction) => _drawingBus?.MoveTransport(direction); + } +} diff --git a/Trolleybus/Trolleybus/DrawingTrolleybus.cs b/Trolleybus/Trolleybus/DrawingTrolleybus.cs index d8532d6..0e38bcb 100644 --- a/Trolleybus/Trolleybus/DrawingTrolleybus.cs +++ b/Trolleybus/Trolleybus/DrawingTrolleybus.cs @@ -4,41 +4,14 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; +using Trolleybus.Entities; -namespace Trolleybus +namespace Trolleybus.DrawingObjects { - public class DrawingTrolleybus + public class DrawingTrolleybus : DrawingBus { /// - /// Класс-сущность - /// - public EntityTrolleybus? EntityTrolleybus { get; private set; } - /// - /// Ширина окна - /// - private int _pictureWidth; - /// - /// Высота окна - /// - private int _pictureHeight; - /// - /// Левая координата прорисовки троллейбуса - /// - private int _startPosX; - /// - /// Верхняя кооридната прорисовки троллейбуса - /// - private int _startPosY; - /// - /// Ширина прорисовки троллейбуса - /// - private readonly int _trolleybusWidth = 150; - /// - /// Высота прорисовки троллейбуса - /// - private readonly int _trolleybusHeight = 95; - /// - /// Инициализация свойств + /// Конструктор /// /// Скорость /// Вес @@ -49,122 +22,32 @@ namespace Trolleybus /// Ширина картинки /// Высота картинки /// true - объект создан, false - проверка не пройдена, нельзя создать объект в этих размерах - public bool Init(int speed, double weight, Color bodyColor, Color additionalColor, bool horns, bool batteries, int width, int height) + public DrawingTrolleybus(int speed, double weight, Color bodyColor, Color additionalColor, bool horns, bool batteries, int width, int height) : base(speed, weight, bodyColor, width, height, 150, 95) { - if (width < _trolleybusWidth || height < _trolleybusHeight) + if (EntityBus != null) { - return false; + EntityBus = new EntityTrolleybus(speed, weight, bodyColor, additionalColor, horns, batteries); } - _pictureWidth = width; - _pictureHeight = height; - EntityTrolleybus = new EntityTrolleybus(); - EntityTrolleybus.Init(speed, weight, bodyColor, additionalColor, horns, batteries); - return true; + } - /// - /// Установка позиции - /// - /// Координата X - /// Координата Y - public void SetPosition(int x, int y) + public override void DrawTransport(Graphics g) { - _startPosX = Math.Min(Math.Max(x, 0), _pictureWidth - _trolleybusWidth); - _startPosY = Math.Min(Math.Max(y, 0), _pictureHeight - _trolleybusHeight); - } - /// - /// Изменение направления перемещения - /// - /// Направление - public void MoveTransport(DirectionType direction) - { - if (EntityTrolleybus == null) + if (EntityBus is not EntityTrolleybus trolleyBus) { return; - } - switch (direction) - { - //влево - case DirectionType.Left: - if (_startPosX - EntityTrolleybus.Step > 0) - { - _startPosX -= (int)EntityTrolleybus.Step; - } - break; - //вверх - case DirectionType.Up: - if (_startPosY - EntityTrolleybus.Step > 0) - { - _startPosY -= (int)EntityTrolleybus.Step; - } - break; - // вправо - case DirectionType.Right: - if (_startPosX + _trolleybusWidth + EntityTrolleybus.Step < _pictureWidth) - { - _startPosX += (int)EntityTrolleybus.Step; - } - break; - // вниз - case DirectionType.Down: - if (_startPosY + _trolleybusHeight + EntityTrolleybus.Step < _pictureHeight) - { - _startPosY += (int)EntityTrolleybus.Step; - } - break; - } - } - /// - /// Прорисовка объекта - /// - /// - public void DrawTransport(Graphics g) - { - if (EntityTrolleybus == null) - { - return; - } - Pen pen = new(Color.Black); - Pen bodyPen = new(EntityTrolleybus.BodyColor); - Pen additionalPen = new(EntityTrolleybus.AdditionalColor); - Brush additionalBrush = new SolidBrush(EntityTrolleybus.AdditionalColor); - Pen windowPen = new(Color.Cyan); - //РИСОВАНИЕ САМОГО ТРРОЛЛЕЙБУСА - //корпус - g.DrawLine(bodyPen, _startPosX, _startPosY + 30, _startPosX, _startPosY + 80); - g.DrawLine(bodyPen, _startPosX, _startPosY + 80, _startPosX + 20, _startPosY + 80); - g.DrawLine(bodyPen, _startPosX + 45, _startPosY + 80, _startPosX + 105, _startPosY + 80); - g.DrawLine(bodyPen, _startPosX + 130, _startPosY + 80, _startPosX + 150, _startPosY + 80); - g.DrawLine(bodyPen, _startPosX + 150, _startPosY + 80, _startPosX + 150, _startPosY + 30); - g.DrawLine(bodyPen, _startPosX + 150, _startPosY + 30, _startPosX, _startPosY + 30); - - //колёса - g.DrawEllipse(pen, _startPosX + 20, _startPosY + 70, 25, 25); - g.DrawEllipse(pen, _startPosX + 105, _startPosY + 70, 25, 25); - - //дверь - g.DrawRectangle(bodyPen, _startPosX + 55, _startPosY + 50, 16, 30); - - //окна - //окна до двери - for (int i = 0; i < 2; i++) - { - g.DrawEllipse(windowPen, _startPosX + 5 + 25 * i, _startPosY + 35, 16, 24); - } - //окна после двери - for (int i = 0; i < 3; i++) - { - g.DrawEllipse(windowPen, _startPosX + 75 + 25 * i, _startPosY + 35, 16, 24); - } - + } + Pen additionalPen = new(trolleyBus.AdditionalColor); + Brush additionalBrush = new SolidBrush(trolleyBus.AdditionalColor); + base.DrawTransport(g); //опциональные "рога" - if (EntityTrolleybus.Horns) + if (trolleyBus.Horns) { g.DrawLine(additionalPen, _startPosX + 70, _startPosY + 30, _startPosX + 40, _startPosY); g.DrawLine(additionalPen, _startPosX + 70, _startPosY + 30, _startPosX + 60, _startPosY); } //опциональный отсек для батареи - if (EntityTrolleybus.Batteries) + if (trolleyBus.Batteries) { Point[] pointsOfBatteries = { new Point(_startPosX + 70, _startPosY + 30), new Point(_startPosX + 70, _startPosY + 25), new Point(_startPosX + 100, _startPosY + 25), new Point(_startPosX + 110, _startPosY + 30)}; g.FillPolygon(additionalBrush, pointsOfBatteries); diff --git a/Trolleybus/Trolleybus/EntityBus.cs b/Trolleybus/Trolleybus/EntityBus.cs new file mode 100644 index 0000000..25c6fbd --- /dev/null +++ b/Trolleybus/Trolleybus/EntityBus.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Trolleybus.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 => (double)Speed * 100 / Weight; + /// + /// Конструктор с параметрами + /// + /// Скорость + /// Вес автобуса + /// Основной цвет + public EntityBus(int speed, double weight, Color bodyColor) + { + Speed = speed; + Weight = weight; + BodyColor = bodyColor; + } + } +} diff --git a/Trolleybus/Trolleybus/EntityTrolleybus.cs b/Trolleybus/Trolleybus/EntityTrolleybus.cs index f78ddaf..940184a 100644 --- a/Trolleybus/Trolleybus/EntityTrolleybus.cs +++ b/Trolleybus/Trolleybus/EntityTrolleybus.cs @@ -4,22 +4,13 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Trolleybus +namespace Trolleybus.Entities { - public class EntityTrolleybus + /// + /// Класс-сущность "Троллейбус" + /// + public class EntityTrolleybus : EntityBus { - /// - /// Скорость - /// - public int Speed { get; private set; } - /// - /// Вес - /// - public double Weight { get; private set; } - /// - /// Основной цвет - /// - public Color BodyColor { get; private set; } /// /// Дополнительный цвет (для опциональных элементов) /// @@ -33,10 +24,6 @@ namespace Trolleybus /// public bool Batteries { get; private set; } /// - /// Шаг перемещения автомобиля - /// - public double Step => (double)Speed * 100 / Weight; - /// /// Инициализация полей объекта-класса троллейбуса /// /// Скорость @@ -45,11 +32,8 @@ namespace Trolleybus /// Дополнительный цвет /// Признак наличия "рогов" /// Признак наличия отсека под электрические батареи - public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool horns, bool batteries) + public EntityTrolleybus(int speed, double weight, Color bodyColor, Color additionalColor, bool horns, bool batteries) : base(speed, weight, bodyColor) { - Speed = speed; - Weight = weight; - BodyColor = bodyColor; AdditionalColor = additionalColor; Horns = horns; Batteries = batteries; diff --git a/Trolleybus/Trolleybus/FormTrolleybus.Designer.cs b/Trolleybus/Trolleybus/FormTrolleybus.Designer.cs index 34f1ad0..610fd6e 100644 --- a/Trolleybus/Trolleybus/FormTrolleybus.Designer.cs +++ b/Trolleybus/Trolleybus/FormTrolleybus.Designer.cs @@ -29,11 +29,14 @@ private void InitializeComponent() { pictureBoxTrolleybus = new PictureBox(); - buttonCreate = new Button(); + buttonCreateTrolleybus = new Button(); buttonUp = new Button(); buttonLeft = new Button(); buttonDown = new Button(); buttonRight = new Button(); + buttonCreateBus = new Button(); + comboBoxStrategy = new ComboBox(); + buttonStep = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBoxTrolleybus).BeginInit(); SuspendLayout(); // @@ -46,16 +49,16 @@ pictureBoxTrolleybus.TabIndex = 5; pictureBoxTrolleybus.TabStop = false; // - // buttonCreate + // buttonCreateTrolleybus // - buttonCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - buttonCreate.Location = new Point(12, 409); - buttonCreate.Name = "buttonCreate"; - buttonCreate.Size = new Size(90, 30); - buttonCreate.TabIndex = 6; - buttonCreate.Text = "Создать"; - buttonCreate.UseVisualStyleBackColor = true; - buttonCreate.Click += ButtonCreate_Click; + buttonCreateTrolleybus.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateTrolleybus.Location = new Point(12, 389); + buttonCreateTrolleybus.Name = "buttonCreateTrolleybus"; + buttonCreateTrolleybus.Size = new Size(120, 50); + buttonCreateTrolleybus.TabIndex = 6; + buttonCreateTrolleybus.Text = "Создать троллейбус"; + buttonCreateTrolleybus.UseVisualStyleBackColor = true; + buttonCreateTrolleybus.Click += ButtonCreateTrolleybus_Click; // // buttonUp // @@ -105,16 +108,52 @@ buttonRight.UseVisualStyleBackColor = true; buttonRight.Click += ButtonMove_Click; // + // buttonCreateBus + // + buttonCreateBus.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateBus.Location = new Point(138, 389); + buttonCreateBus.Name = "buttonCreateBus"; + buttonCreateBus.Size = new Size(120, 50); + buttonCreateBus.TabIndex = 11; + buttonCreateBus.Text = "Создать автобус"; + buttonCreateBus.UseVisualStyleBackColor = true; + buttonCreateBus.Click += ButtonCreateBus_Click; + // + // comboBoxStrategy + // + comboBoxStrategy.Anchor = AnchorStyles.Top | AnchorStyles.Right; + comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxStrategy.FormattingEnabled = true; + comboBoxStrategy.Items.AddRange(new object[] { "В центр", "В правый нижний угол" }); + comboBoxStrategy.Location = new Point(719, 12); + comboBoxStrategy.Name = "comboBoxStrategy"; + comboBoxStrategy.Size = new Size(151, 28); + comboBoxStrategy.TabIndex = 12; + // + // buttonStep + // + buttonStep.Anchor = AnchorStyles.Top | AnchorStyles.Right; + buttonStep.Location = new Point(748, 46); + buttonStep.Name = "buttonStep"; + buttonStep.Size = new Size(94, 29); + buttonStep.TabIndex = 13; + buttonStep.Text = "Шаг"; + buttonStep.UseVisualStyleBackColor = true; + buttonStep.Click += ButtonStep_Click; + // // FormTrolleybus // AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(882, 453); + Controls.Add(buttonStep); + Controls.Add(comboBoxStrategy); + Controls.Add(buttonCreateBus); Controls.Add(buttonRight); Controls.Add(buttonDown); Controls.Add(buttonLeft); Controls.Add(buttonUp); - Controls.Add(buttonCreate); + Controls.Add(buttonCreateTrolleybus); Controls.Add(pictureBoxTrolleybus); Name = "FormTrolleybus"; Text = "Троллейбус"; @@ -125,10 +164,13 @@ #endregion private PictureBox pictureBoxTrolleybus; - private Button buttonCreate; + private Button buttonCreateTrolleybus; private Button buttonUp; private Button buttonLeft; private Button buttonDown; private Button buttonRight; + private Button buttonCreateBus; + private ComboBox comboBoxStrategy; + private Button buttonStep; } } \ No newline at end of file diff --git a/Trolleybus/Trolleybus/FormTrolleybus.cs b/Trolleybus/Trolleybus/FormTrolleybus.cs index d4064dc..3ad371a 100644 --- a/Trolleybus/Trolleybus/FormTrolleybus.cs +++ b/Trolleybus/Trolleybus/FormTrolleybus.cs @@ -1,3 +1,6 @@ +using Trolleybus.DrawingObjects; +using Trolleybus.MovementStrategy; + namespace Trolleybus { /// @@ -8,7 +11,11 @@ namespace Trolleybus /// /// - /// - private DrawingTrolleybus? _drawingTrolleybus; + private DrawingBus? _drawingBus; + /// + /// + /// + private AbstractStrategy? _abstractStrategy; public FormTrolleybus() { InitializeComponent(); @@ -18,26 +25,24 @@ namespace Trolleybus /// private void Draw() { - if (_drawingTrolleybus == null) + if (_drawingBus == null) { return; } Bitmap bmp = new(pictureBoxTrolleybus.Width, pictureBoxTrolleybus.Height); Graphics gr = Graphics.FromImage(bmp); - _drawingTrolleybus.DrawTransport(gr); + _drawingBus.DrawTransport(gr); pictureBoxTrolleybus.Image = bmp; } /// - /// "" + /// " " /// /// /// - private void ButtonCreate_Click(object sender, EventArgs e) + private void ButtonCreateTrolleybus_Click(object sender, EventArgs e) { Random random = new(); - _drawingTrolleybus = new DrawingTrolleybus(); - // - _drawingTrolleybus.Init(random.Next(100, 300), + _drawingBus = new DrawingTrolleybus(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)), @@ -45,17 +50,34 @@ namespace Trolleybus Convert.ToBoolean(random.Next(0, 2)), pictureBoxTrolleybus.Width, pictureBoxTrolleybus.Height); // - _drawingTrolleybus.SetPosition(random.Next(10, 100), random.Next(10, 100)); + _drawingBus.SetPosition(random.Next(10, 100), random.Next(10, 100)); Draw(); } /// + /// " " + /// + /// + /// + private void ButtonCreateBus_Click(object sender, EventArgs e) + { + Random random = new(); + _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)), + pictureBoxTrolleybus.Width, pictureBoxTrolleybus.Height); + _drawingBus.SetPosition(random.Next(10, 100), random.Next(10, 100)); + Draw(); + + } + /// /// /// /// /// private void ButtonMove_Click(object sender, EventArgs e) { - if (_drawingTrolleybus == null) + if (_drawingBus == null) { return; } @@ -63,19 +85,58 @@ namespace Trolleybus switch (name) { case "buttonUp": - _drawingTrolleybus.MoveTransport(DirectionType.Up); + _drawingBus.MoveTransport(DirectionType.Up); break; case "buttonDown": - _drawingTrolleybus.MoveTransport(DirectionType.Down); + _drawingBus.MoveTransport(DirectionType.Down); break; case "buttonLeft": - _drawingTrolleybus.MoveTransport(DirectionType.Left); + _drawingBus.MoveTransport(DirectionType.Left); break; case "buttonRight": - _drawingTrolleybus.MoveTransport(DirectionType.Right); + _drawingBus.MoveTransport(DirectionType.Right); break; } Draw(); } + /// + /// "" + /// + /// + /// + private void ButtonStep_Click(object sender, EventArgs e) + { + if (_drawingBus == null) + { + return; + } + if (comboBoxStrategy.Enabled) + { + _abstractStrategy = comboBoxStrategy.SelectedIndex + switch + { + 0 => new MoveToCenter(), + 1 => new MoveToBorder(), + _ => null, + }; + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.SetData(new DrawingObjectBus(_drawingBus), pictureBoxTrolleybus.Width, pictureBoxTrolleybus.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/Trolleybus/Trolleybus/IMoveableObject.cs b/Trolleybus/Trolleybus/IMoveableObject.cs new file mode 100644 index 0000000..d0bc235 --- /dev/null +++ b/Trolleybus/Trolleybus/IMoveableObject.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Trolleybus.DrawingObjects; + +namespace Trolleybus.MovementStrategy +{ + /// + /// Интерфейс для работы с перемещаемым объектом + /// + public interface IMoveableObject + { + /// + /// Получение координаты X объекта + /// + ObjectParameters? GetObjectPosition { get; } + /// + /// Шаг объекта + /// + int GetStep { get; } + /// + /// Проверка, можно ли переместиться по нужному направлению + /// + /// + /// + bool CheckCanMove(DirectionType direction); + /// + /// Изменение направления пермещения объекта + /// + /// Направление + void MoveObject(DirectionType direction); + } +} diff --git a/Trolleybus/Trolleybus/MoveToBorder.cs b/Trolleybus/Trolleybus/MoveToBorder.cs new file mode 100644 index 0000000..80968f1 --- /dev/null +++ b/Trolleybus/Trolleybus/MoveToBorder.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace Trolleybus.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/Trolleybus/Trolleybus/MoveToCenter.cs b/Trolleybus/Trolleybus/MoveToCenter.cs new file mode 100644 index 0000000..a64c8a1 --- /dev/null +++ b/Trolleybus/Trolleybus/MoveToCenter.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Trolleybus.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/Trolleybus/Trolleybus/ObjectParameters.cs b/Trolleybus/Trolleybus/ObjectParameters.cs new file mode 100644 index 0000000..ad07bf6 --- /dev/null +++ b/Trolleybus/Trolleybus/ObjectParameters.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Trolleybus.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/Trolleybus/Trolleybus/Status.cs b/Trolleybus/Trolleybus/Status.cs new file mode 100644 index 0000000..4078b84 --- /dev/null +++ b/Trolleybus/Trolleybus/Status.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Trolleybus.MovementStrategy +{ + public enum Status + { + NotInit, + InProgress, + Finish + } +}