готово к сдаче

This commit is contained in:
MorozovDanil 2024-03-14 12:17:43 +04:00
parent 82d87e609a
commit bf1961b30b
16 changed files with 951 additions and 308 deletions

View File

@ -1,235 +0,0 @@
using ProjectContainerShip;
using System.Drawing;
namespace ProjectContainerShip;
/// <summary>
/// Класс, отвечающий за прорисовку и перемещение объекта-сущности
/// </summary>
public class DrawningContainerShip
{
/// <summary>
/// Класс-сущность
/// </summary>
public EntityContainerShip? EntityContainerShip { get; private set; }
/// <summary>
/// Ширина окна
/// </summary>
private int? _pictureWidth;
/// <summary>
/// Высота окна
/// </summary>
private int? _pictureHeight;
/// <summary>
/// Левая координата прорисовки контейнеровоза
/// </summary>
private int? _startPosX;
/// <summary>
/// Верхняя кооридната прорисовки контейнеровоза
/// </summary>
private int? _startPosY;
/// <summary>
/// Ширина прорисовки контейнеровоза
/// </summary>
private readonly int _drawningShipWidth = 130;
/// <summary>
/// Высота прорисовки контейнеровоза
/// </summary>
private readonly int _drawningShipHeight = 85;
/// <summary>
/// Инициализация свойств
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodyColor">Основной цвет</param>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="container">Признак наличия контейнеров</param>
/// <param name="Crane">Признак наличия крана</param>
public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool container, bool Crane)
{
EntityContainerShip = new EntityContainerShip();
EntityContainerShip.Init(speed, weight, bodyColor, additionalColor, container, Crane);
_pictureWidth = null;
_pictureHeight = null;
_startPosX = null;
_startPosY = null;
}
/// <summary>
/// Установка границ поля
/// </summary>
/// <param name="width">Ширина поля</param>
/// <param name="height">Высота поля</param>
/// <returns>true - границы заданы, false - проверка не пройдена, нельзя разместить объект в этих размерах</returns>
public bool SetPictureSize(int width, int height)
{
// TODO проверка, что объект "влезает" в размеры поля
if ((width < _drawningShipWidth) || (height < _drawningShipHeight))
{
return false;
}
// если влезает, сохраняем границы и корректируем позицию объекта, если она была уже установлена
_pictureWidth = width;
_pictureHeight = height;
if (_startPosX.HasValue && (_startPosX.Value + _drawningShipWidth > _pictureWidth))
{
_startPosX = _pictureWidth - _drawningShipWidth;
}
if (_startPosY.HasValue && (_startPosY + _drawningShipHeight > _pictureHeight))
{
_startPosY = _pictureHeight - _drawningShipHeight;
}
return true;
}
/// <summary>
/// Установка позиции
/// </summary>
/// <param name="x">Координата X</param>
/// <param name="y">Координата Y</param>
public void SetPosition(int x, int y)
{
_startPosX = x;
_startPosY = y;
if (_startPosX + _drawningShipWidth > _pictureWidth)
{
_startPosX = _pictureWidth - _drawningShipWidth;
}
if (_startPosX < 0)
{
_startPosX = 0;
}
if (_startPosY + _drawningShipHeight > _pictureHeight)
{
_startPosY = _pictureHeight - _drawningShipHeight;
}
if (_startPosY < 0)
{
_startPosY = 0;
}
}
/// <summary>
/// Изменение направления перемещения
/// </summary>
/// <param name="direction">Направление</param>
/// <returns>true - перемещене выполнено, false - перемещение невозможно</returns>
public bool MoveTransport(DirectionType direction)
{
if (EntityContainerShip == null || !_startPosX.HasValue || !_startPosY.HasValue)
{
return false;
}
switch (direction)
{
//влево
case DirectionType.Left:
if (_startPosX.Value - EntityContainerShip.Step > 0)
{
_startPosX -= (int)EntityContainerShip.Step;
}
return true;
//вверх
case DirectionType.Up:
if (_startPosY.Value - EntityContainerShip.Step > 0)
{
_startPosY -= (int)EntityContainerShip.Step;
}
return true;
// вправо
case DirectionType.Right:
//TODO прописать логику сдвига в право
if (_startPosX.Value + EntityContainerShip.Step + _drawningShipWidth < _pictureWidth)
{
_startPosX += (int)EntityContainerShip.Step;
}
return true;
//вниз
case DirectionType.Down:
//TODO прописать логику сдвига в вниз
if (_startPosY.Value + EntityContainerShip.Step + _drawningShipHeight < _pictureHeight)
{
_startPosY += (int)EntityContainerShip.Step;
}
return true;
default:
return false;
}
}
/// <summary>
/// Прорисовка объекта
/// </summary>
/// <param name="g"></param>
public void DrawTransport(Graphics g)
{
if (EntityContainerShip == null || !_startPosX.HasValue || !_startPosY.HasValue)
{
return;
}
Pen pen = new(Color.Black);
Brush additionalBrush = new SolidBrush(EntityContainerShip.AdditionalColor);
// контейнеры
if (EntityContainerShip.Container)
{
g.DrawRectangle(pen, _startPosX.Value + 60, _startPosY.Value + 55, 40, 5);
g.FillRectangle(additionalBrush, _startPosX.Value + 60, _startPosY.Value + 55, 40, 5);
g.DrawRectangle(pen, _startPosX.Value + 60, _startPosY.Value + 50, 40, 5);
g.FillRectangle(additionalBrush, _startPosX.Value + 60, _startPosY.Value + 45, 40, 5);
g.DrawRectangle(pen, _startPosX.Value + 60, _startPosY.Value + 45, 40, 5);
g.FillRectangle(additionalBrush, _startPosX.Value + 60, _startPosY.Value + 50, 40, 5);
}
//границы лодки
g.DrawRectangle(pen, _startPosX.Value + 5, _startPosY.Value + 80, 120, 10);
g.DrawRectangle(pen, _startPosX.Value + 10, _startPosY.Value + 60, 110, 20);
g.DrawEllipse(pen, _startPosX.Value, _startPosY.Value + 60, 25, 25);
g.DrawEllipse(pen, _startPosX.Value + 105, _startPosY.Value + 60, 25, 25);
//кузов
Brush br = new SolidBrush(EntityContainerShip.BodyColor);
g.FillRectangle(br, _startPosX.Value + 5, _startPosY.Value + 80, 120, 10);
g.FillRectangle(br, _startPosX.Value + 10, _startPosY.Value + 60, 110, 20);
g.FillEllipse(br, _startPosX.Value, _startPosY.Value + 60, 25, 25);
g.FillEllipse(br, _startPosX.Value + 105, _startPosY.Value + 60, 25, 25);
//палуба
g.DrawRectangle(pen, _startPosX.Value + 20, _startPosY.Value + 30, 30, 30);
g.FillRectangle(br, _startPosX.Value + 20, _startPosY.Value + 30, 30, 30);
// кран
if (EntityContainerShip.Crane)
{
g.DrawRectangle(pen, _startPosX.Value + 105, _startPosY.Value + 15, 15, 45);
g.DrawRectangle(pen, _startPosX.Value + 75, _startPosY.Value + 17, 30, 7);
g.DrawRectangle(pen, _startPosX.Value + 80, _startPosY.Value + 24, 5, 15);
g.FillRectangle(additionalBrush, _startPosX.Value + 105, _startPosY.Value + 15, 15, 45);
g.FillRectangle(additionalBrush, _startPosX.Value + 75, _startPosY.Value + 17, 30, 7);
g.FillRectangle(additionalBrush, _startPosX.Value + 80, _startPosY.Value + 24, 5, 15);
}
}
}

View File

@ -0,0 +1,32 @@
namespace ProjectContainerShip.Drawnings;
/// <summary>
/// Направление перемещения
/// </summary>
public enum DirectionType
{
/// <summary>
/// Неизвестное направление
/// </summary>
Unknow = -1,
/// <summary>
/// Вверх
/// </summary>
Up = 1,
/// <summary>
/// Вниз
/// </summary>
Down = 2,
/// <summary>
/// Влево
/// </summary>
Left = 3,
/// <summary>
/// Вправо
/// </summary>
Right = 4
}

View File

@ -0,0 +1,70 @@
using ProjectContainerShip.Entities;
namespace ProjectContainerShip.Drawnings;
/// <summary>
/// Класс, отвечающий за прорисовку и перемещение объекта-сущности
/// </summary>
public class DrawningContainerShip : DrawningShip
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodyColor">Цвет палубы</param>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="crane">Признак наличия крана</param>
/// <param name="container">Признак наличия контейнеров</param>
public DrawningContainerShip(int speed, double weight, Color bodyColor, Color additionalColor, bool crane, bool container) : base(125, 60)
{
EntityShip = new EntityContainerShip(speed, weight, bodyColor, additionalColor, crane, container);
}
/// <returns>true - объект создан, false - проверка не пройдена, нельзя создать объект в этих размерах</returns>
public override void DrawTransport(Graphics g)
{
if (EntityShip == null || EntityShip is not EntityContainerShip containerShip || !_startPosX.HasValue || !_startPosY.HasValue)
{
return;
}
Pen pen = new(Color.Black);
Brush additionalBrush = new SolidBrush(containerShip.AdditionalColor);
base.DrawTransport(g);
_startPosX -= 5;
_startPosY -= 30;
// кран
if (containerShip.Crane)
{
g.DrawRectangle(pen, _startPosX.Value + 105, _startPosY.Value + 22, 15, 38);
g.DrawRectangle(pen, _startPosX.Value + 75, _startPosY.Value + 22, 30, 7);
g.DrawRectangle(pen, _startPosX.Value + 80, _startPosY.Value + 29, 5, 15);
g.FillRectangle(additionalBrush, _startPosX.Value + 105, _startPosY.Value + 22, 15, 38);
g.FillRectangle(additionalBrush, _startPosX.Value + 75, _startPosY.Value + 22, 30, 7);
g.FillRectangle(additionalBrush, _startPosX.Value + 80, _startPosY.Value + 29, 5, 15);
}
//base.DrawTransport(g);
// контейнеры
if (containerShip.Container)
{
g.DrawRectangle(pen, _startPosX.Value + 60, _startPosY.Value + 55, 40, 5);
g.FillRectangle(additionalBrush, _startPosX.Value + 60, _startPosY.Value + 55, 40, 5);
g.DrawRectangle(pen, _startPosX.Value + 60, _startPosY.Value + 50, 40, 5);
g.FillRectangle(additionalBrush, _startPosX.Value + 60, _startPosY.Value + 50, 40, 5);
g.DrawRectangle(pen, _startPosX.Value + 60, _startPosY.Value + 45, 40, 5);
g.FillRectangle(additionalBrush, _startPosX.Value + 60, _startPosY.Value + 45, 40, 5);
}
//base.DrawTransport(g);
_startPosX += 5;
_startPosY += 30;
}
}

View File

@ -0,0 +1,233 @@
using ProjectContainerShip.Entities;
namespace ProjectContainerShip.Drawnings;
/// <summary>
/// Класс, отвечающий за прорисовку и перемещение базового объекта-сущности
/// </summary>
public class DrawningShip
{
/// <summary>
/// Класс-сущность
/// </summary>
public EntityShip? EntityShip { get; protected set; }
/// <summary>
/// Ширина окна
/// </summary>
private int? _pictureWidth;
/// <summary>
/// Высота окна
/// </summary>
private int? _pictureHeight;
/// <summary>
/// Левая координата прорисовки корабля
/// </summary>
protected int? _startPosX;
/// <summary>
/// Верхняя кооридната прорисовки корабля
/// </summary>
protected int? _startPosY;
/// <summary>
/// Ширина прорисовки корабля
/// </summary>
private readonly int _drawningShipWidth = 125;
/// <summary>
/// Высота прорисовки корабля
/// </summary>
private readonly int _drawningShipHeight = 60;
/// <summary>
/// Координата X объекта
/// </summary>
public int? GetPosX => _startPosX;
/// <summary>
/// Координата Y объекта
/// </summary>
public int? GetPosY => _startPosY;
/// <summary>
/// Ширина объекта
/// </summary>
public int GetWidth => _drawningShipWidth;
/// <summary>
/// Высота объекта
/// </summary>
public int GetHeight => _drawningShipHeight;
/// <summary>
/// Пустой конструктор
/// </summary>
private DrawningShip()
{
_pictureWidth = null;
_pictureHeight = null;
_startPosX = null;
_startPosY = null;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodyColor">Основной цвет</param>
public DrawningShip(int speed, double weight, Color bodyColor) : this()
{
EntityShip = new EntityShip(speed, weight, bodyColor);
}
/// <summary>
/// Конструктор для наследников
/// </summary>
/// <param name="drawningShipWidth">Ширина прорисовки автомобиля</param>
/// <param name="drawningShipHeight">Высота прорисовки автомобиля</param>
protected DrawningShip(int drawningShipWidth, int drawningShipHeight) : this()
{
_drawningShipWidth = drawningShipWidth;
_pictureHeight = drawningShipHeight;
}
/// <summary>
/// Установка границ поля
/// </summary>
/// <param name="width">Ширина поля</param>
/// <param name="height">Высота поля</param>
/// <returns>true - границы заданы, false - проверка не пройдена, нельзя разместить объект в этих размерах</returns>
public bool SetPictureSize(int width, int height)
{
// TODO проверка, что объект "влезает" в размеры поля
if ((width < _drawningShipWidth) || (height < _drawningShipHeight))
{
return false;
}
// если влезает, сохраняем границы и корректируем позицию объекта, если она была уже установлена
_pictureWidth = width;
_pictureHeight = height;
if (_startPosX.HasValue && (_startPosX.Value + _drawningShipWidth > _pictureWidth))
{
_startPosX = _pictureWidth - _drawningShipWidth;
}
if (_startPosY.HasValue && (_startPosY + _drawningShipHeight > _pictureHeight))
{
_startPosY = _pictureHeight - _drawningShipHeight;
}
return true;
}
/// <summary>
/// Установка позиции
/// </summary>
/// <param name="x">Координата X</param>
/// <param name="y">Координата Y</param>
public void SetPosition(int x, int y)
{
if (EntityShip == null) return;
while (x + _drawningShipWidth > _pictureWidth)
{
x -= (int)EntityShip.Step;
}
while (x < 0)
{
x += (int)EntityShip.Step;
}
while (y + _drawningShipHeight > _pictureHeight)
{
y -= (int)EntityShip.Step;
}
while (y < 0)
{
y += (int)EntityShip.Step;
}
_startPosX = x;
_startPosY = y;
}
/// <summary>
/// Изменение направления перемещения
/// </summary>
/// <param name="direction">Направление</param>
public bool MoveTransport(DirectionType direction)
{
if (EntityShip == null || !_startPosX.HasValue || !_startPosY.HasValue)
{
return false;
}
switch (direction)
{
//влево
case DirectionType.Left:
if (_startPosX.Value - EntityShip.Step > 0)
{
_startPosX -= (int)EntityShip.Step;
}
return true;
//вверх
case DirectionType.Up:
if (_startPosY.Value - EntityShip.Step > 0)
{
_startPosY -= (int)EntityShip.Step;
}
return true;
// вправо
case DirectionType.Right:
if (_startPosX + _drawningShipWidth + EntityShip.Step < _pictureWidth)
{
_startPosX += (int)EntityShip.Step;
}
return true;
//вниз
case DirectionType.Down:
if (_startPosY + _drawningShipHeight + EntityShip.Step < _pictureHeight)
{
_startPosY += (int)EntityShip.Step;
}
return true;
default:
return false;
}
}
/// <summary>
/// Прорисовка объекта
/// </summary>
/// <param name="g"></param>
public virtual void DrawTransport(Graphics g)
{
if (EntityShip == null || !_startPosX.HasValue || !_startPosY.HasValue)
{
return;
}
//незабыть смещение к границе лев.верх.
Pen pen = new(Color.Black);
//границы лодки
g.DrawRectangle(pen, _startPosX.Value, _startPosY.Value + 50, 120, 10);
g.DrawRectangle(pen, _startPosX.Value + 5, _startPosY.Value + 30, 110, 20);
g.DrawEllipse(pen, _startPosX.Value - 5, _startPosY.Value + 30, 25, 25);
g.DrawEllipse(pen, _startPosX.Value + 100, _startPosY.Value + 30, 25, 25);
//кузов
Brush br = new SolidBrush(EntityShip.BodyColor);
g.FillRectangle(br, _startPosX.Value, _startPosY.Value + 50, 120, 10);
g.FillRectangle(br, _startPosX.Value + 5, _startPosY.Value + 30, 110, 20);
g.FillEllipse(br, _startPosX.Value - 5, _startPosY.Value + 30, 25, 25);
g.FillEllipse(br, _startPosX.Value + 100, _startPosY.Value + 30, 25, 25);
//палуба
g.DrawRectangle(pen, _startPosX.Value + 15, _startPosY.Value, 30, 30);
g.FillRectangle(br, _startPosX.Value + 15, _startPosY.Value, 30, 30);
}
}

View File

@ -1,63 +1,38 @@
 namespace ProjectContainerShip.Entities;
namespace ProjectContainerShip;
/// <summary> /// <summary>
/// Класс-сущность "Контейнеровоз" /// Класс-сущность "Контейнеровоз"
/// </summary> /// </summary>
public class EntityContainerShip public class EntityContainerShip : EntityShip
{ {
/// <summary>
/// Скорость
/// </summary>
public int Speed { get; private set; }
/// <summary>
/// Вес
/// </summary>
public double Weight { get; private set; }
/// <summary>
/// Основной цвет
/// </summary>
public Color BodyColor { get; private set; }
/// <summary> /// <summary>
/// Дополнительный цвет (для опциональных элементов) /// Дополнительный цвет (для опциональных элементов)
/// </summary> /// </summary>
public Color AdditionalColor { get; private set; } public Color AdditionalColor { get; private set; }
/// <summary>
/// Признак (опция) наличия Контейнеров
/// </summary>
public bool Container { get; private set; }
/// <summary> /// <summary>
/// Признак (опция) наличия крана /// Признак (опция) наличия крана
/// </summary> /// </summary>
public bool Crane { get; private set; } public bool Crane { get; private set; }
/// <summary> /// <summary>
/// Шаг перемещения контейнеровоза /// Признак (опция) наличия дополнительных контейнеров
/// </summary> /// </summary>
public double Step => Speed * 100 / Weight; public bool Container { get; private set; }
/// <summary> /// <summary>
/// Инициализация полей объекта-класса контейнеровоза /// Инициализация полей объекта-класса контейнеровоза
/// </summary> /// </summary>
/// <param name="speed">Скорость</param> /// <param name="speed">Скорость</param>
/// <param name="weight">Вес контейнеровоза</param> /// <param name="weight">Вес </param>
/// <param name="bodyColor">Основной цвет</param> /// <param name="bodyColor">Основной цвет</param>
/// <param name="additionalColor">Дополнительный цвет</param> /// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="container">Признак наличия контейнеров</param>
/// <param name="crane">Признак наличия крана</param> /// <param name="crane">Признак наличия крана</param>
public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool container, bool crane) /// <param name="container">Признак наличия контейнеров</param>
public EntityContainerShip(int speed, double weight, Color bodyColor, Color additionalColor, bool crane, bool container) : base(speed, weight, Color.Black)
{ {
Speed = speed;
Weight = weight;
BodyColor = bodyColor;
AdditionalColor = additionalColor; AdditionalColor = additionalColor;
Container = container;
Crane = crane; Crane = crane;
Container = container;
} }
} }

View File

@ -0,0 +1,42 @@
namespace ProjectContainerShip.Entities;
/// <summary>
/// Класс-сущность "Корабль"
/// </summary>
public class EntityShip
{
/// <summary>
/// Скорость
/// </summary>
public int Speed { get; private set; }
/// <summary>
/// Вес
/// </summary>
public double Weight { get; private set; }
/// <summary>
/// Основной цвет
/// </summary>
public Color BodyColor { get; private set; }
/// <summary>
/// Шаг перемещения корабля
/// </summary>
public double Step => (double)Speed * 100 / Weight;
/// <summary>
/// Конструктор с параметрами
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес корабля</param>
/// <param name="bodyColor">Основной цвет</param>
public EntityShip(int speed, double weight, Color bodyColor)
{
Speed = speed;
Weight = weight;
BodyColor = bodyColor;
}
}

View File

@ -38,6 +38,9 @@ namespace ProjectContainerShip
buttonUp = new Button(); buttonUp = new Button();
buttonDown = new Button(); buttonDown = new Button();
buttonRight = new Button(); buttonRight = new Button();
buttonCreateShip = new Button();
comboBoxStrategy = new ComboBox();
buttonStrategyStep = new Button();
((System.ComponentModel.ISupportInitialize)pictureBoxContainerShip).BeginInit(); ((System.ComponentModel.ISupportInitialize)pictureBoxContainerShip).BeginInit();
SuspendLayout(); SuspendLayout();
// //
@ -46,18 +49,18 @@ namespace ProjectContainerShip
pictureBoxContainerShip.Dock = DockStyle.Fill; pictureBoxContainerShip.Dock = DockStyle.Fill;
pictureBoxContainerShip.Location = new Point(0, 0); pictureBoxContainerShip.Location = new Point(0, 0);
pictureBoxContainerShip.Name = "pictureBoxContainerShip"; pictureBoxContainerShip.Name = "pictureBoxContainerShip";
pictureBoxContainerShip.Size = new Size(923, 597); pictureBoxContainerShip.Size = new Size(934, 586);
pictureBoxContainerShip.TabIndex = 0; pictureBoxContainerShip.TabIndex = 0;
pictureBoxContainerShip.TabStop = false; pictureBoxContainerShip.TabStop = false;
// //
// buttonCreateContainerShip // buttonCreateContainerShip
// //
buttonCreateContainerShip.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; buttonCreateContainerShip.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonCreateContainerShip.Location = new Point(12, 562); buttonCreateContainerShip.Location = new Point(12, 546);
buttonCreateContainerShip.Name = "buttonCreateContainerShip"; buttonCreateContainerShip.Name = "buttonCreateContainerShip";
buttonCreateContainerShip.Size = new Size(75, 23); buttonCreateContainerShip.Size = new Size(196, 26);
buttonCreateContainerShip.TabIndex = 1; buttonCreateContainerShip.TabIndex = 1;
buttonCreateContainerShip.Text = "Создать"; buttonCreateContainerShip.Text = "Создать контейнеровоз";
buttonCreateContainerShip.UseVisualStyleBackColor = true; buttonCreateContainerShip.UseVisualStyleBackColor = true;
buttonCreateContainerShip.Click += ButtonCreateContainerShip_Click; buttonCreateContainerShip.Click += ButtonCreateContainerShip_Click;
// //
@ -66,9 +69,9 @@ namespace ProjectContainerShip
buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonLeft.BackgroundImage = Properties.Resources.arrowLeft; buttonLeft.BackgroundImage = Properties.Resources.arrowLeft;
buttonLeft.BackgroundImageLayout = ImageLayout.Stretch; buttonLeft.BackgroundImageLayout = ImageLayout.Stretch;
buttonLeft.Location = new Point(787, 550); buttonLeft.Location = new Point(798, 532);
buttonLeft.Name = "buttonLeft"; buttonLeft.Name = "buttonLeft";
buttonLeft.Size = new Size(35, 35); buttonLeft.Size = new Size(35, 40);
buttonLeft.TabIndex = 2; buttonLeft.TabIndex = 2;
buttonLeft.UseVisualStyleBackColor = true; buttonLeft.UseVisualStyleBackColor = true;
buttonLeft.Click += ButtonMove_Click; buttonLeft.Click += ButtonMove_Click;
@ -78,9 +81,9 @@ namespace ProjectContainerShip
buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonUp.BackgroundImage = Properties.Resources.arrowUp; buttonUp.BackgroundImage = Properties.Resources.arrowUp;
buttonUp.BackgroundImageLayout = ImageLayout.Stretch; buttonUp.BackgroundImageLayout = ImageLayout.Stretch;
buttonUp.Location = new Point(828, 509); buttonUp.Location = new Point(839, 486);
buttonUp.Name = "buttonUp"; buttonUp.Name = "buttonUp";
buttonUp.Size = new Size(35, 35); buttonUp.Size = new Size(35, 40);
buttonUp.TabIndex = 3; buttonUp.TabIndex = 3;
buttonUp.UseVisualStyleBackColor = true; buttonUp.UseVisualStyleBackColor = true;
buttonUp.Click += ButtonMove_Click; buttonUp.Click += ButtonMove_Click;
@ -90,9 +93,9 @@ namespace ProjectContainerShip
buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonDown.BackgroundImage = Properties.Resources.arrowDown; buttonDown.BackgroundImage = Properties.Resources.arrowDown;
buttonDown.BackgroundImageLayout = ImageLayout.Stretch; buttonDown.BackgroundImageLayout = ImageLayout.Stretch;
buttonDown.Location = new Point(828, 550); buttonDown.Location = new Point(839, 532);
buttonDown.Name = "buttonDown"; buttonDown.Name = "buttonDown";
buttonDown.Size = new Size(35, 35); buttonDown.Size = new Size(35, 40);
buttonDown.TabIndex = 4; buttonDown.TabIndex = 4;
buttonDown.UseVisualStyleBackColor = true; buttonDown.UseVisualStyleBackColor = true;
buttonDown.Click += ButtonMove_Click; buttonDown.Click += ButtonMove_Click;
@ -102,18 +105,52 @@ namespace ProjectContainerShip
buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonRight.BackgroundImage = Properties.Resources.arrowRight; buttonRight.BackgroundImage = Properties.Resources.arrowRight;
buttonRight.BackgroundImageLayout = ImageLayout.Stretch; buttonRight.BackgroundImageLayout = ImageLayout.Stretch;
buttonRight.Location = new Point(869, 550); buttonRight.Location = new Point(880, 532);
buttonRight.Name = "buttonRight"; buttonRight.Name = "buttonRight";
buttonRight.Size = new Size(35, 35); buttonRight.Size = new Size(35, 40);
buttonRight.TabIndex = 5; buttonRight.TabIndex = 5;
buttonRight.UseVisualStyleBackColor = true; buttonRight.UseVisualStyleBackColor = true;
buttonRight.Click += ButtonMove_Click; buttonRight.Click += ButtonMove_Click;
// //
// buttonCreateShip
//
buttonCreateShip.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonCreateShip.Location = new Point(214, 546);
buttonCreateShip.Name = "buttonCreateShip";
buttonCreateShip.Size = new Size(196, 26);
buttonCreateShip.TabIndex = 6;
buttonCreateShip.Text = "Создать корабль";
buttonCreateShip.UseVisualStyleBackColor = true;
buttonCreateShip.Click +=ButtonCreateShip_Click;
//
// comboBoxStrategy
//
comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxStrategy.FormattingEnabled = true;
comboBoxStrategy.Items.AddRange(new object[] { "К центру", "К краю" });
comboBoxStrategy.Location = new Point(801, 12);
comboBoxStrategy.Name = "comboBoxStrategy";
comboBoxStrategy.Size = new Size(121, 25);
comboBoxStrategy.TabIndex = 7;
//
// buttonStrategyStep
//
buttonStrategyStep.Location = new Point(839, 43);
buttonStrategyStep.Name = "buttonStrategyStep";
buttonStrategyStep.Size = new Size(75, 23);
buttonStrategyStep.TabIndex = 8;
buttonStrategyStep.Text = "Шаг";
buttonStrategyStep.UseVisualStyleBackColor = true;
buttonStrategyStep.Click += ButtonStrategyStep_Click;
//
// FormContainerShip // FormContainerShip
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(923, 597); ClientSize = new Size(934, 586);
Controls.Add(buttonStrategyStep);
Controls.Add(comboBoxStrategy);
Controls.Add(buttonCreateShip);
Controls.Add(buttonRight); Controls.Add(buttonRight);
Controls.Add(buttonDown); Controls.Add(buttonDown);
Controls.Add(buttonUp); Controls.Add(buttonUp);
@ -134,5 +171,9 @@ namespace ProjectContainerShip
private Button buttonUp; private Button buttonUp;
private Button buttonDown; private Button buttonDown;
private Button buttonRight; private Button buttonRight;
private Button button1;
private Button buttonCreateShip;
private ComboBox comboBoxStrategy;
private Button buttonStrategyStep;
} }
} }

View File

@ -1,4 +1,5 @@
using ProjectContainerShip; using ProjectContainerShip.Drawnings;
using ProjectContainerShip.MovementStrategy;
namespace ProjectContainerShip; namespace ProjectContainerShip;
@ -10,7 +11,12 @@ public partial class FormContainerShip : Form
/// <summary> /// <summary>
/// Поле-объект для прорисовки объекта /// Поле-объект для прорисовки объекта
/// </summary> /// </summary>
private DrawningContainerShip? _drawningContainerShip; private DrawningShip? _drawningShip;
/// <summary>
/// Стратегия перемещения
/// </summary>
private AbstractStrategy? _strategy;
/// <summary> /// <summary>
/// Конструктор формы /// Конструктор формы
@ -18,6 +24,7 @@ public partial class FormContainerShip : Form
public FormContainerShip() public FormContainerShip()
{ {
InitializeComponent(); InitializeComponent();
_strategy = null;
} }
/// <summary> /// <summary>
@ -25,35 +32,61 @@ public partial class FormContainerShip : Form
/// </summary> /// </summary>
private void Draw() private void Draw()
{ {
if (_drawningContainerShip == null) if (_drawningShip == null)
{ {
return; return;
} }
Bitmap bmp = new(pictureBoxContainerShip.Width, pictureBoxContainerShip.Height); Bitmap bmp = new(pictureBoxContainerShip.Width, pictureBoxContainerShip.Height);
Graphics gr = Graphics.FromImage(bmp); Graphics gr = Graphics.FromImage(bmp);
_drawningContainerShip.DrawTransport(gr); _drawningShip.DrawTransport(gr);
pictureBoxContainerShip.Image = bmp; pictureBoxContainerShip.Image = bmp;
} }
/// <summary> /// <summary>
/// Обработка нажатия кнопки "Создать" /// Создание объекта класса-перемещения
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="type">Тип создаваемого объекта</param>
/// <param name="e"></param> private void CreateObject(string type)
private void ButtonCreateContainerShip_Click(object sender, EventArgs e)
{ {
Random random = new(); Random random = new();
_drawningContainerShip = new DrawningContainerShip(); switch (type)
_drawningContainerShip.Init(random.Next(100, 300), random.Next(1000, 3000), {
case nameof(DrawningShip):
_drawningShip = new DrawningShip(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(DrawningContainerShip):
_drawningShip = new DrawningContainerShip(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)),
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))); Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2)));
_drawningContainerShip.SetPictureSize(pictureBoxContainerShip.Width, pictureBoxContainerShip.Height); break;
_drawningContainerShip.SetPosition(random.Next(10, 100), random.Next(10, 100)); default:
return;
}
_drawningShip.SetPictureSize(pictureBoxContainerShip.Width, pictureBoxContainerShip.Height);
_drawningShip.SetPosition(random.Next(10, 100), random.Next(10, 100));
_strategy = null;
comboBoxStrategy.Enabled = true;
Draw(); Draw();
} }
/// <summary>
/// Обработка нажатия кнопки "Создать спортивный автомобиль"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCreateContainerShip_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningContainerShip));
/// <summary>
/// Обработка нажатия кнопки "Создать автомобиль"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCreateShip_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningShip));
/// <summary> /// <summary>
/// Перемещение объекта по форме (нажатие кнопок навигации) /// Перемещение объекта по форме (нажатие кнопок навигации)
/// </summary> /// </summary>
@ -61,7 +94,7 @@ public partial class FormContainerShip : Form
/// <param name="e"></param> /// <param name="e"></param>
private void ButtonMove_Click(object sender, EventArgs e) private void ButtonMove_Click(object sender, EventArgs e)
{ {
if (_drawningContainerShip == null) if (_drawningShip == null)
{ {
return; return;
} }
@ -71,16 +104,16 @@ public partial class FormContainerShip : Form
switch (name) switch (name)
{ {
case "buttonUp": case "buttonUp":
result = _drawningContainerShip.MoveTransport(DirectionType.Up); result = _drawningShip.MoveTransport(DirectionType.Up);
break; break;
case "buttonDown": case "buttonDown":
result = _drawningContainerShip.MoveTransport(DirectionType.Down); result = _drawningShip.MoveTransport(DirectionType.Down);
break; break;
case "buttonLeft": case "buttonLeft":
result = _drawningContainerShip.MoveTransport(DirectionType.Left); result = _drawningShip.MoveTransport(DirectionType.Left);
break; break;
case "buttonRight": case "buttonRight":
result = _drawningContainerShip.MoveTransport(DirectionType.Right); result = _drawningShip.MoveTransport(DirectionType.Right);
break; break;
} }
@ -89,4 +122,47 @@ public partial class FormContainerShip : Form
Draw(); Draw();
} }
} }
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonStrategyStep_Click(object sender, EventArgs e)
{
if (_drawningShip == null)
{
return;
}
if (comboBoxStrategy.Enabled)
{
_strategy = comboBoxStrategy.SelectedIndex switch
{
0 => new MoveToCenter(),
1 => new MoveToBorder(),
_ => null,
};
if (_strategy == null)
{
return;
}
_strategy.SetData(new MoveableShip(_drawningShip), pictureBoxContainerShip.Width, pictureBoxContainerShip.Height);
}
if (_strategy == null)
{
return;
}
comboBoxStrategy.Enabled = false;
_strategy.MakeStep();
Draw();
if (_strategy.GetStatus() == StrategyStatus.Finish)
{
comboBoxStrategy.Enabled = true;
_strategy = null;
}
}
} }

View File

@ -0,0 +1,141 @@
using ProjectContainerShip.Drawnings;
using ProjectContainerShip.MovementStrategy;
namespace ProjectContainerShip.MovementStrategy;
/// <summary>
/// Класс-стратегия перемещения объекта
/// </summary>
public abstract class AbstractStrategy
{
/// <summary>*
/// Перемещаемый объект
/// </summary>
private IMoveableObject? _moveableObject;
/// <summary>
/// Статус перемещения
/// </summary>
private StrategyStatus _state = StrategyStatus.NotInit;
/// <summary>
/// Ширина поля
/// </summary>
protected int FieldWidth { get; private set; }
/// <summary>
/// Высота поля
/// </summary>
protected int FieldHeight { get; private set; }
/// <summary>
/// Статус перемещения
/// </summary>
public StrategyStatus GetStatus() { return _state; }
/// <summary>
/// Установка данных
/// </summary>
/// <param name="moveableObject">Перемещаемый объект</param>
/// <param name="width">Ширина поля</param>
/// <param name="height">Высота поля</param>
public void SetData(IMoveableObject moveableObject, int width, int height)
{
if (moveableObject == null)
{
_state = StrategyStatus.NotInit;
return;
}
_state = StrategyStatus.InProgress;
_moveableObject = moveableObject;
FieldWidth = width;
FieldHeight = height;
}
/// <summary>
/// Шаг перемещения
/// </summary>
public void MakeStep()
{
if (_state != StrategyStatus.InProgress)
{
return;
}
if (IsTargetDestinaion())
{
_state = StrategyStatus.Finish;
return;
}
MoveToTarget();
}
/// <summary>
/// Перемещение влево
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveLeft() => MoveTo(MovementDirection.Left);
/// <summary>
/// Перемещение вправо
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveRight() => MoveTo(MovementDirection.Right);
/// <summary>
/// Перемещение вверх
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveUp() => MoveTo(MovementDirection.Up);
/// <summary>
/// Перемещение вниз
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveDown() => MoveTo(MovementDirection.Down);
/// <summary>
/// Параметры объекта
/// </summary>
protected ObjectParameters? GetObjectParameters => _moveableObject?.GetObjectPosition;
/// <summary>
/// Шаг объекта
/// </summary>
/// <returns></returns>
protected int? GetStep()
{
if (_state != StrategyStatus.InProgress)
{
return null;
}
return _moveableObject?.GetStep;
}
/// <summary>
/// Перемещение к цели
/// </summary>
protected abstract void MoveToTarget();
/// <summary>
/// Достигнута ли цель
/// </summary>
/// <returns></returns>
protected abstract bool IsTargetDestinaion();
/// <summary>
/// Попытка перемещения в требуемом направлении
/// </summary>
/// <param name="movementDirection">Направление</param>
/// <returns>Результат попытки (true - удалось переместиться, false - неудача)</returns>
private bool MoveTo(MovementDirection movementDirection)
{
if (_state != StrategyStatus.InProgress)
{
return false;
}
return _moveableObject?.TryMoveObject(movementDirection) ?? false;
}
}

View File

@ -0,0 +1,28 @@
using ProjectContainerShip.Drawnings;
namespace ProjectContainerShip.MovementStrategy;
/// <summary>
/// Интерфейс для работы с перемещаемым объектом
/// </summary>
public interface IMoveableObject
{
/// <summary>
/// Получение координаты X объекта
/// </summary>
ObjectParameters? GetObjectPosition { get; }
/// <summary>
/// Шаг объекта
/// </summary>
int GetStep { get; }
/// <summary>
/// Попытка переместить объект в указанном направлении
/// </summary>
/// <param name="direction">Направление</param>
/// <returns>true - объект перемещен, false - перемещение невозможно</returns>
bool TryMoveObject(MovementDirection direction);
}

View File

@ -0,0 +1,47 @@
namespace ProjectContainerShip.MovementStrategy;
internal class MoveToBorder : AbstractStrategy
{
protected override bool IsTargetDestinaion()
{
if (GetObjectParameters == null)
{
return false;
}
return GetObjectParameters.RightBorder <= FieldWidth &&
GetObjectParameters.RightBorder + GetStep() >= FieldWidth &&
GetObjectParameters.DownBorder <= FieldHeight &&
GetObjectParameters.DownBorder + GetStep() >= FieldHeight;
}
protected override void MoveToTarget()
{
if (GetObjectParameters == null)
{
return;
}
if (Math.Abs(GetObjectParameters.ObjectMiddleHorizontal - FieldWidth) > GetStep())
{
if (GetObjectParameters.ObjectMiddleHorizontal - FieldWidth > 0)
{
MoveLeft();
}
else
{
MoveRight();
}
}
if (Math.Abs(GetObjectParameters.ObjectMiddleVertical - FieldHeight) > GetStep())
{
if (GetObjectParameters.ObjectMiddleVertical - FieldHeight > 0)
{
MoveUp();
}
else
{
MoveDown();
}
}
}
}

View File

@ -0,0 +1,51 @@
namespace ProjectContainerShip.MovementStrategy
{
public class MoveToCenter : AbstractStrategy
{
protected override bool IsTargetDestinaion()
{
ObjectParameters? 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()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null)
{
return;
}
int diffX = objParams.ObjectMiddleHorizontal - FieldWidth / 2;
if (Math.Abs(diffX) > GetStep())
{
if (diffX > 0)
{
MoveLeft();
}
else
{
MoveRight();
}
}
int diffY = objParams.ObjectMiddleVertical - FieldHeight / 2;
if (Math.Abs(diffY) > GetStep())
{
if (diffY > 0)
{
MoveUp();
}
else
{
MoveDown();
}
}
}
}
}

View File

@ -0,0 +1,69 @@
using ProjectContainerShip.Drawnings;
namespace ProjectContainerShip.MovementStrategy;
/// <summary>
/// Класс-реализация IMoveableObject с использованием DrawningShip
/// </summary>
public class MoveableShip : IMoveableObject
{
/// <summary>
/// Поле-объект класса DrawningShip или его наследника
/// </summary>
private readonly DrawningShip? _ship = null;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="ship"></param>
public MoveableShip(DrawningShip ship)
{
_ship = ship;
}
public ObjectParameters? GetObjectPosition
{
get
{
if (_ship == null || _ship.EntityShip == null || !_ship.GetPosX.HasValue || !_ship.GetPosY.HasValue)
{
return null;
}
return new ObjectParameters(_ship.GetPosX.Value, _ship.GetPosY.Value, _ship.GetWidth, _ship.GetHeight);
}
}
public int GetStep => (int)(_ship?.EntityShip?.Step ?? 0);
public bool TryMoveObject(MovementDirection direction)
{
if (_ship == null || _ship.EntityShip == null)
{
return false;
}
return _ship.MoveTransport(GetDirectionType(direction));
}
/// <summary>
/// Конвертация из MovementDirection в DirectionType
/// </summary>
/// <param name="direction">MovementDirection</param>
/// <returns>DirectionType</returns>
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.Unknow,
};
}
}

View File

@ -1,9 +1,9 @@
namespace ProjectContainerShip; namespace ProjectContainerShip.MovementStrategy;
/// <summary> /// <summary>
/// Направление перемещения /// Направление перемещения
/// </summary> /// </summary>
public enum DirectionType public enum MovementDirection
{ {
/// <summary> /// <summary>
/// Вверх /// Вверх

View File

@ -0,0 +1,53 @@
namespace ProjectContainerShip.MovementStrategy;
public class ObjectParameters
{
private readonly int _x;
private readonly int _y;
private readonly int _width;
private readonly int _height;
/// <summary>
/// Левая граница
/// </summary>
public int LeftBorder => _x;
/// <summary>
/// Верхняя граница
/// </summary>
public int TopBorder => _y;
/// <summary>
/// Правая граница
/// </summary>
public int RightBorder => _x + _width;
/// <summary>
/// Нижняя граница
/// </summary>
public int DownBorder => _y + _height;
/// <summary>
/// Середина объекта
/// </summary>
public int ObjectMiddleHorizontal => _x + _width / 2;
/// <summary>
/// Середина объекта
/// </summary>
public int ObjectMiddleVertical => _y + _height / 2;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="x">Координата X</param>
/// <param name="y">Координата Y</param>
/// <param name="width">Ширина</param>
/// <param name="height">Высота</param>
public ObjectParameters(int x, int y, int width, int height)
{
_x = x;
_y = y;
_width = width;
_height = height;
}
}

View File

@ -0,0 +1,20 @@
namespace ProjectContainerShip.MovementStrategy;
public enum StrategyStatus
{
/// <summary
/// Все готово к началу
/// </summary
NotInit,
/// <summary
/// Выполняется
/// </summary
InProgress,
/// <summary
/// Завершено
/// </summary
Finish
}