From 46aae7a930c97f39239edbe0f976b874c0bbfbc8 Mon Sep 17 00:00:00 2001 From: selli73 <145283432+selli73@users.noreply.github.com> Date: Wed, 21 Feb 2024 20:05:37 +0400 Subject: [PATCH 1/6] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=20=E2=84=961?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Monorail/Monorail/DirectionType.cs | 31 ++ Monorail/Monorail/DrawningMonorail.cs | 333 ++++++++++++++++++ Monorail/Monorail/EntityMonorail.cs | 54 +++ Monorail/Monorail/Form1.Designer.cs | 39 -- Monorail/Monorail/Form1.cs | 10 - Monorail/Monorail/FormMonorail.Designer.cs | 134 +++++++ Monorail/Monorail/FormMonorail.cs | 100 ++++++ .../{Form1.resx => FormMonorail.resx} | 50 +-- Monorail/Monorail/Monorail.csproj | 15 + Monorail/Monorail/Program.cs | 2 +- .../Monorail/Properties/Resources.Designer.cs | 123 +++++++ Monorail/Monorail/Properties/Resources.resx | 139 ++++++++ Monorail/Monorail/Resources/1.png | Bin 0 -> 8292 bytes Monorail/Monorail/Resources/2.png | Bin 0 -> 8172 bytes Monorail/Monorail/Resources/3.png | Bin 0 -> 8243 bytes Monorail/Monorail/Resources/4.png | Bin 0 -> 8190 bytes .../Resources/rightarrowbutton_99645.png | Bin 0 -> 8190 bytes .../Resources/rightarrowbutton_996451.png | Bin 0 -> 8190 bytes 18 files changed, 955 insertions(+), 75 deletions(-) create mode 100644 Monorail/Monorail/DirectionType.cs create mode 100644 Monorail/Monorail/DrawningMonorail.cs create mode 100644 Monorail/Monorail/EntityMonorail.cs delete mode 100644 Monorail/Monorail/Form1.Designer.cs delete mode 100644 Monorail/Monorail/Form1.cs create mode 100644 Monorail/Monorail/FormMonorail.Designer.cs create mode 100644 Monorail/Monorail/FormMonorail.cs rename Monorail/Monorail/{Form1.resx => FormMonorail.resx} (93%) create mode 100644 Monorail/Monorail/Properties/Resources.Designer.cs create mode 100644 Monorail/Monorail/Properties/Resources.resx create mode 100644 Monorail/Monorail/Resources/1.png create mode 100644 Monorail/Monorail/Resources/2.png create mode 100644 Monorail/Monorail/Resources/3.png create mode 100644 Monorail/Monorail/Resources/4.png create mode 100644 Monorail/Monorail/Resources/rightarrowbutton_99645.png create mode 100644 Monorail/Monorail/Resources/rightarrowbutton_996451.png diff --git a/Monorail/Monorail/DirectionType.cs b/Monorail/Monorail/DirectionType.cs new file mode 100644 index 0000000..3fb9deb --- /dev/null +++ b/Monorail/Monorail/DirectionType.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace monorail; +/// +/// Направление перемещения +/// +public enum DirectionType +{ + /// + /// Вверх + /// + Up = 1, + + /// + /// Вниз + /// + Down = 2, + /// + /// Влево + /// + Left = 3, + /// + /// Вправо + /// + Right = 4 + +} \ No newline at end of file diff --git a/Monorail/Monorail/DrawningMonorail.cs b/Monorail/Monorail/DrawningMonorail.cs new file mode 100644 index 0000000..c3bba62 --- /dev/null +++ b/Monorail/Monorail/DrawningMonorail.cs @@ -0,0 +1,333 @@ + + +namespace monorail; +/// +/// Класс отвечающий за прорисовку и перемещение объекта-сущности +/// +public class DrawningMonorail +{ + /// + /// Класс-сущность (объект) + /// + public EntityMonorail? EntityMonorail { get; private set; } + + /// + /// Ширина окна + /// + + private int? _pictureWidth; + /// + /// Высота окна + /// + private int? _pictureHeight; + + /// + /// Левая координата прорисовки монорельса + /// + private int? _startPosX; + + /// + /// Верхняя координата прорисовки монорельса + /// + private int? _startPosY; + /// + /// Ширина прорисовки монорельса (размер объекта) + /// + private readonly int _drawningMonorailWidth = 95; + /// + /// Высота прорисовки монорельса (размер объекта) + /// + private readonly int _drawingMonorailHeight = 40; + + /// + /// Инициализация свойства + /// + /// Скорость + /// Вес + /// Основной цвет + /// Дополнительный цвет + /// магнитный рельс + /// Вторая кабинка в задней части + + public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool magneticRail, bool secondCabin) + { + EntityMonorail = new EntityMonorail(); + EntityMonorail.Init(speed, weight, bodyColor, additionalColor, magneticRail, secondCabin); + _pictureWidth = null; + _pictureHeight = null; + _startPosX = null; + _startPosY = null; + + } + + /// + /// Установка границ поля + /// + /// Ширина поля + /// Высота поля + /// true - границы заданы, false - проверка не пройдена, нельзя разместить объект в этих размерах + + public bool SetPictureSize(int width, int height) + { + // TODO проверка, что объект "влезает" в размеры поля + // если влезает, сохраняем границы и корректируем позицию объекта, если она была уже установлена + if (_drawningMonorailWidth <= width && _drawingMonorailHeight <= height) + { + _pictureWidth = width; + _pictureHeight = height; + if (_startPosX.HasValue && _startPosY.HasValue) + { + if (_startPosX + _drawningMonorailWidth > _pictureWidth) + { + _startPosX = _pictureWidth - _drawningMonorailWidth; + } + if (_startPosY + _drawingMonorailHeight > _pictureHeight) + { + _startPosY = _pictureHeight - _drawingMonorailHeight; + } + } + return true; + + } + return false; + + + + } + /// + /// Установка позиции + /// + /// Координата X + /// Координата Y + public void SetPosition(int x, int y) + { + if (!_pictureHeight.HasValue || !_pictureWidth.HasValue) + { + return; + } + // TODO если при установке объекта в эти координаты, он будет "выходить" за границы формы + // то надо изменить координаты, чтобы он оставался в этих границах + + // Проверка выхода за границы формы по оси X + if (x < 0) // Если новая позиция находится левее левой границы формы + { + x = 0; // Устанавливаем позицию по оси X равной нулю (левой границе формы) + } + else if (x + _drawningMonorailWidth > _pictureWidth.Value) // Если новая позиция выходит за правую границу формы + { + x = _pictureWidth.Value - _drawningMonorailWidth; // Корректируем позицию по оси X + } + + // Проверка выхода за границы формы по оси Y + if (y < 0) // Если новая позиция выше верхней границы формы + { + y = 0; // Устанавливаем позицию по оси Y равной нулю (верхней границе формы) + } + else if (y + _drawingMonorailHeight > _pictureHeight.Value) // Если новая позиция выходит за нижнюю границу формы + { + y = _pictureHeight.Value - _drawingMonorailHeight; // Корректируем позицию по оси Y + } + + + _startPosX = x; + _startPosY = y; + } + + + /// + /// Изменение направления перемещения + /// + /// Направление + /// true - перемещение выполнено, false - перемещение невозможно + public bool MoveTransport(DirectionType direction) + { + if (EntityMonorail == null || !_startPosX.HasValue || !_startPosY.HasValue) + { + return false; + } + switch (direction) + { + //влево + case DirectionType.Left: + if (_startPosX.Value - EntityMonorail.Step > 0) + { + _startPosX -= (int)EntityMonorail.Step; + } + return true; + //вверх + case DirectionType.Up: + if (_startPosY.Value - EntityMonorail.Step > 0) + { + _startPosY -= (int)EntityMonorail.Step; + } + return true; + // вправо + case DirectionType.Right: + // TODO прописать логику сдвига в право + if (_startPosX.Value + EntityMonorail.Step + _drawningMonorailWidth < _pictureWidth) + { + _startPosX += (int)EntityMonorail.Step; + } + + return true; + //вниз + case DirectionType.Down: + //TODO прописать логику сдвига в вниз + if (_startPosY.Value + EntityMonorail.Step + _drawingMonorailHeight < _pictureHeight) + { + _startPosY += (int)EntityMonorail.Step; + } + return true; + default: + return false; + } + + } + + /// + /// Прорисовка объекта + /// + /// + /// + public void DrawTransport(Graphics g) + { + if (EntityMonorail == null || !_startPosX.HasValue || !_startPosY.HasValue) + { + return; + } + + Pen pen = new(Color.Black); + Brush additionalBrush = new SolidBrush(EntityMonorail.AdditionalColor); + + //магнитная рельса + if (EntityMonorail.MagneticRail) + { + g.FillRectangle(additionalBrush, _startPosX.Value, _startPosY.Value + 40, 90, 3); + } + + //вторая часть монорельса + + if (EntityMonorail.SecondCabin) + { + Point[] points_second_cabin = { + new Point(_startPosX.Value + 85, _startPosY.Value), + new Point(_startPosX.Value + 95, _startPosY.Value + 15), + new Point(_startPosX.Value + 95, _startPosY.Value + 30), + new Point(_startPosX.Value + 85, _startPosY.Value + 30), + new Point(_startPosX.Value + 85, _startPosY.Value + 15), + new Point(_startPosX.Value + 95, _startPosY.Value + 15) + + }; + g.DrawPolygon(pen, points_second_cabin); + g.FillPolygon(additionalBrush, points_second_cabin); + + } + + + //границы Монорельса + Brush br = new SolidBrush(EntityMonorail.BodyColor); + g.DrawRectangle(pen, _startPosX.Value + 5, _startPosY.Value + 15, 80, 15); + Point[] points1 = { + new Point(_startPosX.Value + 15, _startPosY.Value), + new Point(_startPosX.Value + 85, _startPosY.Value), + new Point(_startPosX.Value + 85, _startPosY.Value + 15), + new Point(_startPosX.Value + 5, _startPosY.Value + 15) + }; + g.DrawPolygon(pen, points1); + + //кузов + + g.FillRectangle(br, _startPosX.Value + 6, _startPosY.Value + 16, 79, 14); + + Point[] points2 = { + new Point(_startPosX.Value + 16, _startPosY.Value + 1), + new Point(_startPosX.Value + 84, _startPosY.Value + 1), + new Point(_startPosX.Value + 84, _startPosY.Value + 14), + new Point(_startPosX.Value + 6, _startPosY.Value + 14) + }; + + g.FillPolygon(br, points2); + + //дверь + Brush brWhite = new SolidBrush(Color.White); + g.DrawRectangle(pen, _startPosX.Value + 40, _startPosY.Value + 7, 10, 20); + g.FillRectangle(brWhite, _startPosX.Value + 41, _startPosY.Value + 8, 9, 20); + + //окна + Pen pen1 = new(Color.Blue); + g.DrawRectangle(pen1, _startPosX.Value + 17, _startPosY.Value + 5, 7, 7); + g.DrawRectangle(pen1, _startPosX.Value + 27, _startPosY.Value + 5, 7, 7); + g.DrawRectangle(pen1, _startPosX.Value + 75, _startPosY.Value + 5, 7, 7); + + //держатель + + Brush brBlack = new SolidBrush(Color.Black); + + //1-ый держатель + + Point[] points_cart1 = { + new Point(_startPosX.Value, _startPosY.Value + 35), + new Point(_startPosX.Value + 15, _startPosY.Value + 35), + new Point(_startPosX.Value + 15, _startPosY.Value + 30), + new Point(_startPosX.Value + 5, _startPosY.Value + 30) + }; + g.DrawPolygon(pen, points_cart1); + g.FillPolygon(brBlack, points_cart1); + + //2-ой держатель + + Point[] points_cart2 = { + new Point(_startPosX.Value + 20, _startPosY.Value + 30), + new Point(_startPosX.Value + 25, _startPosY.Value + 35), + new Point(_startPosX.Value + 30, _startPosY.Value + 35), + new Point(_startPosX.Value + 35, _startPosY.Value + 30) + }; + + g.DrawPolygon(pen, points_cart2); + g.FillPolygon(brBlack, points_cart2); + + //3-ий держатель + + Point[] points_cart3 = { + new Point(_startPosX.Value + 55, _startPosY.Value + 30), + new Point(_startPosX.Value + 60, _startPosY.Value + 35), + new Point(_startPosX.Value + 65, _startPosY.Value + 35), + new Point(_startPosX.Value + 70, _startPosY.Value + 30) + }; + g.DrawPolygon(pen, points_cart3); + g.FillPolygon(brBlack, points_cart3); + + //4-ый держатель + + Point[] points_cart4 = { + new Point(_startPosX.Value + 70, _startPosY.Value + 30), + new Point(_startPosX.Value + 75, _startPosY.Value + 35), + new Point(_startPosX.Value + 90, _startPosY.Value + 35), + new Point(_startPosX.Value + 85, _startPosY.Value + 30) + }; + g.DrawPolygon(pen, points_cart4); + g.FillPolygon(brBlack, points_cart4); + + //колеса + + //1-ое колеса + g.DrawEllipse(pen, _startPosX.Value + 15, _startPosY.Value + 30, 10, 10); + g.FillEllipse(brWhite, _startPosX.Value + 15, _startPosY.Value + 30, 10, 10); + + //2-ое колесо + g.DrawEllipse(pen, _startPosX.Value + 30, _startPosY.Value + 30, 10, 10); + g.FillEllipse(brWhite, _startPosX.Value + 30, _startPosY.Value + 30, 10, 10); + + //3-ее колесо + g.DrawEllipse(pen, _startPosX.Value + 50, _startPosY.Value + 30, 10, 10); + g.FillEllipse(brWhite, _startPosX.Value + 50, _startPosY.Value + 30, 10, 10); + + //4-ое колесо + g.DrawEllipse(pen, _startPosX.Value + 65, _startPosY.Value + 30, 10, 10); + g.FillEllipse(brWhite, _startPosX.Value + 65, _startPosY.Value + 30, 10, 10); + + + + + } +} \ No newline at end of file diff --git a/Monorail/Monorail/EntityMonorail.cs b/Monorail/Monorail/EntityMonorail.cs new file mode 100644 index 0000000..1933d50 --- /dev/null +++ b/Monorail/Monorail/EntityMonorail.cs @@ -0,0 +1,54 @@ +namespace monorail; +/// +/// Класс-сущность "Монорельс" +/// +public class EntityMonorail +{ + /// + /// скорость + /// + public int Speed { get; private set; } + /// + /// Вес + /// + public double Weight { get; private set; } + /// + /// основной цвет + /// + public Color BodyColor { get; private set; } + /// + /// дополнительный цвет + /// + public Color AdditionalColor { get; private set; } + /// + /// признак (опция) наличие рельса + /// + public bool MagneticRail { get; private set; } + /// + /// признак (опция) вторая кабинка + /// + public bool SecondCabin { get; private set; } + + /// + /// шаг + /// + public double Step => Speed * 100 / Weight; + /// + /// Инициализация полей объекта-класса монорельса + /// + /// Скорость + /// Вес + /// Основной цвет + /// Дополнительный цвет + /// признак наличие рельса + /// признак вторая кабинка + public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool magneticRail, bool secondCabin) + { + Speed = speed; + Weight = weight; + BodyColor = bodyColor; + AdditionalColor = additionalColor; + MagneticRail = magneticRail; + SecondCabin = secondCabin; + } +} \ No newline at end of file diff --git a/Monorail/Monorail/Form1.Designer.cs b/Monorail/Monorail/Form1.Designer.cs deleted file mode 100644 index bea6503..0000000 --- a/Monorail/Monorail/Form1.Designer.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace Monorail -{ - partial class Form1 - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); - this.Text = "Form1"; - } - - #endregion - } -} \ No newline at end of file diff --git a/Monorail/Monorail/Form1.cs b/Monorail/Monorail/Form1.cs deleted file mode 100644 index 853d9d8..0000000 --- a/Monorail/Monorail/Form1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Monorail -{ - public partial class Form1 : Form - { - public Form1() - { - InitializeComponent(); - } - } -} \ No newline at end of file diff --git a/Monorail/Monorail/FormMonorail.Designer.cs b/Monorail/Monorail/FormMonorail.Designer.cs new file mode 100644 index 0000000..70f1931 --- /dev/null +++ b/Monorail/Monorail/FormMonorail.Designer.cs @@ -0,0 +1,134 @@ +namespace Monorail +{ + partial class FormMonorail + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + pictureBox1Monorail = new PictureBox(); + buttonCreate = new Button(); + buttonLeft = new Button(); + buttonDown = new Button(); + buttonRight = new Button(); + buttonUp = new Button(); + ((System.ComponentModel.ISupportInitialize)pictureBox1Monorail).BeginInit(); + SuspendLayout(); + // + // pictureBox1Monorail + // + pictureBox1Monorail.Dock = DockStyle.Fill; + pictureBox1Monorail.Location = new Point(0, 0); + pictureBox1Monorail.Name = "pictureBox1Monorail"; + pictureBox1Monorail.Size = new Size(755, 393); + pictureBox1Monorail.TabIndex = 0; + pictureBox1Monorail.TabStop = false; + // + // buttonCreate + // + buttonCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreate.Location = new Point(10, 358); + buttonCreate.Name = "buttonCreate"; + buttonCreate.Size = new Size(75, 23); + buttonCreate.TabIndex = 1; + buttonCreate.Text = "создать"; + buttonCreate.UseVisualStyleBackColor = true; + buttonCreate.Click += buttonCreate_Click; + // + // buttonLeft + // + buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonLeft.BackgroundImage = Properties.Resources._2; + buttonLeft.BackgroundImageLayout = ImageLayout.Stretch; + buttonLeft.Location = new Point(625, 346); + buttonLeft.Name = "buttonLeft"; + buttonLeft.Size = new Size(35, 35); + buttonLeft.TabIndex = 2; + buttonLeft.UseVisualStyleBackColor = true; + buttonLeft.Click += buttonMove_Click; + // + // buttonDown + // + buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonDown.BackgroundImage = Properties.Resources._1; + buttonDown.BackgroundImageLayout = ImageLayout.Stretch; + buttonDown.Location = new Point(666, 346); + buttonDown.Name = "buttonDown"; + buttonDown.Size = new Size(35, 35); + buttonDown.TabIndex = 3; + buttonDown.UseVisualStyleBackColor = true; + buttonDown.Click += buttonMove_Click; + // + // buttonRight + // + buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonRight.BackgroundImage = Properties.Resources._4; + buttonRight.BackgroundImageLayout = ImageLayout.Stretch; + buttonRight.Location = new Point(707, 346); + buttonRight.Name = "buttonRight"; + buttonRight.Size = new Size(35, 35); + buttonRight.TabIndex = 4; + buttonRight.UseVisualStyleBackColor = true; + buttonRight.Click += buttonMove_Click; + // + // buttonUp + // + buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonUp.BackgroundImage = Properties.Resources._3; + buttonUp.BackgroundImageLayout = ImageLayout.Stretch; + buttonUp.Location = new Point(666, 305); + buttonUp.Name = "buttonUp"; + buttonUp.Size = new Size(35, 35); + buttonUp.TabIndex = 5; + buttonUp.UseVisualStyleBackColor = true; + buttonUp.Click += buttonMove_Click; + // + // FormMonorail + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(755, 393); + Controls.Add(buttonUp); + Controls.Add(buttonRight); + Controls.Add(buttonDown); + Controls.Add(buttonLeft); + Controls.Add(buttonCreate); + Controls.Add(pictureBox1Monorail); + Name = "FormMonorail"; + Text = "FormMonorail"; + ((System.ComponentModel.ISupportInitialize)pictureBox1Monorail).EndInit(); + ResumeLayout(false); + } + + #endregion + + private PictureBox pictureBox1Monorail; + private Button buttonCreate; + private Button buttonLeft; + private Button buttonDown; + private Button buttonRight; + private Button buttonUp; + } +} \ No newline at end of file diff --git a/Monorail/Monorail/FormMonorail.cs b/Monorail/Monorail/FormMonorail.cs new file mode 100644 index 0000000..aec1d9e --- /dev/null +++ b/Monorail/Monorail/FormMonorail.cs @@ -0,0 +1,100 @@ +using monorail; +namespace Monorail; +/// +/// Форма работы с объектом "Монорельс" +/// +public partial class FormMonorail : Form +{ + /// + /// Поле-объект для прорисовки объекта + /// + private DrawningMonorail? _drawningMonorail; + /// + /// конструктор формы + /// + public FormMonorail() + { + InitializeComponent(); + } + /// + /// Метод прорисовки машины + /// + private void Draw() + { + if (_drawningMonorail == null) + { + return; + } + + Bitmap bmp = new(pictureBox1Monorail.Width, pictureBox1Monorail.Height); + Graphics gr = Graphics.FromImage(bmp); + _drawningMonorail.DrawTransport(gr); + pictureBox1Monorail.Image = bmp; + } + + + private void FormMonorail_Load(object sender, EventArgs e) + { + + } + + /// + /// Обработка нажатия кнопки "Создать" + /// + /// + /// + + private void buttonCreate_Click(object sender, EventArgs e) + { + Random random = new(); + _drawningMonorail = new DrawningMonorail(); + _drawningMonorail.Init(random.Next(100, 300), random.Next(1000, 3000), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), + Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2))); + _drawningMonorail.SetPictureSize(pictureBox1Monorail.Width, pictureBox1Monorail.Height); + _drawningMonorail.SetPosition(random.Next(10, 100), random.Next(10, 100)); + + Bitmap bmp = new(pictureBox1Monorail.Width, pictureBox1Monorail.Height); + Graphics gr = Graphics.FromImage(bmp); + _drawningMonorail.DrawTransport(gr); + pictureBox1Monorail.Image = bmp; + Draw(); + } + + /// + /// Перемещение объекта по форме (нажатие кнопок навигации) + /// + /// + /// + private void buttonMove_Click(object sender, EventArgs e) + { + if (_drawningMonorail == null) + { + return; + } + + string name = ((Button)sender)?.Name ?? string.Empty; + bool result = false; + switch (name) + { + case "buttonUp": + result = _drawningMonorail.MoveTransport(DirectionType.Up); + break; + case "buttonDown": + result = _drawningMonorail.MoveTransport(DirectionType.Down); + break; + case "buttonLeft": + result = _drawningMonorail.MoveTransport(DirectionType.Left); + break; + case "buttonRight": + result = _drawningMonorail.MoveTransport(DirectionType.Right); + break; + } + if (result) + { + Draw(); + } + + } +} diff --git a/Monorail/Monorail/Form1.resx b/Monorail/Monorail/FormMonorail.resx similarity index 93% rename from Monorail/Monorail/Form1.resx rename to Monorail/Monorail/FormMonorail.resx index 1af7de1..af32865 100644 --- a/Monorail/Monorail/Form1.resx +++ b/Monorail/Monorail/FormMonorail.resx @@ -1,17 +1,17 @@  - diff --git a/Monorail/Monorail/Monorail.csproj b/Monorail/Monorail/Monorail.csproj index e1a0735..244387d 100644 --- a/Monorail/Monorail/Monorail.csproj +++ b/Monorail/Monorail/Monorail.csproj @@ -8,4 +8,19 @@ enable + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + \ No newline at end of file diff --git a/Monorail/Monorail/Program.cs b/Monorail/Monorail/Program.cs index 6337e19..be64774 100644 --- a/Monorail/Monorail/Program.cs +++ b/Monorail/Monorail/Program.cs @@ -11,7 +11,7 @@ namespace Monorail // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - Application.Run(new Form1()); + Application.Run(new FormMonorail()); } } } \ No newline at end of file diff --git a/Monorail/Monorail/Properties/Resources.Designer.cs b/Monorail/Monorail/Properties/Resources.Designer.cs new file mode 100644 index 0000000..473ec25 --- /dev/null +++ b/Monorail/Monorail/Properties/Resources.Designer.cs @@ -0,0 +1,123 @@ +//------------------------------------------------------------------------------ +// +// Этот код создан программой. +// Исполняемая версия:4.0.30319.42000 +// +// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае +// повторной генерации кода. +// +//------------------------------------------------------------------------------ + +namespace Monorail.Properties { + using System; + + + /// + /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. + /// + // Этот класс создан автоматически классом StronglyTypedResourceBuilder + // с помощью такого средства, как ResGen или Visual Studio. + // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen + // с параметром /str или перестройте свой проект VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Monorail.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Перезаписывает свойство CurrentUICulture текущего потока для всех + /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Поиск локализованного ресурса типа System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap _1 { + get { + object obj = ResourceManager.GetObject("1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap _2 { + get { + object obj = ResourceManager.GetObject("2", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap _3 { + get { + object obj = ResourceManager.GetObject("3", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap _4 { + get { + object obj = ResourceManager.GetObject("4", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rightarrowbutton_99645 { + get { + object obj = ResourceManager.GetObject("rightarrowbutton_99645", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rightarrowbutton_996451 { + get { + object obj = ResourceManager.GetObject("rightarrowbutton_996451", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Monorail/Monorail/Properties/Resources.resx b/Monorail/Monorail/Properties/Resources.resx new file mode 100644 index 0000000..ce92c6b --- /dev/null +++ b/Monorail/Monorail/Properties/Resources.resx @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\rightarrowbutton_99645.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\rightarrowbutton_996451.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\3.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Monorail/Monorail/Resources/1.png b/Monorail/Monorail/Resources/1.png new file mode 100644 index 0000000000000000000000000000000000000000..dba207a6afe4760b8558c0da51dd94e09ff07cb1 GIT binary patch literal 8292 zcmZ{J1yoes`}NE)z%bO%-QC^Y9fG7tNr^NHgMbW;G}7H5A|VI}B1(5FB^{C?AP5M; zcait~eZT(~cb#?bbDy)Hz4v*}U2A6UJlEG%!-Z4AK_C#WhPtu=2m}E_2ndD-Tsq5` z`+y7B+dxebR6Rny4ctH-6?7Cppf?HFmp14i5E@8d`>qO*|E~jjlfL1BK>llhL0~Wl z4Ge<(e+DoGzQzBo1sHBD{LkZt7QpB%k6U)}!!1HgaB?Ro(-H*&!FKhgln-^?xSKe_RpoH+u>!@NW#@|I?gXiCY7=&Ad_nmj~j5Hn9${ zUOzU_H3UH^cofZCe4~={U%l@cUs&1yakV-!^e!vL|GusSBQ~+1o?BdH=k(smQg7`G zpL;TxU^mg$9tj-@|xpK!J9#us1Urn~Ah?K~80`AS`Hs&x9A;jH9-%`z>pLFZ$ymS`^^U#>r3EJFS)kaI z*fGSUN%vgb)k=2%`gV3-XWwgtZ}X?g1Z(r=<$mxt-yiOt%s89gQN`B|3M`t>-5vV=?8SKIGB`*TX8wlUw%$lK#CkdZqLS<>}{j=~OH_e3g;K6HAD$r_KPPgPwcE#Z|f zLn)azJQ6BfM)f)wpm!uNe_Xg}VT@#A3GQ5p?`}Y-wG&tKf+o$>VmykpQzel4KhBTX zf?wElW-m(OmG?55HHj`r;Y5=8XwqCA(`1Tskq)-5{VJgjW7tbk}Tr%(t=HJuA1p&yp{Wy z@~0S-7f1hcnUu^t4R^XbTa6)rAYZO6@42eIgF^!IxgnzFj+KwHcir1%zI#bgQQeh# zvjL@I&xqt&==x!~@O`OhRXeu>D#0-MkIoOc+u9$MdFtt@nk!~cUL_|q8Y*8I@+4+O z4aj(qytmB9kQzyn4JP$lNH6M6@je!zkVNSG*3lX>*EIJ?o@b9@b`T`JK zxILyhOX2ISkYl0+N8g>S<|@2V!~8-lLbG;U&(Y;?k2aE&KkB6TyaLZLDu|e8j~R}5 zn-tR!&g@tStFBU9(^SmL`1H4xljFWHoi8U`ZOJE1o?=}#3f?tl@Lv)6P9&^Vr2e7j zMYr@ByZI7{PBLOd=jCqO95-cj&z&W|C6=w!{5}h&p5kEQrt~k&d|V<=K{_RMt5QbP zKO9pMQu1|0{b2?q47l5<2m`|%zN1k&xCu{qWbBhWcCQkeF)AfP>3^7Xv-)SST$8e> z#pXIazf`_^Pq$#4_~_%h$!TH9iK1{e=LBDhdr-@}JQL@=v*$d0T276>#VPf`*c%_O z$=QE8((7GaB*g9dv1KJT+|fx)82g?9;ldf#%D}R6*b>1X?lZm@D(0>!%;8?l;HUW` zQd)V)S-|p+^{y~8!)k5lce3D9M|yOEbc%(sf}yvDPPtUwx4Y}o3oKUtXmL@OGogusj!%YJENjao!IztS8Mn|*fy_Ha`KT-2odQ_tSXyb z+U1|7#9drrDGJw(i;tx*PtYxscjZWbwnmh(71rkj4cZg7aON;;1|$Hq)=}ijIThzK1P$osk2IXtHO5 zFJweg{5Aa=I@d>-Y(gkpF|W7(%_j*#Xb%0fgt$zZR8qJS+@P*;4VpQ`aq$t+Fqc&W z_QKBK)^fwePmz$f^TSwW&fIzz0H)`zl+jIoIAM3KH_@2!VRz4zS{>1V#Wuj4-$zcr z8m-$|A*iA&L#>)<#D~c?h$D!B0u%LO45iW1qvg$t-;dy0j8cM4h{ktd3C#t0fE4Bp z#ceRMQ3+)0GS3YiURLKGY=^XB-1nS_WtIV{YHwlfrO|?z@-95*a16)bbi)eIa&_G0 zYKL)%T7u3yxy0cQwPLTBJaA<*LMy&45>ovNRHBZmJBga2Ux+?vJ|5nS%NU+?;fPl; z{U!;01QRQ^SvKB#c}JQYlj(J7l2+t#cckC}m7=Ig{c~|@8;mQhj1fmR`O$zb7eS1r z=d2V>A*ONx%xGE!b+eWohwQtNrfX?~PF%Iv1ohjLE2uF0O~xtlW|K8Ei8HPc(fdKv ziFIFk0`Oa@=z2r!FF3F8@zm!QV4}ROZV-wWb)?+JeS3CYC!Z+K_-RW(oE5=NYy6qh z4$B6h)YzO@j|aYFve8%^sDXXOcLI;vUBsM#xNdF1$c{ud3Y!DPX-vOJKHSq=%Yd$L zWD(l6;J9iylL&d~{7~8?6k}ECED-`DR7);7%!ae0BkVLN6{ixus94K!psWR&`iUc` zIyAu0dpXe=Cv&m*%gS*2uwH_CUBigwKRN2)Fn()z$W-LG{3o~psPI^2tfhqK(|fZd z2+aPDWYJWp4cR9xIDH9uW17}()ael;I${FyXBu*LA9@U6bWRD2_T|=chX5jyuC!D9-a&Gp4ltOGUwR#4 z#Fu~=$672wUu6r@iRGb`{vnaZt0&YNVCBRj*DnQTNC_NEgvY$%ZK5Onr)#2W~RQKVsBT<5()d>Fc)8x+r+CX`+ec z?Vcc>nX*|RSquTjW?GfYm4goidu-^4ZlfqUoKu|EcrFeU`L{ETHw#6RX|}4P!t@e7S3fP^8WO5ZnRa zIl1sTpljD;@^JakgRcWeH|PR|nclF4-W55m4M!o$1rm~kR|QYgUiPxu7zZg ztu(#X06Qf~P?|w)WhseEK*CreqA9+r_CQn-#|sSc7m66AI?WX4RS|xM>umsE8Z0H4FJeXI@`;0&wpzm%9jL-HaIhcTC zm3o&u{*(Ew7P4$$CKjo{?xX^kaD`H)O@rDhPW0v_%M zm8^QyTT#6Z0n!xqN};|hn4CaeA(dA%)u<8BawXsOBc8lUV0$9#!i)Xf2@NxeQF!)L zecavNBs2 z7L}%oC2Rb{Bt`v@R@yj}7$vLQODSy-1_WR3W|5m~!sYWPsg(}Z2@F8LnI&l3nN$E@ z-Ysj6|A1&j4*t%4_6P`8iw3Nemubc*rMv)wv00q9Fao(e}0=AcK6JW?`w~gM8y?p7k=k#3d^Lz-YA;6o;$nYN&5v+y-P&+kM znie!FTBYm?JLzV33mupq?ghN63}I^$-0Dn}N1gSADocl=hCxVi#A`lY4NAlHb>5WV z`*s`#`#IkPwlcN+UvQ!7I7F(e$>4AV&R5;&+uHYld4xq;En=kK+%yL*Ki&-q}+CzOcXQFW) zDgJ12Y5JDI(ap9PG?3~>tsdAJ6@dOb z_H^!*gWYZ`i+Wg|R_ltujA;Bh`C)w`hC=$&&iB*_SZfPp0W@a%k2A$&@$U8R_x)^Q zQS1!Gie?enTk_>Vj8$nLS3S7IXAu^2nDMqK{m*be{w!^QUi}0@=pgK^%39!X z|Hu=eB#=hl=LvGDRSH+%^SR{goTsq-GTke$9kPul!N|M=BqZsiB0>LP*FyMTB7?ma6XyPi_zC8Y;e@mY#G zFu1j}oT1r|<8wD;7+D>Z5{K!el~>9cI13qfUi8uNV@pI52;cvJ*wK}CMBTBfWmRO| za}H~v8>Mi1M|ANAJdv+qB zWC-P!=`UoIbqMSH*EeQI>qOz(#_rOvccL{h; z6tETC6ld)I&;%2j96s53b{X~@XEm^WwhJhrh(glDLtYq8cYalD;hPD7b(B<7LVgv= zxUrCLw=J{4UbHYoHGPI%#>VWez;X&O37GuEn3fI74}?TTUwp?NaU4hEHj?Bh87e-b zppzny5ZTrupbu0csMBM3)~9BrtUH7YOK98siKx?~xlBojO(2lu(7@RTE6RlJ^_F`K zeqos*%V{HM7vP5oTzF6aK{7`LiP2LQW@VFF2t4**^KTGsyLv( zjeSIpZq9&=(2*Q>?JB02pvIbUmMRbaVmVukK%!{RXvFZDo=HhuFp=}_%P$9y^!%7% z7$XayEUXp42*z|C*;F;Q=WiiucfTmAZ)<#|3|Px5a~t~6AN36Q=2SZqj~%ka zvyEL=)v@v}lc2#bql%JpPlws|6`DA?)HvIOOKw!Um&jyD+p<^0DJW1-#HFpzCEl>M zcn01tjgIZX?sFA}!}u_A`sjp7PyqK3*M>=)jzak@l<%9CVb+@q;>Z<8R9SdK#t0D} zzZ;%`K(}LndxjI0(3{lbw9_mXn8aZ_`97Hk;@MFpHx7xeYir({ro?D0^3!CcQB15J zzsLORK_M16)8U8L30a$?V@t=vui8_MJ4AGKxu{WvJ$(!EtXtItx@dtvYjx zhd<$YJ@_;LNzvIGHPV4uU*cZ-`C;t!RO+BrybDfU?68kK!_a3W!AqRcaHUF9ewdvd;e^NUt2_h+N?M8CBPvY!gx774v9^EB-xYgb=YS>=TM*nllG)nl`qp>~PZ%{5O zVD$)Vlh%5xG`RSIocz4ID&0C!Yzu5v1hASrMF{(-N^8NAB%)~^eooD3LMI)HF zgZ;=$Ll!#5!VHgVEmKUtu8U9r3;A9#w)@y+qCILJ zrPsXj^hQ_MQ6Ko;(b9b~`X$IrSp49O`d5h9z$EkYi@uBsb!OxHcgZR5a+-Axomo#d zTjAWJIDH`jA0qmBk3h@n;8AO4)mhV&>*$53I*PJS9rITxBPB(xM-ki`8W64MmPXd! zOM&FNr|R-*Hu5}t3?9?Dmr5L8&%4++#iAOLMdtw8 zpqAeuowKg6d#PZtjzF)>CETj9S_*@SrS;iVi=OFhLt}9;a z%&OMYBv?uFoiqFxE9>RFxt##~p=bCUDsOTFfsO6cc{`7Ds)k$KR@PQfFK0QDK1EXa z_B?EN^<8_Lf+oQm;8Q?b5Gm(sUybS9BKeE;xM z;9INov{+m2l)%idMp;HC8p1}>kOWpLhd9u9)V8i);hwT419iI=xj$tEc@>fuuK*R; z$I;ht>5m%CXbjrf+&P8{%Bt!b#ae}t9i%=y*g*yp?_hn#T_C$lujKkQq^spI3fcc^;jpimYT-3;VRj(MCj99`DzTf;+V@wBn08t+6j3HXf5JV ztAnkW%Dpa6wYZwQj;oUOUJ6ORTvu3!zCXVX^!MTN5*Sx}@;l_bhLJ75zjYeIvoRN8 zq22v-e0|`XkAkjcZ!;fsxzt?`WvX+IiC2#DJ$hm`_jJG9rFRlYpj+*TFyrkKKxg>k>GgW~?v^u(lW~4Uw4M4F z(dONsu^Rpx5#An*c--pj!sn#&wb>qa3c-UZab8S@PA;Gzhj=iI?S3W;^!)vF%AHT+ zE=G=Z2ydDvuGlU)=VmbZ8E1>n&2A3oO5r*^v)S*c$~!U25uvpSy97Bn_t+ml%HUcv zhD58F;{$J+yf{X}?t7InAZ%h-8y|zvXly@J%KDz*%#a9KHdVao=GMY>>(r<<5^JWm zPJW&40eAVes0n4}KGCH1FQnMjXr{LdjnxdD`+h=lt#Pt9q^-D?JZ8fA$yTMNc>DPl z4_Y`+D$SZG@|&Lp=O@MLMJFG{Hf5I%$b<2%l7Oh?u(~rUl^F zc7TP&6tYVp+M7?Y<8&st?M2Cp2kd__%6mFzKbH^Z5S%V5?EkHq8@>)3XtKdbv?Nkx zG_`q`g5_j4;nmAvVN*L5wtuZMQAGwJji6MtyHtDpC7#jFrl6F$C+MLe_k(a;-xGde zUTg_61{a$|g2sgFDK=Le2$||ZV(T9=GplBL>kMCt$Je1O{T`m7d*kmmBt#O9mV#5m z92eC>>x9gWlLS6R*b1{Ljcg``MWyblQ&J|EH`L`>TTs?r{w8B@A~GNl5O2XA?wi@- zN{Su(9$M|BJe9L+Utp>o&8vo8ciIAZ?`i7pCMBE?X{=E-P^^ELJdV`N@QS;n7-RXV z8Pim# zL#Ta7a%4YNc`$reSbf#ctOpCJDjnIQuKqAEvVei`^DB$D${mvKK^Sw4;FI6PRf%J) z`PySO5DHAfm5v(H=I7$!-2ToYC4AKJY@^Ec%y5$gs-%_!&!7e<@b;TmBk`;3Q}I#V z3|!cc52O+?nq|@%h+-9EnXmwr#LpKgR)$6Umg}5~UX6hmJf$T(`Am8Q#&a=oCe^rNEc|iaWj)-KJmv$RIWu9|e45E!erofU z&O7dF852w4q`#rzSd_~~&?md3prU9#>jfT{w-50M3Ep@uUE@yjg=MDWJZ8iqNZ-C* zY-P;sST!A+SLXZ6_=X!63#qw9-G2$TnBBPWpToU%{WXURB> zOM7`<>-;)+PtyIhLP3Y{$cI1b`&wc@cLK4*+Xq?szBpyZ`IOsydazkP_eBdlyi~n_ zsB*6#x?18*|8eQlH~3-C_k9h?=-K{>5=?D|;mMZKy}h}7m!5*Q?*tLGhSQOF(k`A$ z^xoUP3#sPAnKGwKzps!pS=VsUtAju(79THtJ>8hV26NI?>C8`)&YSjMOUm_f{7p9h z(B(Wl$ayeY6uBhPVDa>6z&kmuxq0`_cu*aLMh2P`q)em$0DwYU3uyuXfbdli z078I&bUxwvfPVn}Of*#i)k7@H_y+j4ioOZ}P?th>VowMF5CDwy%+&Gy|GL2E-RC?Y z(7y^000aUEfB?|{QSd{+3;ds0Jj1z#|9+j*;xYdl)qleO#{N4F@8=@wA8FwKASbwx z{_E}B$^VM^*A(z1|6tC;|Hhu%`zwDg{m1S3=pWAWkw4(`5Pbb_|9>X?r}G^AhXMQt zc|rIez~3SK_=V_sPA+)<=>9ht9{i_V%olIwTn>N#M;cG^r{@Cpk1if|u~O$thR0u| z;!o6hp7Fcj!q{JX_`nMr7nKW@3%T>~Kd}Elr58@{RDUaYF)fxsbRpaFNV& z^}jrzK!ULaJnNaiiGe8q%qXII-QzAgy{M|Cdvxae#^xz@XrMVSA@rt!3>O*g6+^G2 zr=62)d*6C$(*ms(h=J_t?irtc&%H6bObUWqL{$#YHpV+#r63ftdDykP^a7O;@;sYV{`OLM~_$KIB)-D7>^SIQ}D!mJZ}$A{N6rKY_9aYSad|Fi6I z+eO#cslgSm9FG~k~d&~$wxS7~78xQIx=P`|?q?cdElI~(jb%=6QwJuSp*qxJVz`INvz@F39fM=jpp5x3fJ?xV7|w*h3eXe`iK!d!HVt2nb%U~DZ%1nsAiaI+#pU7Y z224Jq`+Y!H9N`eAgXS~FBswW)U|}iCU`_hDG*`Lgibg?}^^^?dx@d+01(}+WIyUDp zLnP|t`+=i2Ht~j8hP3k9Y|R#E5vArpnYfD9puf@cjM0B+%Iml@4-;HgE1e{>=C^#pf z$;}OtZqg&J3U0m@0xL~2eG?pm3dMB!=#|edHt3N!`=2uR%}4uQ2SRM`&U9XrU%#aq zG9iqJ93pz4UaEjVTsAxS?(~XKsYC?vNyvJ&^xeRo3vtr($%F97N7m6yGo892SS|$G z#(|XQRsWY@F&>vg1s^XF47`lXKmU${%BA#P`32*!V-O;Ve#87I&)ZIxMR~r$+b8SE z?eH+a2d=&*#hFV=zu&A%Qs_UfH%)?yY|niwAJOYOav)LVW%Imt%w=zTw13dU`echg zEl>f*yIs;NgUELCO<#W5CJ-#6GkbY|*{e(Q#O>@dlRl^6NNxn#n8}DoRn8+V&4{e# z^vpcp>OET+!)4D0sxQc$+Tx4Rgs#s=!s^LhWu2Z7ckQK7+Y+RVjz+X|1!7>l`y1w9 zH4yYA?I8biSen5$Up(&iNUCrAuqq3Wojo->WNqB{L-x#)PAErhqSs0N`>NkAM!hFo zC*vFS(madnQA&bRqs)fE%%c@MXno{NoJblkvuxUB03BS4B-`z4`}V5}sk%Y0I1Om> z88DMiim91+P^dM$&v3t|hg3U@FRUp1RK{_M2~jsvD54q=w@yEy$xXHl8>Ql*;mAU~cI)@^eLxY>T~jkMVVaRzuhMy&AR@+Vj_>})*`nLkAFjN&YSh#raQ1E1%U1|LaeOV%wD5U|(t##RCo?}YgrmTz z-{@xEeJw=*lp&@vk0^6k;z*%G^nST&Jkd)Lu78FpR_eGOrj&`J&MI(be``3-q+Q(W6`pk2*U(@@GI6to$hnYCejzgM1YtH|~5* zFy>E#lyR3zYB<+uMk2-KrV6NDv%ZIY7ndP#&Z7iGFCHoRr`>=35r}FpP$EZ{(V?Oz zW|v<85s(``XUdu~3zcCRYT(RC;+u;zOhvL9*)yt8+*bw-%%I^t!kOVOxg*y6dP^f&f}iddxu`s<;K4_h&{? z6P3t` zsV7s^qZJ1|a#LB`Jrp)>7hL@T+W%gPB*`))?nZRN;^!UYk5VM1|0|B|zOrmg;}Nz-uY>>8kLMQ~FkR zF(Gd<(Ehv`Vzwry!UJq+t=p;+3?FfP<-?LPerl2+D0h>m1k2{BSH5}sX{yKok zaPWGPLwbi(Zm#(Caxnids7fg81!&VWYSJ%4(lrzC@U1tMV$@3kd(XSb#RujjMpvke zL!~G;O_Yxwa6^Q05w~r@{&syfb~rTF-y1gLRO*2K8^~Zi%N4vw}|qF z6CmHFxafTp0cvn<$YvZ89Ue(zE*riCOE0X8JqCRPXafggFgHONYpQdNyx4%?_1eIn z#GiTF2O+IZ(ygLG{rIfi1o`7fS-Se`KZjfe)#JUyNCO&1W8S65M?KF@0DCr{t3Yua^3WpkBZkvY# zD^3*=P=7ttE%clC4Ac9s(+P4RZBnc>9H2VeasBS=oKXr#1gtc3j#t69uH-hUz1*J0 zzc`k20KARE`QPGyEZTRDvb*F0hB*&)r=GHTE3|Z85*f#{=K8>ILA^c&7F$Ruo|wteE=p87DDzcQR!0XR(JZAmpgWst|G zyeEfi>+!=dzXj4YWj-PCA?y(2?g0Tm-qSl^BG;!W{=5TZG$|l*y8`~ynE!;t=tcnI z6QyC?K&HzXej<4Q-fO#X_V*GXImduyQ!>R5OSnf$HZ6G{JDje$LnON-ut(E$#n=vLiO@l+~=jvw4J zHZ0q=tbEGew~^GNninGJR@uA}49O`u<+olS!CX~})e#f}!6eLN?)=mY5-x0gxhndz zvdR;kTM~i6Ed>b|82>O*WA(XI5Q@PpQQ^=|JA}q z&T~!mtMIjFPt4d;x^~(Nclws^Yl6(a-sHqKLT$6YAI2Yk?Mvyc&$j3a8ZBj(4?joW3nZfR!(y8rYT9Y`Q#UX0E2oCFhp#D1)vr-@A8k~cLieL7?E8*$ zm2^P%Rw4I9-$i}zS2Af`(?HATLmuUb>f2E@-br&LHDH(aJB{ti3`b_PMc^rCy?69} z6WPHQ%tc^n?-N$*XZQ3qBP6%AQL)|EJ?iKNREy%V>41aX>!Lm`%I8)ML0{j`Kk<=0 z+Kn~@oebEA7dJnJUa3qr1R_ZzVi@T#C*f?|=i%neI$Ea95oBhXeDN ztn1#Zre5Gq9EIP}6Ii>8nQK*jPX|a)1SY%(zq#<7w=LLIkaZvq;w{AciP3;Hu{13} zusk+f+9;R%gWyc~F^3+Oq6qv!Vrt;p86SqnW?LI@H6N@M;8+K5+|mK?^%E+fIO6WM zz6CwG)o<){-zd(zl@gSDLV8H8LcMv&)2@2I*NyWkrxupA2&^SBR=ZfS3rP#=fdieH z9^f1G!4R}}7`0u)D6Ms}&X^napdBy%q+8HKW|ab|-HK0*P*UWSuX)BSjdJcgI8cKz zscx~>`2`fd9c2hw6Zd+T^)Z%JxwuP0k!0(|Wftq?(p=>*{6gJjB%c)VGMtYLn@a~I zCF1iF=}fR2iO(XUqxQW9eGS?5ihWSW=(fOo3y9qt&(oQ*(D7Mgepm^as zdbxF18!bcpM9SpNg>P!TPz!2@11Xs|9TEicSZhTUNosp>$s$cIu@$oTU7&Ca*mSA% zy6X9UtPTqACmNGik;HGsim@mQhkThlfoDXbB(<##b{doS6@Hd z#f$`1`0ZAoFBz;)XO)~xD27b~IB^G_;y3lkGnIB;U>|+*T8gI)&axJi4W6>F+5&p) zs`>R~e8=MwG$Rr{lQkx5TnL`y1?v~*=S{a!+>;+?1g%tV$x|0sv@U4LW2>g?cV4?B zYJ&Xv#eR7Qbxrn?U0!S)rB4C77~AX|1a*DkPVawOD)i@<>^KAmRh^hw+OX?yYoUl1 zc{e+`PruqTv6Jm+q1YCAm0~oxr0-R?>d0ar0_fBN8ESI{M+$JDn<<1cJj#gAA%tuR z_RUXvqFAWs!13YW6vE3M3@c>}lqBK+^|l8+7$08eVrSX!seqRl9Q(EE=om+XFD?0yCH~+Nw zK9;f0B~bXo>Cm%H<9hqA=-bGTD&+whZ;>Nww8f61J?u*hKX87+hpZ0HKj<<%E-`N< zqHIoC0?cMC&HG>8%yFUS7?Ukh8q3Xn-Qvc+g!uL@`OvITlk9JtPuS5(GR z&JH;)R$Gm^owQ@O7(V1x{HmxV2#oRjsiY>RiB6nJzzKyV+$NlG5npj@S?5;~!=GP- zv)sr*%M(#S_pA8hOB_=pPBu&`vd4CtuVC^D(4>be#4_>6`=&1sGjBKOp-3Qa$F$_d znj2;-Y98U+$I!4cu)J8S@No)ZqaNxr_s%c9OHAly?uvR({284du+f-0&rzJXo@skr&{RhBXc3jSR^VgP3D(-(5|O2? z(Z*OI~4)l4P|z8Xc%np5 zN(P2qgVx+N3ozRTB%fDl)ik-9@f_vw$eCn|uw&oxHrp&uuzye zJn{qJWitVv$_Xo0g<5rO1~-uWOZYd%ThPYaWb|0io%p7(B+I8@^sdBu77urH*z5Jn z;9F_tB;tfBp`8(|#?0hTElJ-CKca5mgM-)g2Yg#i-8RI9(i2xQ0F&I#o5)9!;}{xZ zSPF?OZ+l?Z+D(O5-NZpo_8q}V)Ep7i4*TDUS}j6E_BpsB5IU$nb%!wRccF`S`3X6H z;a{6`Ub(S#xK0QX=ipbb2yE%K;(mvD_IVVa8Z<-fh^KuMTIZdj9j;zMBtbLeo(}kU zm&-v(vE%qt?eu1_iYN8l0c5I(JE)E8$=l@S)=@s7GlyMU-gknkW();rS1%h}@m3k- zeRGS%=~*Ark!?8*;LTxkh9$I7;Smphn@lLFjjE)lpFQMOEKQY|hgsju<7xMUOeVfF zK1@|@6;tdAe<#JZ%!goSgK$5j*y?VvPkxuSb)&p z2$rhd_2bJPGZXBFQA*Qzj^oc8Ooisw>kU`!i505~Ke$Oa{ni;(g`EfwVJ>fNO@tZe?oFgl8h3u!u@5NSegb z2@t6ISaM|N8fs-DBX~v2qDM^d?Q(#3DTrL2z~@?so~(6k3#gOnNO@%lV#gh`3hh zLXoni?y_PJ(t4YIU+Xc}Ggx``_46*#IHYr->cO-f!@f3;!$+7Mp+c;ofRmSz1<*ZT zp00&AjbHIW^^4xJDY1uLA92!OJi3$PXw84Bw@oimsZU8hMD-tx83A7r9rICNdSLLv zbR%S~0J6Em#67oOZv9tSDG05nN-2u|a86MLlSPCcQP-XUXurF>G9@K;(?L^(5 z@>%W3WvGBBppO=#r(W?#L)^_!>A;-bx~O!>Q{G{0VzK$4rVP^PptzL9kDd_5xejp< zZkD;vZA=R@>M*p{2CSk$aYnM? ziIl!KCLL(C!5vG0;tqZObV&3d5Kz(BT1!0?UF@BM3uSswt}+B~CFwdObJ3P=StzEC&OaETD;S~mEm&_1;DWCDdgH$vF}Qo? zk|8eLvM3ddzE9ILO2LxEp410jk{wiq`vlZ-SE*gf?^_2e>uX|+IXle8T5y1kCyOOI z(IqFHF5$qn(mK#U*|6q3nLYOmYkN+9CoABsM>)A&pXaJxdteZ=B)4#LlqK}DK*L)W zH5nKGk_O}=dVW?looq?pEJb=v1JUf`i_=O4P6i@gqKHNv=9B%}BD?8Lq$rpJa;)3u z&sJ>8U-7VJ9x*XlS?;;M2_~i^3pky8!Cix??+TEiH?)gzvi z#(Ix>;gssE`>IN2ToTcQ+OCeB51Cosl=C_lqMFuMuJm&k-{hUPvo9D&SrLzN$Dw&8 zka&dbia}IXPr!+7G37`|r&MkTKwmJI!S$hl^|Q|@M43YvVkn5DW24E%fMhXtw8XBq zBgX*X+H#K!MogmR&wzN`kTq&%qJkSI9^|i+3Wbr^tvSWDoj!F{RwE|BhG=ipoC)3? zMrw6MHJH0760S`r6{B5OZISZ=oQe;_sjRRD=8MA-WjDn*5DuzVqG-zD z>xJ(=_1W&f;Fkc2l*U~9%zhj!?#*wd87%bT7EGeDWc5Zv>R7D8G{ttBtO;LnW=12I zy_5qlo5JWNk+R2&+*lZVyUJ+V7CdN*Yx$Ppl=4)1`Q)p)|AP1DL*#pB`rN`s+7g%_ zJ+GL`7XdrBom-HE9ENY|55GLnr28N>_*9&hE_<>{8?+0%gX8N3-j< zvQwW%a4(}ePJnyM&EM!}(iuwi7r)1A6`!5#$K_6HReg(jYP{8$0VpZ>e|DY>CC!F(I5hdSe>9lpo?>uJkKy zW#YAaHnZF}pL_5GQ<}iFk<-`iHLqSjVtOj|(8SZq_R~rqk;vI<{1!cIFkjt|^{z9|yZ5u7{k;1Oti>S=rlE+7br%Z&0N^SsLA3w?5DJ0-7-*=Ew)afk zs1Km4mZB`6Y>;{lwE^48sLKEVl`+`o<`4h?4FFTqmPf_^;{soYuXRA6|5!i(5C}j6 z0zm)ALZyJW{F_>o!nK9}eqGC=IRBf}KjnXG|FaI|=eFwK*1-QEj&|GnueWO_|10M| zj(`&RmvdeIxAxlJ-}cw7Z`@vIZ#1tnH{|OQ6#g6k=dd@yYx0c(_=b5a_z&T43YEWY zdOed{otwV@jfNuMtlRUV%v`ra-T!Tk61j=o(*Es>qTN2J>qmy--;Uy@>Uz$oZ^5mx zzxGgtw>ECUZI|12*X1{~|9_;nPEb;R0g8FMP!9idT`Qn26z#U%?G|5C!6^Q}!?|s7Yv6X6*WLf>fZWiAmr<%$ zFSIls0l<`8vic70p$VBqO`YFn7JhGEE)MqBzmD)W)(~aDCgIn77FFCfzIiy;RT1xI zD2WcFm4BKzdNKb=n-2@bsvA)Fb+$I#LKqiv-z2Vmf2A6s&TjtZ``L2oLmU~OnyvFx zYK)-nEP=hW$3&!o&o}TClaD@Fqe-mYy`!Ab{6y-cQU{Y|mtg9+$_7fl%A3wMsW$ES zV`6|uu=U_e51AQvq(Plh&M9(ftk=uFgZP&MT?<9@$ME6>+%FUQUWG+vMN+GOPA(qLtd%vcj=d@~d`Zq_zs!8kXD2Pwzf|ZvQ`q#; zm+73~reRyoKJFb4my}Ph504uY(?SeOOTG6}DuuAiXd?!NHZ5D(HU8|?A}3wx^8`5v`BwD|6%piU+9#BsZIJ+rCOP-bo@&vw?+>J>Wc z5QFd63$v@*X=dC|!-n1P(o!y|!=D3B9($Wcs8OrM#*h4N+8$q!m@J;(!T)s0aYYW} zZ|M6F(RNuW%(4-OhR?dN!w^s8jr%4nVX-FQa2($*#v)Wn2YT~nygY;q)pytHYFq9glS(EXn>GBEG;ckdHP#o=CYkb@nUk@(>; zNkPbNIM%a9TA|#J4_5o|Wk_A8bKG)Tb9nOPVJ)S`#s#mRIRCE3Fn(fCTevKKIx&B& zgrwc#$3Kuyf>M6%=_v>(_@j@t&WLq5Glx@4P^+LI-^WwY@+s$ZWj=YKX!daQdB-zt zg#)`Qmg49Pw_PKeyidUoxS_bvPbq^jtxX`ybviG2$>WhjG7)j?>=O3(7F8G=|oczfF4uM=xHLw z!}tT>B4Mzxz@4P-i9ePY3aLY37Za}>qX@!znY~Fl;`5h}-Z{3X9Gckp&^u|1UFyw? zOk=+~GLgn$;H-?vkxlb-CkGLjtJqE|n@tmvm?BHF$T^bYocVwCsaU2-(hpKb2Vh4S z_1ZU1W(#LcwDNzaI3%a3qzED-6Vt&RRh=DdVXLapR>Wp=uh$B=XSq8l@w$FVql1!eOB*MulfGe9-oT z&ce{pwLJjc-r&3yv^m-#Q3eY8y)8l$JRGkP!#;`bY(YJ&#sXlpnXwcR8k`7k!{UD+ zE}CtHORY^XOvKs+Y_q};kty?b_Hy`OO@!B@Ki8OFCiZE?FG->Lix;6r?0}Z=5+btW z)3<)A{@x3$0oxOI+cC=Zs5ZW_W3UCg+gsU*7IC&A^yaIC{nXRrYLLSw zRYl^JZ#86zP?b5eK%jZ@5Mohf#BycZOesvC%<*S|7|Y{FSrR0p3rOKjn|+);MEqL} zqsM~rL=){hN4LPf9Q$!Bh+A4Mxz{f8)4mWRVde45Y_WZ#ixD(F{X!PELA_AVBoce< zsUaezWq<5nmPjHcHCmt8hvU5MRy3D=fUY}FfTs>x`CRq9_~G!`a&`PTGh_|qbBoV|glNF4RbROICp3Rs`b0fcEkm2>s}!zVr=k`X_oM&Z zoxzMBG%-iBafZq8ZHvWv>|y1+pV^A&1i2y0m=1itCtp`~2z|b>;yK7KNIJ6H^RB5) zIX44;=@kEFSaHiqXnSnCh|gQ`@t2|9C501&x@GGa?R3^t0bPW#%BuCkz;QZ)wu!lO zHsaZj^um@rMncbGq;WPX0ZsG2^+Yrwiu{?_^GX!o*|v48|D-xyVi$z?Ivolu^8S?D zL^h4Btj2g#G|jKaRh&YX*?7sd*!P8zX-DxFb~uZ?Ye)uch6jS;?%Lv;2==ek?dDUp z6U6Q|{+Rg-XKMORv_^4t^JcD3`wqLt)5L5VA-}#`vbc5r5NWsUH$Hx#iJAN&LaLyX z#Ko~+5S-DTl2%oqxhb+4Eh!9YX|5%N>&**nCVXfMRrugpk_pliv)fbNO#EO=7-gb4@6CDfWbO63+(}FXhYtR? zUxF57pS$3#L{Rg%JdPTOu`T^wU%hfnvxNdB9_Fcl;5*?zT}?=L@a}iXr??bXs66|< z8mfRlX#C2(6iPrgMHKVa)n+of;~g$uUGWGA$Rp8wp#v=d-a#hS!oh=xo7w zymER!`2)Z={zNlLRCTUI#wP_5COkYMv{}hX9bC?_k#|D;9Y1qrRRC$05aCSmnT$R@ z>p0l%thMmrytGfP98=4=uvFimPw}c^8N(U{UdPyYC{rl3Ol}b?nE^y~xO^U419kh= zCtVi<#G?ZkehLe$B&~Y8xiUrU=gH4dk#r_Z9bN27s3dLF71%lX*`ZFi)>wp2cbZU% z?&Xf?v-j`L>o&gn^dbrHgZ5MZfGh3tB>eT+X5{*@NhwkJq!ek}BQ)irAx?h~@}oAGXDIPbY92JNDCwNQ1=#>$GM zyMaG)0lzOUc8wM0)m5^5_OV1S_HrRX@)+m-c+LUddUI6{o#f7QKp(9zRdNq*)bq?R zi&y?=B7<1Ti)PqEtkqO_U*XMj2tFLvJKPfyt>O->OSLuM(ToK(+tEe7jrR25Rl@<% zphG+x5zueD5JQC2vpO2v@NjNLoTSKA_mKPC=cI5os(oUt7R~UhRUnRT2-b7%bKZf4 zGozua@c8r2K%dBX#qK#6j^8}Ic04AqVLjX?oiiaLShP5 z0^!s)=Mn^qb+C*ui1}7U$eL>lI?RvO<|*SZilt?o_h@!Sv$C2krXEV7NDD=ybqkWP z6b|AL6Xe64SZDfh^=64=#}>w<@kf-1hdc8}8alZ<4%nB`!zm3^+toYnSX|PX>w3dZYd z!YS!fOv4N_uW!}qz_yb@yC*pcx6+bYi&)%+FK9>$Na2H&Y5~5-wGi8^<-Fi|^;0r* zswoO(L%6h5?}xmyX76R@ez~w7(HcB?t0f#2lf?%g6=&txcxBq^af{g>!T~Abl#Xzd z`1)E1Ro0J=q6Mz?J7*ic3JU#RBne@lx&ESyT{36xPuTaM-7GeaGN$U^=ct=a@kEwLe>}erEA6nO*|@fAJ>+$WsmPJF9cOGJp57`EhQ#FsQ?+?DsgdmxQ8|xv^$dRO z?}W4IR;&$#sYJ>xgzalkc;K24TAu|}xS0);85tT(Xn4p!Let=qroH!_>jfvfz4vfw zv%aM2M#9@&YyyB?-j?)~02LXqk1@-Ag?qrJ_Dln$>C0 zLH1{&B_{Q!!Rq#lpS~8Qxe`Ce_KNSB#W=@#+)aI0H?OiK>p&<#O4@yIcQrt=7P~^e zFCe?%;iVTN)9c_TtCkUo0W$@Xkma~%*t5l>&1CHAa8DHxrIUvFuLh4C;8mg)*sW8G zfYzLX_kT<$7;@oY)PUvooWTl1Z%LYvpM%36b%wrxDri0r!0tR{DT8&UU_@oSG9Y${ zBcxh@m^I?SpDB8b)C?DtB8(qA4YG(P zdMj6vuHax&Y<;jAAh7BUR#Gc*!>bDwi9XdDw7cFZY&!o`9!YWeERAT7RYerTO?%S< z0b$Dd$pEZb$R5L#qC~U-h;0gMq~-!6HdSOGh>KxZ;a#h?+zYZ`5nL)OZQ}_O%rI@% zXoeJkox=)P2>Htq5P%6A`SoZdO-1QX6NfwxFnl=a>|wKH^lwhiyDbe-#xHwU_;lNX zuB6StaZm4fHT?EEd67*|1)r?*#z!AnD}3*sU?Puv0;13*U+r>>WI-F3BWh;rAfhvV z8p^f81ndvX8>4OJR0g;*0VB1zfp^U!L{XbYyTi(kH%tgo-(N4Wg%ydK->`rc@1!wc znrRr9;?<=lfO&1Rbf^sbl|iZB4U2FBhh@63GT;#lsp81p>5nLFttvCin{*wS;t0_{X@?)o6D#UO&53tA2#q5hXPJO%?D}GLkUCG4MQdee=s@K_ zIun9DZ@&^|EHXr(3=lX?4jv&a*F)vsS=uQrvqTD`MiN<@M{gXZTY~E8>}jW@yFmIh z9$-U)q5^NImYQ}-VICc?nGlq;Nx{oH*)(jJW&s~a3+!fgUJED#h{+h=mw61NF(ELS z@dH(jV#eQ~q;_yE)&p*k6OYAuKOMl--jZu9@`+ z;X{Q{KLY9-LAPOYR5;_GFawjis(PEDk1~iNIXOHw9Jkf`8jk@8lPE%uj^n|+oA;pF z7J%6$Rifq!fzX2XQjZuOWk8!4V-C^p7ax0)nGox>!v?u))vr0++3cObEWm8xbe1gs7flaOyED-(PUe|grNU?nI&bZH;0=H=FQ0x%_&42aAsU)jHKKeBkc$VL zO5O|9D>9Q%Ga{0HI9IXLd#{<5A|5)8)K4A@ z-bY#JS0HHl>1w2;MI;?!EyfL0{So-p6{RA#vnnk`osSg@9?D+N1ps+J;v|AGO3y*S z7QP#}Wr{&x^O4gh2wxcy>(>j#5c?6Zy+e;lpjCk0@>4Q7il-8_>5WSYl_q!Nl2Jy$ z4(foPRu&B%lt9R;yTD(9xTZ_8M07}9nBOPv=A-&pFvfyRqAAZ&!!ZMKJfP)*9cnvY zbh?zTrUU|y({_yWcuIZl4P=sr(OjtEQel;kLYaX9jpTX43@?G7`vaJydH2=N(VI&G z>rpUUJn&2)kM{H6D<)}z!2GP8JCZ@$u5_3LQ2O3y+Gjx%K(u(kD=yv>T0pTGGY};3 z9lWDrf;1jt#Uy~CJyHkoNPSZQfvwJ2vSPgX++;JDr0G`g`eDIlsW*cplo8UP0i4qB z-zRWi#sh$yiVXt>uV2v+vSQAgDqts03$lDdV+NiJj1doI_DCd?rhs>zj#!b1<4EWv zC4+bRy7ds!@nYt-xyqp9@9da)c-RrKSL8vpGt(k;*elOLDXS*0X5eG!sEDbPG@cIf zC4RRpQ{ek~QMTeOgGB_6)vpYEIug7HpTG~%+s&^#ZBD;C~571r_v$$!Y%2s$u$8$3f)H*tA| z*0`Uh)Q~06>kub2!DAiunJRpEiZSkck(Z7sF>~cFnm_AD`AupQPeRb={3=bjqg!P* zB;JVhNi?tS>5_Q5&DZD`kp1DJChA$)>}YfIo1xCPj}dJcIW7-7 z3afe|M55{JsWlRfUB;HA19ElDBO&9gd^90M;JnOcyDGT99d`UrOj~Zi%rO@$kIsosBF_%rRY2Z)04UqdAp4?&NpK3=1O&#Loa=qH0QXazf#O zZ`jTJ11DWgAHIA^U0e139t*eWao(AI#{Pp;=Vh-J_q*@9jfjmK1ncPcuw(2?~ z?BMy+JV_2!b(%Yju!Zq?(E>K>s7s3M@FF93T6v+u%@$XJvH~VI{30dirI5ZP1Z~Fi z^z48UVJlz&nZL(^thR=>k^y5vgbvK<-4yxNV_z}c>OM%IJ@WL#5s~D9xRlP2}}28O@kXlW&56m9lzED z`&=3&4sxwFoVjYt)HHE(tR_s9>{yz%ohr^Ox<-+%?>~hcJuQW!UTX(&f1BLHXR$RM z!C_EcE3?lm-%;}{qP17DyRcW2Y0jzYFHSTKu2HA2p3I<57BiEwS5c0*Q}AH6%}cbL zM$VDl)|vcdYrM_(RrsU6`sAaO`~EWq68RH!@jv`CgNBe&37NW2hIdOUM+uULc(!rn z?-0?Xv&HzRdCf05XfqfpW=uzzAt|XY`y2Hqc58^L&!LG;Ub^r52nJ5q-P`F}1sZqw z-Q<*wHfY0x%}t_DHuQ92!Y$_JP_Ltl>qBtV6c33~F5BB&`nt#pP1Tq)(RNuglcp~o zsQAXZ;BDR&ks18FrN#O~aWC6By;!(2E41~Q>gzF9p&~ZRi-=;l;6g0lr*)zeKBeuc zh~3wCZ+=osz_u|4Ws%f{?q-D&%Q3nA>+Z8j!PN^DHBA|`WRCAn?d~?_uhHOLQCrP? zdocl{Hi6A&jQh^hDPG=Z6LFhGc)H|=>ggMRoNFZSO$X88qZ>ZF&u!_vT3z`RkFgZwtutl&_EX$)-C?3#V=U-ejZq zW*o?uu9s0Bc}1*DM49o_POVGYj(hBCZ;5@lsPh|Y4Gv_@`>ND^=;1zd u=-;&Udn(_gNOyOG(nEK5iIk*-gmgD3DLHgENOy`f2#82`BPjk*;12Tn z{lELa_nv1z=j^lhde>U}eb0H$oHJ4Cs&ZK9BtA=|8aXi`-k&><`4Kj1kwLH{;$RU8N3JoVF3R@J`ny3@OKI^ z{~&swlLwwZy8jJ^0RL$Z>qVHkmqYCTEsY@gGx7lYw=M$qP^tTpA@C2W_!D)XXT(+T zVC=6wMBsysht7k_gWP@iAK3q&(g!C9s=pls@}VId{%5;qKx_!ugWSU@V*gkDf%(tC zzn1p@QvKi@u}6Ua(jt%#sk;wEIDeS>)4#7NVu6492>id3^C0nH;31j!>VJ7auaIW8 z5Uh9ZnyOj=@MCr<0|(E@q}=lMq3N&dC#Sa?6JsqIF|SQjg=sJdc+{NYD*6|WzON3~ zzI|mRiVCEZu}}VVv(~B2jSgbe3oe^nX^MU(h=t5*`exu_ry)><*&=K9*H)D{rlfD< z@$Ympw6GC4@3(h4c#lGy53%J^ubQopp6-*NDCG3miv3fk3t>2iF8!>xh7s*@WiowM z{^Gd2IL^t}ciH`c(3~UI@V$Kgb?D~&sLzW*{5@H!UgG$UVhy?{EC&M8XCnIQmNx#b zULMB$I8zZnglKVtX1a<^e%0E zE|I4cwPB9jk4Oc?Mc%*-0Ki7{vHO9;&ZW-*08(ECn54Fs>G4-@a{`?l)H5O&o(fec zp$o3?(-s11EJY|DfjS)>Rg^h&3QQXgM&p`xVZw_dlLkm4!?x7v`p}r*Xf*kyOlv_@ z8%JyWn@90&75N1dLQk9+Z^DfIbUZ&j3CImNYB=az{iRS|VR}QsE34hvaFF|zN@OR? z&2p1OAUeT0D=~3uOAse*SF+FhTqSdmKSA_P+>oyYz8zL&xTys5c3d)bKc`Q7Z@-%N ztWtWRZq_QzvnyX|K{sjd$*E#qXhUNVLG1C7%7|>-vKD6&f!{l9u}KZG%dUg+B8tf$ zN~fDwQsbuA=}M;4Ihrl6V1>)qp0V2(;{GN#r)2Z!<5V<-TQWH05xvl&0RLVuz6ck7 zYIXr&2$lZCVw7MZTqiU^H|%Bp?bjJF&beSuj2QLBU+AiVc8!dZZn5Qb@*m- z9$x6-8HG%c=o#+0PSo@&12rVs@L@d-FFW0(IG*;fu-hts-@j%{pOBSYJ z&)c5gT^ODmY!#XK17%Vw_rv3p;O)qG+>LKj&Ko-KL2tOj?Dq=xL@XS(Ezx2WTu+K# zk98F9?ou&?8>GC6fu^$w8(vnCgR;}CuREwcCDjJ{)Dt*m>Bf?qNnUd4sos)+`=7ea zV%=<-%_d^JGO+k2bVfD9?CUIfo_qcxaVvdGU68p?) zx7Vmij|$FB=xq3n&Nmv1rVMxVs9Z6NQY!fjFd4AN@1 z-AH5iagdgH)L>K~;`~fyDK3%4N*|J;Mx)C|Dyb9k1j&){m5UWsbvaWf0Xw6>e&t+3 zP%DG3uZzB0m~M6T0!|!*z>7lVy3bJmCm z@k6U0u%4YWL&Yjf;8Hr&X*>R+abYG6r*F#L@fWG=0OY049P-`9e|#Khu4K!ra=Y21 z6X~L~i{6+hbc6*q=5fyV9(c(PbuA;ve;FErgw_W8F}oU&vm&)vRF@im*XrshyGDO5 z5GQU^-GtUjV68Q6c2ZB*W@%oNkMX;r>N$EJ=W;K#E#7*00o?-1uc=FCNfCK&>E|L} zZAl6ajBC$hIpl)m*7n+vhML<}a>Y2mKD^X9e5D7dnFgXy*CZFr7lhWd>xYSEW3-zGgw?9ZanTtUY2FaoRjT#E&)l(JsnVSR zQNjwE>+ETeh^}%$F=e;8+8IZEJudZ4;;)qHUh+Mb?w6V4K1!9}l#azBnzSr|(da#M z5%P*G4pb`bU=1IBIsC*t4aO2vY#B%<5HcU|W=>fw326@?VMu8aNhX5|_%^!XVsQp0 z2gtLnoWFQG*mzqqCpIJ`yrX**DL=a2w&7@pow$V;Z&^zA<~8pt=|cY553N8xR0&|f zfVnXI$qh)m=l38n$Co(DAQNcW_mRQC&&T3*NHncc#9WzQL&otxTM2)YGymqj`1H-n z3&v{nxZa^C5XTVwvn|~XNPVPS++xuo={J{vN^&j5rgbJ`twnxh1GkHSumVOell2T3 zGn;*xx6U9x){Xnsd;OR=ys)Pcy$!u@>=qd`M(SahW?TLdDtJX5QR^}K6e+>FGg;)s zJ!nN!et_uuvQRQ|U^xpjjx_Nb%{H{c%3{PL_!u4IdsSN+zJ_1DkX`oFOVNX>0W zn@796eC-g*bmSUqP5i?WA7&?LF2tTGxh>J;LNqj6FINl9Z!sWNk8yP#xQg27>tJxF z?@~=}CX#-k@IuYk$kSk4!1(()cU6ry|3JFovyrzh2Gg6Y?U{=ek4>kiZBqOi3%!`T zDw-L-PMak#pL=PD8%@bzj0r)~{qVk4@fobzueMJQCblMQWE#5Z{JQI&sZcqKcVf%M zc8KCUs5&{;`pRd5$ytUYLd-%-i0uB4zH38ESk6_iSmbS3DSKCObKRb!3a7mRdfv#A z361p_*q5TS%4)9D%ZxR*z?1r&ldQrT=hRmbvFTa{|KJqGZ)%%L8DC;g<~`cO4>xWe z`(a4#)A`D|-QowfVl@4dbFpN(CR{%J8GQnx16X>0JZE-vmz)gdEn@QR0h?D%4iCFe z6Od!PVCjN)_CR_T?K5temm~amN%nblB(<}m==IQJrJm^fIyS_8*_mO`Xd0Yj!D zv8PNY=$FIYAI}u<_2mJnqy;in$wf|=!@1q*ja-o_VDrj$LQh5HOmY$2T;AX&usKFe z|CP1?S@wCq;~Z8mA%0*T-}eOM-Q;}EuDF5WF>_(yqKeA7j)z}V^-lq^T%M5cVDqQ| zog1qC?kW6S&4zPk-q1II*c9fjVAl`2?gMF)XVlW6DS*oH?VoM=C$i$c)2?ET0qgVt z%PVF-HZRQ1v)kMcKO9sS#t$JaSce5wqIK+-aYyql8y$#1= z-Vtf+7SI|E&c?L^)s|w?r)g)2qaWAoYjilqMWcAHe&z<^dass!5&U&( zYZkMOxg+`*(u1;NIXj~y9i!HcR6{y=i>PQCO?UB&Rcby$#Ca6heE1Vnqv;`)xi+Dx zU^FeHC)!zuCVh6=xTe$V6Wavhx<=i#K;>yiiTloTs_BAUf)|MOl<0M${x~nNd0l5> zg7mj|9Y{1{<%#+G%UxtWcu~qS4Yo;4bpWJ&VLEDfTE)PMzM$w)>Y7ZBlT%o>JRLHU4;Avfi%mO`0cfGw))ob=S-Y;ZZwxcX});a?VAU?1lzGcOc-WSv5-@ zPO(N@$4jPd|DBCTtGu({FZMC^>O#v;@cbXwoN3+UQg$jByL27soq;;~5>}DF@XfW0 zim+#vm*=gnKk|Q(6ET-niM;EX??>YVc^527nqQQRy!)lVgUt%fbbYutsaDgFcF*{= zghENe0CE;8A3Jc1O(@{{7H)r*MZ1X?SSQylx4QijU8S9HQkaJeNcWV`7nL2qRz5Zg zac8@|eU#Nrd5l*}9R3bbNlcl$?X%iu9VcJ}V>mR?~R36IW97Y zE6oo=NGWn+Cuj6@CmOFuIym^^(P3m)@NLz7J9KWDA`kg_T*VrTaz=d4!!furi z?irZEO$Gu8#+bOUEfY&LPtk^x=r_7P`i7lnxsi)4U5%&+H{{+ZklOp0?E$l5R# z4y{zy?=i7q+Ab#G?{{O(Yre6G%m{-)E+)RVnD|P)uW-%A-~XABRNm!t?8pnG$$P{E3>Kc)Rj;Kq3YYWM0D-@YNNrbcS91Re z(zfSlfRXTWdorqnz{6JcI}`#~2|x3}Xz?F~mmCcYtcuIpdv7?n9iz@wTNq!fE)tKbl;1e@r9wV9@e?UpO2gYdwZKB3 zi!vH*Dbyg>rDn7@u8SodENB?M$blj3msnKPTJG1_4U%l)E^i~W-kJtv9g5h z;xxp$3+wY_RiJz?fl#}Co@~_}c$$I7kR<&Cm(mFvL!Yl6L?6gW^h3_;r=8qvUlDbo z;)qWhH;nMv0eGYNdu-f3+b z*%sY2Y9<;7!aDaBRQjIB$SP2LYM;96`{Dv3%dqvW=$>HQC+4h8a;zwwMX-+iPu-E@ zQzU-d_2-8wV-$nW_I?oOQ>&_S@SI!&53FEh_($ZgZ`+h#M zo3Qs9OX-DB4Np@(-LiwSQ;dJ=^+pRKnD;h>eH?b%;vjGnd@t_CO45X`=EcJYR2_re z(Q{YV>tvqAGVZa!|HtY7TJM@v7eewZ=_KNnCJ-Jnpo_Hr~e zDxJXE7&P+ga#!aiNnqXmooolG4N)2w{CJ=za3Yj*{#+l_u?W0L9VFRa_fXr; z!J5AIy)+b%US2_=7;=kW`El|Yjd5@}h%(sPcAe8}Vw!ic=~i>)?fKs1p>*Rp($ifg z?DqMUzVCZ=u`3d^$jhXfGg!aomt~TsESSGbvHn^UR=aw(YN&LJ-I+4S(a0+^P_>U# z>lTM465XZv0^1+VMI9qIVHT5pIC`_=>#n1FJf%6*)ywL8Qx9%m&=ln!Osf<^Rk1p9 z>gY3=iB`J({VGV}wBQbVWI04t(LsD^bWyV78OdoA6m_e(y%ytLlZ?IS@gx6)d}3Al z9=Pmc(A=oov@y;H9KGxfWl#%7Os!ulx$JA!5uc_$i+H-8jJ(CRqb}(XR?L3;@Ru~e zw$;cuB~C2%>RNEkohF9!wLK4fvhr-K@uVtuZUoVIS{;Z+H|VE+xaRMbPMA8K_zAtu8vQ2 zfD~7qe0_(dZb66`fZ|I8BNEk!)A?<@Y7pnEdRQuehwZ{CH^P4Tk!f0B-}FZ4TR@VP z;odAt2?p#}gHqjVGFm(-kbM1EyQ6W{6nD3B1`z=tFuK5l72ZrPdT}b|I|J^;lgL5P zUZ}Z`chlCV3BA`y1n(7nnl>xS9~}%v()wYIdI)0Z>3MR_ob4Mnf&7hC%sx;8Lbbqi z`s!Wu3i2Eh<$UfPIMFR{GSU&<6|d(I!`Cn%0Y2vgHO|Ll^p_IzkA+BS${p?IOS zn}s|99wO<`v)km!C}ON-C$ciHTFUBi+`rpIlz_be-$e*tO%1|h4aC-@+*=e!fqq1j zrCkyd=E3vOjnmVnglK2+a8GxFYem1JAp#suSi-tewhc_B;yp~63;&$_n4VuEfi-sK zwb^RX1*1@q5(j^*gULp z1BP)7?tT$W$4H9dg-C{jR1_>W{8ieF^xz<@6r*Xp(t+k;Y7^AT6B6Gf+jSXC`@QJ2 z%?cP&rY2VArq?}MhjZt!z@1bUqjYpN|5-^=uvpdoVHU3 z=$rT(d>_HvB5EJySC$}NKW8o}nBB+_ucj5veM**ZR{fRA+ocL+L{{jXq4vB$zkjqp z4QfOUC+-sup*=T8yxI0f_l4y*atp{N^XBuTaMP63^5PBl>Lg3*!5QCXON+W|aU_jM(=8)NoZ%pF56 ztFj8p*kU}9P~Ak|D-qy^1T`qpjALt!&S+w0IdT*p_Ms~rL|ZiAW@D<$+hAs78O+U;uB>z6K z$N`RCb7AV~bg6F#2Nu7W;RimMS}=W$3(7%t;Vqk^2>Anc%w( z*o%+esQ2w}Twz~}U$Zl@FUSzn$(aOq;_e$KP`m0L5FW+LTYD^if>-AC1BB@v5W5p< z5zNHILw-ygRCi*kJVq{|rv!q-s!@E^@oat zK-c$D!enus>S+vcrd}ayt7kP7a-en6scJkDt~SPidf6S7lx>i;3eXjXu@nZ04eq| zJ!T}b6k2zXK9i3IwJ>UmyvOZA^R?TQ{k?nTv%rXaB6uxA0E6Jd1Jfy$T4mV9$ou zs(fGu>oB)p!T+I?`rJ)Z82!14jGPMB;5`_qGof2fV;N#;gsX}yGYH40bNHtWtvDm6 z&?gv|nIv3-#h&}?6Oy1fR9x9G$2e)5NUJYIG?9uiJ~_qc;e#GgiQfXSZQsRl;9{6E zOZ?<>3D$jAcjR0Jeaa5An)0R~o56;SG;WPJ@ABI9GENyC8_P9Gz%E`yNRtmPM5wqHdmlAK5%DVX859Mw!m8g)RYu(c z>t=g$($%Kf@!FOHUbs5#o%xHL;b@uOvVb)VE-XJzJ;sZd#)zkRt7u5!c;Z0$C3e{$ z)P<#ZucCSn6g8IDDD?e6nV+@r?jJ{Y8XpQ!Md%QBJK~xlx|;iqjaIWI68l+&=ry^< zQ+|`{*N}R_=jA5LdagNS`l0Gdk+QiFrS)zi)N7jitF5us-_K^sxm3&Bm69^7wx(D8 zx|RwD8K`~-TU~X+u}EZE6hE-WKI+gsZ+|(hwLjS73nTV^I_zMVOwMdmk32k^#AA=F8tc>DKxF6DMj#>ty2 zI%nS}9!Yaq3p}22*d^^;DKYaw7q0Vk+x;#|GZ8{9I`6sCp_iBPML}hga@^tUG@G|O z*Sbu=Vy5xb#{cIjEAPTP_10M^vpq^&){W)m?tZ^zCe8^FC1q}QqPjQ3hl^Z?$yxv7 tjA3lGZrbbN;5Q-jrOmpYUc|ow7>{$4h@X$a5r57B6l7Fk)l%lc{{=`juBZS2 literal 0 HcmV?d00001 diff --git a/Monorail/Monorail/Resources/rightarrowbutton_99645.png b/Monorail/Monorail/Resources/rightarrowbutton_99645.png new file mode 100644 index 0000000000000000000000000000000000000000..6b7224b4a7f80919749f8663de54332e42ee5491 GIT binary patch literal 8190 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 literal 0 HcmV?d00001 diff --git a/Monorail/Monorail/Resources/rightarrowbutton_996451.png b/Monorail/Monorail/Resources/rightarrowbutton_996451.png new file mode 100644 index 0000000000000000000000000000000000000000..6b7224b4a7f80919749f8663de54332e42ee5491 GIT binary patch literal 8190 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 literal 0 HcmV?d00001 -- 2.25.1 From b10750e80175a22e6500c43c14747bbaf60094d8 Mon Sep 17 00:00:00 2001 From: selli73 <145283432+selli73@users.noreply.github.com> Date: Sat, 2 Mar 2024 14:43:02 +0400 Subject: [PATCH 2/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=80=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB?= =?UTF-8?q?=D0=B5=D0=B9=20=D0=B8=20=D0=B2=D0=B2=D0=BE=D0=B4=20=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D1=8B=D1=85=20=D0=BA=D0=BE=D0=BD=D1=81=D1=82=D1=80=D1=83?= =?UTF-8?q?=D0=BA=D1=82=D0=BE=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Monorail/{ => Drawnings}/DirectionType.cs | 2 +- .../Monorail/Drawnings/DrawningMonorail.cs | 67 ++++++++++ .../Drawning_Monorail.cs} | 122 +++++++++--------- .../Monorail/{ => Entities}/EntityMonorail.cs | 33 ++--- Monorail/Monorail/Entities/Entity_Monorail.cs | 48 +++++++ Monorail/Monorail/FormMonorail.Designer.cs | 17 ++- Monorail/Monorail/FormMonorail.cs | 80 ++++++++---- 7 files changed, 259 insertions(+), 110 deletions(-) rename Monorail/Monorail/{ => Drawnings}/DirectionType.cs (94%) create mode 100644 Monorail/Monorail/Drawnings/DrawningMonorail.cs rename Monorail/Monorail/{DrawningMonorail.cs => Drawnings/Drawning_Monorail.cs} (78%) rename Monorail/Monorail/{ => Entities}/EntityMonorail.cs (69%) create mode 100644 Monorail/Monorail/Entities/Entity_Monorail.cs diff --git a/Monorail/Monorail/DirectionType.cs b/Monorail/Monorail/Drawnings/DirectionType.cs similarity index 94% rename from Monorail/Monorail/DirectionType.cs rename to Monorail/Monorail/Drawnings/DirectionType.cs index 3fb9deb..d6daf61 100644 --- a/Monorail/Monorail/DirectionType.cs +++ b/Monorail/Monorail/Drawnings/DirectionType.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace monorail; +namespace Monorail.Drawnings; /// /// Направление перемещения /// diff --git a/Monorail/Monorail/Drawnings/DrawningMonorail.cs b/Monorail/Monorail/Drawnings/DrawningMonorail.cs new file mode 100644 index 0000000..15ecd94 --- /dev/null +++ b/Monorail/Monorail/Drawnings/DrawningMonorail.cs @@ -0,0 +1,67 @@ +using Monorail.Entities; + +namespace Monorail.Drawnings; +/// +/// Класс отвечающий за прорисовку и перемещение объекта-сущности +/// +public class DrawningMonorail : Drawning_Monorail +{ + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Дополнительный цвет + /// магнитный рельс + /// Вторая кабинка в задней части + + public DrawningMonorail(int speed, double weight, Color bodyColor, Color additionalColor, bool magneticRail, bool secondCabin) : base(95, 40) + { + Entity_Monorail = new EntityMonorail(speed, weight, bodyColor, additionalColor, magneticRail, secondCabin); + } + + public override void DrawTransport(Graphics g) + { + if (Entity_Monorail == null || Entity_Monorail is not EntityMonorail monorail || !_startPosX.HasValue || !_startPosY.HasValue) + { + return; + } + + + Pen pen = new(Color.Black); + Brush additionalBrush = new SolidBrush(monorail.AdditionalColor); + + //магнитная рельса + if (monorail.MagneticRail) + { + g.FillRectangle(additionalBrush, _startPosX.Value, _startPosY.Value + 40, 90, 3); + } + + //вторая часть монорельса + + if (monorail.SecondCabin) + { + Point[] points_second_cabin = { + new Point(_startPosX.Value + 85, _startPosY.Value), + new Point(_startPosX.Value + 95, _startPosY.Value + 15), + new Point(_startPosX.Value + 95, _startPosY.Value + 30), + new Point(_startPosX.Value + 85, _startPosY.Value + 30), + new Point(_startPosX.Value + 85, _startPosY.Value + 15), + new Point(_startPosX.Value + 95, _startPosY.Value + 15) + + }; + g.DrawPolygon(pen, points_second_cabin); + g.FillPolygon(additionalBrush, points_second_cabin); + + } + + + + //_startPosX += 10; + //_startPosY += 5; + base.DrawTransport(g); + //_startPosX -= 10; + //_startPosY -= 5; + } +} \ No newline at end of file diff --git a/Monorail/Monorail/DrawningMonorail.cs b/Monorail/Monorail/Drawnings/Drawning_Monorail.cs similarity index 78% rename from Monorail/Monorail/DrawningMonorail.cs rename to Monorail/Monorail/Drawnings/Drawning_Monorail.cs index c3bba62..363386f 100644 --- a/Monorail/Monorail/DrawningMonorail.cs +++ b/Monorail/Monorail/Drawnings/Drawning_Monorail.cs @@ -1,15 +1,18 @@ - +using Monorail.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; -namespace monorail; -/// -/// Класс отвечающий за прорисовку и перемещение объекта-сущности -/// -public class DrawningMonorail +namespace Monorail.Drawnings; + +public class Drawning_Monorail { /// /// Класс-сущность (объект) /// - public EntityMonorail? EntityMonorail { get; private set; } + public Entity_Monorail? Entity_Monorail { get; protected set; } /// /// Ширина окна @@ -24,42 +27,62 @@ public class DrawningMonorail /// /// Левая координата прорисовки монорельса /// - private int? _startPosX; + protected int? _startPosX; /// /// Верхняя координата прорисовки монорельса /// - private int? _startPosY; + protected int? _startPosY; /// /// Ширина прорисовки монорельса (размер объекта) /// - private readonly int _drawningMonorailWidth = 95; + private readonly int _drawningMonorailWidth = 90; /// /// Высота прорисовки монорельса (размер объекта) /// private readonly int _drawingMonorailHeight = 40; - /// - /// Инициализация свойства - /// - /// Скорость - /// Вес - /// Основной цвет - /// Дополнительный цвет - /// магнитный рельс - /// Вторая кабинка в задней части - public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool magneticRail, bool secondCabin) + /// + /// Пустой конструктор + /// + private Drawning_Monorail() { - EntityMonorail = new EntityMonorail(); - EntityMonorail.Init(speed, weight, bodyColor, additionalColor, magneticRail, secondCabin); _pictureWidth = null; _pictureHeight = null; _startPosX = null; _startPosY = null; + } + + + /// + /// Конструтор + /// + /// Скорость + /// Вес + /// Основной цвет + + + public Drawning_Monorail(int speed, double weight, Color bodyColor) : this() + { + Entity_Monorail = new Entity_Monorail(speed, weight, bodyColor); } + /// + /// Конструтор для наследников + /// + /// Ширина прорисовки монорельса (размер объекта) + /// Высота прорисовки монорельса (размер объекта) + + + protected Drawning_Monorail(int drawningMonorailWidth, int drawingMonorailHeight) : this() + { + _drawningMonorailWidth = drawningMonorailWidth; + _drawingMonorailHeight = drawingMonorailHeight; + } + + /// /// Установка границ поля /// @@ -141,7 +164,7 @@ public class DrawningMonorail /// true - перемещение выполнено, false - перемещение невозможно public bool MoveTransport(DirectionType direction) { - if (EntityMonorail == null || !_startPosX.HasValue || !_startPosY.HasValue) + if (Entity_Monorail == null || !_startPosX.HasValue || !_startPosY.HasValue) { return false; } @@ -149,33 +172,33 @@ public class DrawningMonorail { //влево case DirectionType.Left: - if (_startPosX.Value - EntityMonorail.Step > 0) + if (_startPosX.Value - Entity_Monorail.Step > 0) { - _startPosX -= (int)EntityMonorail.Step; + _startPosX -= (int)Entity_Monorail.Step; } return true; //вверх case DirectionType.Up: - if (_startPosY.Value - EntityMonorail.Step > 0) + if (_startPosY.Value - Entity_Monorail.Step > 0) { - _startPosY -= (int)EntityMonorail.Step; + _startPosY -= (int)Entity_Monorail.Step; } return true; // вправо case DirectionType.Right: // TODO прописать логику сдвига в право - if (_startPosX.Value + EntityMonorail.Step + _drawningMonorailWidth < _pictureWidth) + if (_startPosX.Value + Entity_Monorail.Step + _drawningMonorailWidth < _pictureWidth) { - _startPosX += (int)EntityMonorail.Step; + _startPosX += (int)Entity_Monorail.Step; } return true; //вниз case DirectionType.Down: //TODO прописать логику сдвига в вниз - if (_startPosY.Value + EntityMonorail.Step + _drawingMonorailHeight < _pictureHeight) + if (_startPosY.Value + Entity_Monorail.Step + _drawingMonorailHeight < _pictureHeight) { - _startPosY += (int)EntityMonorail.Step; + _startPosY += (int)Entity_Monorail.Step; } return true; default: @@ -189,43 +212,20 @@ public class DrawningMonorail /// /// /// - public void DrawTransport(Graphics g) + public virtual void DrawTransport(Graphics g) { - if (EntityMonorail == null || !_startPosX.HasValue || !_startPosY.HasValue) + if (Entity_Monorail == null || !_startPosX.HasValue || !_startPosY.HasValue) { return; } Pen pen = new(Color.Black); - Brush additionalBrush = new SolidBrush(EntityMonorail.AdditionalColor); - //магнитная рельса - if (EntityMonorail.MagneticRail) - { - g.FillRectangle(additionalBrush, _startPosX.Value, _startPosY.Value + 40, 90, 3); - } - - //вторая часть монорельса - - if (EntityMonorail.SecondCabin) - { - Point[] points_second_cabin = { - new Point(_startPosX.Value + 85, _startPosY.Value), - new Point(_startPosX.Value + 95, _startPosY.Value + 15), - new Point(_startPosX.Value + 95, _startPosY.Value + 30), - new Point(_startPosX.Value + 85, _startPosY.Value + 30), - new Point(_startPosX.Value + 85, _startPosY.Value + 15), - new Point(_startPosX.Value + 95, _startPosY.Value + 15) - - }; - g.DrawPolygon(pen, points_second_cabin); - g.FillPolygon(additionalBrush, points_second_cabin); - - } + //границы Монорельса - Brush br = new SolidBrush(EntityMonorail.BodyColor); + Brush br = new SolidBrush(Entity_Monorail.BodyColor); g.DrawRectangle(pen, _startPosX.Value + 5, _startPosY.Value + 15, 80, 15); Point[] points1 = { new Point(_startPosX.Value + 15, _startPosY.Value), @@ -244,7 +244,7 @@ public class DrawningMonorail new Point(_startPosX.Value + 84, _startPosY.Value + 1), new Point(_startPosX.Value + 84, _startPosY.Value + 14), new Point(_startPosX.Value + 6, _startPosY.Value + 14) - }; + }; g.FillPolygon(br, points2); @@ -266,7 +266,7 @@ public class DrawningMonorail //1-ый держатель Point[] points_cart1 = { - new Point(_startPosX.Value, _startPosY.Value + 35), + new Point(_startPosX.Value + 5, _startPosY.Value + 30), new Point(_startPosX.Value + 15, _startPosY.Value + 35), new Point(_startPosX.Value + 15, _startPosY.Value + 30), new Point(_startPosX.Value + 5, _startPosY.Value + 30) @@ -330,4 +330,4 @@ public class DrawningMonorail } -} \ No newline at end of file +} diff --git a/Monorail/Monorail/EntityMonorail.cs b/Monorail/Monorail/Entities/EntityMonorail.cs similarity index 69% rename from Monorail/Monorail/EntityMonorail.cs rename to Monorail/Monorail/Entities/EntityMonorail.cs index 1933d50..965f544 100644 --- a/Monorail/Monorail/EntityMonorail.cs +++ b/Monorail/Monorail/Entities/EntityMonorail.cs @@ -1,21 +1,9 @@ -namespace monorail; +namespace Monorail.Entities; /// /// Класс-сущность "Монорельс" /// -public class EntityMonorail +public class EntityMonorail : Entity_Monorail { - /// - /// скорость - /// - public int Speed { get; private set; } - /// - /// Вес - /// - public double Weight { get; private set; } - /// - /// основной цвет - /// - public Color BodyColor { get; private set; } /// /// дополнительный цвет /// @@ -30,11 +18,7 @@ public class EntityMonorail public bool SecondCabin { get; private set; } /// - /// шаг - /// - public double Step => Speed * 100 / Weight; - /// - /// Инициализация полей объекта-класса монорельса + /// Конструктор /// /// Скорость /// Вес @@ -42,7 +26,8 @@ public class EntityMonorail /// Дополнительный цвет /// признак наличие рельса /// признак вторая кабинка - public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool magneticRail, bool secondCabin) + + public EntityMonorail(int speed, double weight, Color bodyColor, Color additionalColor, bool magneticRail, bool secondCabin) : base(speed, weight, bodyColor) { Speed = speed; Weight = weight; @@ -50,5 +35,13 @@ public class EntityMonorail AdditionalColor = additionalColor; MagneticRail = magneticRail; SecondCabin = secondCabin; + + } + + public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool magneticRail, bool secondCabin) + { + AdditionalColor = additionalColor; + MagneticRail = magneticRail; + SecondCabin = secondCabin; } } \ No newline at end of file diff --git a/Monorail/Monorail/Entities/Entity_Monorail.cs b/Monorail/Monorail/Entities/Entity_Monorail.cs new file mode 100644 index 0000000..2df55f8 --- /dev/null +++ b/Monorail/Monorail/Entities/Entity_Monorail.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.Entities; + +/// +/// Класс-сущносить "Монорельс" +/// +public class Entity_Monorail +{ + /// + /// скорость + /// + public int Speed { get; set; } + /// + /// Вес + /// + public double Weight { get; set; } + /// + /// основной цвет + /// + public Color BodyColor { get; set; } + + /// + /// шаг + /// + public double Step => Speed * 100 / Weight; + + + /// + /// Конструктор сущности + /// + /// Скорость + /// Вес + /// Основной цвет + + public Entity_Monorail(int speed, double weight, Color bodyColor) + { + Speed = speed; + Weight = weight; + BodyColor = bodyColor; + + } + +} diff --git a/Monorail/Monorail/FormMonorail.Designer.cs b/Monorail/Monorail/FormMonorail.Designer.cs index 70f1931..a858c62 100644 --- a/Monorail/Monorail/FormMonorail.Designer.cs +++ b/Monorail/Monorail/FormMonorail.Designer.cs @@ -34,6 +34,7 @@ buttonDown = new Button(); buttonRight = new Button(); buttonUp = new Button(); + buttonCreateMonorail = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBox1Monorail).BeginInit(); SuspendLayout(); // @@ -51,9 +52,9 @@ buttonCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; buttonCreate.Location = new Point(10, 358); buttonCreate.Name = "buttonCreate"; - buttonCreate.Size = new Size(75, 23); + buttonCreate.Size = new Size(221, 23); buttonCreate.TabIndex = 1; - buttonCreate.Text = "создать"; + buttonCreate.Text = "создать монорельс"; buttonCreate.UseVisualStyleBackColor = true; buttonCreate.Click += buttonCreate_Click; // @@ -105,11 +106,22 @@ buttonUp.UseVisualStyleBackColor = true; buttonUp.Click += buttonMove_Click; // + // buttonCreateMonorail + // + buttonCreateMonorail.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateMonorail.Location = new Point(247, 358); + buttonCreateMonorail.Name = "buttonCreateMonorail"; + buttonCreateMonorail.Size = new Size(221, 23); + buttonCreateMonorail.TabIndex = 6; + buttonCreateMonorail.Text = "создать monorail"; + buttonCreateMonorail.UseVisualStyleBackColor = true; + // // FormMonorail // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(755, 393); + Controls.Add(buttonCreateMonorail); Controls.Add(buttonUp); Controls.Add(buttonRight); Controls.Add(buttonDown); @@ -130,5 +142,6 @@ private Button buttonDown; private Button buttonRight; private Button buttonUp; + private Button buttonCreateMonorail; } } \ No newline at end of file diff --git a/Monorail/Monorail/FormMonorail.cs b/Monorail/Monorail/FormMonorail.cs index aec1d9e..367116b 100644 --- a/Monorail/Monorail/FormMonorail.cs +++ b/Monorail/Monorail/FormMonorail.cs @@ -1,4 +1,5 @@ -using monorail; +using Monorail.Drawnings; + namespace Monorail; /// /// Форма работы с объектом "Монорельс" @@ -8,7 +9,8 @@ public partial class FormMonorail : Form /// /// Поле-объект для прорисовки объекта /// - private DrawningMonorail? _drawningMonorail; + private Drawning_Monorail? _drawning_Monorail; + /// /// конструктор формы /// @@ -21,46 +23,70 @@ public partial class FormMonorail : Form /// private void Draw() { - if (_drawningMonorail == null) + if (_drawning_Monorail == null) { return; } Bitmap bmp = new(pictureBox1Monorail.Width, pictureBox1Monorail.Height); Graphics gr = Graphics.FromImage(bmp); - _drawningMonorail.DrawTransport(gr); + _drawning_Monorail.DrawTransport(gr); pictureBox1Monorail.Image = bmp; } + private void FormMonorail_Load(object sender, EventArgs e) { } + + + private void CreateObject(string type) + { + Random random = new(); + switch (type) + { + case nameof(Drawning_Monorail): + _drawning_Monorail = new Drawning_Monorail(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(DrawningMonorail): + _drawning_Monorail = new DrawningMonorail(random.Next(100, 300), random.Next(1000, 3000), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), + Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2))); + break; + default: + return; + } + + _drawning_Monorail.SetPictureSize(pictureBox1Monorail.Width, pictureBox1Monorail.Height); + _drawning_Monorail.SetPosition(random.Next(10, 100), random.Next(10, 100)); + //_strategy = null; + //comboBoxStrategy.Enabled = true; + Draw(); + } + + + /// - /// Обработка нажатия кнопки "Создать" + /// Обработка нажатия кнопки "Создать Монорельс" /// /// /// - private void buttonCreate_Click(object sender, EventArgs e) - { - Random random = new(); - _drawningMonorail = new DrawningMonorail(); - _drawningMonorail.Init(random.Next(100, 300), random.Next(1000, 3000), - Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), - Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), - Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2))); - _drawningMonorail.SetPictureSize(pictureBox1Monorail.Width, pictureBox1Monorail.Height); - _drawningMonorail.SetPosition(random.Next(10, 100), random.Next(10, 100)); + private void buttonCreate_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningMonorail)); + + + /// + /// Обработка нажатия кнопки "Создать _Монорельс" + /// + /// + /// + private void ButtonCreateMonorail_Click(object sender, EventArgs e) => CreateObject(nameof(Drawning_Monorail)); - Bitmap bmp = new(pictureBox1Monorail.Width, pictureBox1Monorail.Height); - Graphics gr = Graphics.FromImage(bmp); - _drawningMonorail.DrawTransport(gr); - pictureBox1Monorail.Image = bmp; - Draw(); - } /// /// Перемещение объекта по форме (нажатие кнопок навигации) @@ -69,7 +95,7 @@ public partial class FormMonorail : Form /// private void buttonMove_Click(object sender, EventArgs e) { - if (_drawningMonorail == null) + if (_drawning_Monorail == null) { return; } @@ -79,16 +105,16 @@ public partial class FormMonorail : Form switch (name) { case "buttonUp": - result = _drawningMonorail.MoveTransport(DirectionType.Up); + result = _drawning_Monorail.MoveTransport(DirectionType.Up); break; case "buttonDown": - result = _drawningMonorail.MoveTransport(DirectionType.Down); + result = _drawning_Monorail.MoveTransport(DirectionType.Down); break; case "buttonLeft": - result = _drawningMonorail.MoveTransport(DirectionType.Left); + result = _drawning_Monorail.MoveTransport(DirectionType.Left); break; case "buttonRight": - result = _drawningMonorail.MoveTransport(DirectionType.Right); + result = _drawning_Monorail.MoveTransport(DirectionType.Right); break; } if (result) @@ -97,4 +123,6 @@ public partial class FormMonorail : Form } } + + } -- 2.25.1 From eeb2f04169ae1acab30cfa697d8db7bd7c6eb7f3 Mon Sep 17 00:00:00 2001 From: selli73 <145283432+selli73@users.noreply.github.com> Date: Thu, 7 Mar 2024 17:10:03 +0400 Subject: [PATCH 3/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=B5=D0=B3?= =?UTF-8?q?=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Monorail/Monorail/Drawnings/DirectionType.cs | 5 + ...ning_Monorail.cs => DrawningLocomotive.cs} | 59 +++++--- .../Monorail/Drawnings/DrawningMonorail.cs | 15 +- ...Entity_Monorail.cs => EntityLocomotive.cs} | 6 +- Monorail/Monorail/Entities/EntityMonorail.cs | 9 +- Monorail/Monorail/FormMonorail.Designer.cs | 51 +++++-- Monorail/Monorail/FormMonorail.cs | 87 ++++++++--- .../MovementStrategy/AbstractStrategy.cs | 142 ++++++++++++++++++ .../MovementStrategy/IMoveableObject.cs | 30 ++++ .../Monorail/MovementStrategy/MoveToBorder.cs | 37 +++++ .../Monorail/MovementStrategy/MoveToCenter.cs | 60 ++++++++ .../MovementStrategy/MoveableLocomotive.cs | 71 +++++++++ .../MovementStrategy/MovementDirection.cs | 28 ++++ .../MovementStrategy/ObjectParameters.cs | 75 +++++++++ .../MovementStrategy/StrategyStatus.cs | 25 +++ 15 files changed, 632 insertions(+), 68 deletions(-) rename Monorail/Monorail/Drawnings/{Drawning_Monorail.cs => DrawningLocomotive.cs} (85%) rename Monorail/Monorail/Entities/{Entity_Monorail.cs => EntityLocomotive.cs} (85%) create mode 100644 Monorail/Monorail/MovementStrategy/AbstractStrategy.cs create mode 100644 Monorail/Monorail/MovementStrategy/IMoveableObject.cs create mode 100644 Monorail/Monorail/MovementStrategy/MoveToBorder.cs create mode 100644 Monorail/Monorail/MovementStrategy/MoveToCenter.cs create mode 100644 Monorail/Monorail/MovementStrategy/MoveableLocomotive.cs create mode 100644 Monorail/Monorail/MovementStrategy/MovementDirection.cs create mode 100644 Monorail/Monorail/MovementStrategy/ObjectParameters.cs create mode 100644 Monorail/Monorail/MovementStrategy/StrategyStatus.cs diff --git a/Monorail/Monorail/Drawnings/DirectionType.cs b/Monorail/Monorail/Drawnings/DirectionType.cs index d6daf61..d8d9e8b 100644 --- a/Monorail/Monorail/Drawnings/DirectionType.cs +++ b/Monorail/Monorail/Drawnings/DirectionType.cs @@ -10,6 +10,11 @@ namespace Monorail.Drawnings; /// public enum DirectionType { + /// + /// Неизвестное направление + /// + Unknow = -1, + /// /// Вверх /// diff --git a/Monorail/Monorail/Drawnings/Drawning_Monorail.cs b/Monorail/Monorail/Drawnings/DrawningLocomotive.cs similarity index 85% rename from Monorail/Monorail/Drawnings/Drawning_Monorail.cs rename to Monorail/Monorail/Drawnings/DrawningLocomotive.cs index 363386f..85335db 100644 --- a/Monorail/Monorail/Drawnings/Drawning_Monorail.cs +++ b/Monorail/Monorail/Drawnings/DrawningLocomotive.cs @@ -7,12 +7,15 @@ using System.Threading.Tasks; namespace Monorail.Drawnings; -public class Drawning_Monorail +/// +/// Класс, отвечающий за прорисовку и перемещение базового объекта-сущности +/// +public class DrawningLocomotive { /// /// Класс-сущность (объект) /// - public Entity_Monorail? Entity_Monorail { get; protected set; } + public EntityLocomotive? EntityLocomotive { get; protected set; } /// /// Ширина окна @@ -42,11 +45,33 @@ public class Drawning_Monorail /// private readonly int _drawingMonorailHeight = 40; + /// + /// Координата X объекта + /// + public int? GetPosX => _startPosX; + + /// + /// Координата Y объекта + /// + public int? GetPosY => _startPosY; + + /// + /// Ширина объекта + /// + public int GetWidth => _drawningMonorailWidth; + + /// + /// Высота объекта + /// + public int GetHeight => _drawingMonorailHeight; + + + /// /// Пустой конструктор /// - private Drawning_Monorail() + private DrawningLocomotive() { _pictureWidth = null; _pictureHeight = null; @@ -63,9 +88,9 @@ public class Drawning_Monorail /// Основной цвет - public Drawning_Monorail(int speed, double weight, Color bodyColor) : this() + public DrawningLocomotive(int speed, double weight, Color bodyColor) : this() { - Entity_Monorail = new Entity_Monorail(speed, weight, bodyColor); + EntityLocomotive = new EntityLocomotive(speed, weight, bodyColor); } @@ -76,7 +101,7 @@ public class Drawning_Monorail /// Высота прорисовки монорельса (размер объекта) - protected Drawning_Monorail(int drawningMonorailWidth, int drawingMonorailHeight) : this() + protected DrawningLocomotive(int drawningMonorailWidth, int drawingMonorailHeight) : this() { _drawningMonorailWidth = drawningMonorailWidth; _drawingMonorailHeight = drawingMonorailHeight; @@ -164,7 +189,7 @@ public class Drawning_Monorail /// true - перемещение выполнено, false - перемещение невозможно public bool MoveTransport(DirectionType direction) { - if (Entity_Monorail == null || !_startPosX.HasValue || !_startPosY.HasValue) + if (EntityLocomotive == null || !_startPosX.HasValue || !_startPosY.HasValue) { return false; } @@ -172,33 +197,33 @@ public class Drawning_Monorail { //влево case DirectionType.Left: - if (_startPosX.Value - Entity_Monorail.Step > 0) + if (_startPosX.Value - EntityLocomotive.Step > 0) { - _startPosX -= (int)Entity_Monorail.Step; + _startPosX -= (int)EntityLocomotive.Step; } return true; //вверх case DirectionType.Up: - if (_startPosY.Value - Entity_Monorail.Step > 0) + if (_startPosY.Value - EntityLocomotive.Step > 0) { - _startPosY -= (int)Entity_Monorail.Step; + _startPosY -= (int)EntityLocomotive.Step; } return true; // вправо case DirectionType.Right: // TODO прописать логику сдвига в право - if (_startPosX.Value + Entity_Monorail.Step + _drawningMonorailWidth < _pictureWidth) + if (_startPosX.Value + EntityLocomotive.Step + _drawningMonorailWidth < _pictureWidth) { - _startPosX += (int)Entity_Monorail.Step; + _startPosX += (int)EntityLocomotive.Step; } return true; //вниз case DirectionType.Down: //TODO прописать логику сдвига в вниз - if (_startPosY.Value + Entity_Monorail.Step + _drawingMonorailHeight < _pictureHeight) + if (_startPosY.Value + EntityLocomotive.Step + _drawingMonorailHeight < _pictureHeight) { - _startPosY += (int)Entity_Monorail.Step; + _startPosY += (int)EntityLocomotive.Step; } return true; default: @@ -214,7 +239,7 @@ public class Drawning_Monorail /// public virtual void DrawTransport(Graphics g) { - if (Entity_Monorail == null || !_startPosX.HasValue || !_startPosY.HasValue) + if (EntityLocomotive == null || !_startPosX.HasValue || !_startPosY.HasValue) { return; } @@ -225,7 +250,7 @@ public class Drawning_Monorail //границы Монорельса - Brush br = new SolidBrush(Entity_Monorail.BodyColor); + Brush br = new SolidBrush(EntityLocomotive.BodyColor); g.DrawRectangle(pen, _startPosX.Value + 5, _startPosY.Value + 15, 80, 15); Point[] points1 = { new Point(_startPosX.Value + 15, _startPosY.Value), diff --git a/Monorail/Monorail/Drawnings/DrawningMonorail.cs b/Monorail/Monorail/Drawnings/DrawningMonorail.cs index 15ecd94..755ba77 100644 --- a/Monorail/Monorail/Drawnings/DrawningMonorail.cs +++ b/Monorail/Monorail/Drawnings/DrawningMonorail.cs @@ -4,7 +4,7 @@ namespace Monorail.Drawnings; /// /// Класс отвечающий за прорисовку и перемещение объекта-сущности /// -public class DrawningMonorail : Drawning_Monorail +public class DrawningMonorail : DrawningLocomotive { /// /// Конструктор @@ -16,14 +16,14 @@ public class DrawningMonorail : Drawning_Monorail /// магнитный рельс /// Вторая кабинка в задней части - public DrawningMonorail(int speed, double weight, Color bodyColor, Color additionalColor, bool magneticRail, bool secondCabin) : base(95, 40) + public DrawningMonorail(int speed, double weight, Color bodyColor, Color additionalColor, bool magneticRail, bool secondCabin) : base(90, 40) { - Entity_Monorail = new EntityMonorail(speed, weight, bodyColor, additionalColor, magneticRail, secondCabin); + EntityLocomotive = new EntityMonorail(speed, weight, bodyColor, additionalColor, magneticRail, secondCabin); } public override void DrawTransport(Graphics g) { - if (Entity_Monorail == null || Entity_Monorail is not EntityMonorail monorail || !_startPosX.HasValue || !_startPosY.HasValue) + if (EntityLocomotive == null || EntityLocomotive is not EntityMonorail monorail || !_startPosX.HasValue || !_startPosY.HasValue) { return; } @@ -56,12 +56,7 @@ public class DrawningMonorail : Drawning_Monorail } - - - //_startPosX += 10; - //_startPosY += 5; base.DrawTransport(g); - //_startPosX -= 10; - //_startPosY -= 5; + } } \ No newline at end of file diff --git a/Monorail/Monorail/Entities/Entity_Monorail.cs b/Monorail/Monorail/Entities/EntityLocomotive.cs similarity index 85% rename from Monorail/Monorail/Entities/Entity_Monorail.cs rename to Monorail/Monorail/Entities/EntityLocomotive.cs index 2df55f8..60d5d08 100644 --- a/Monorail/Monorail/Entities/Entity_Monorail.cs +++ b/Monorail/Monorail/Entities/EntityLocomotive.cs @@ -7,9 +7,9 @@ using System.Threading.Tasks; namespace Monorail.Entities; /// -/// Класс-сущносить "Монорельс" +/// Класс-сущносить "Локомотив" /// -public class Entity_Monorail +public class EntityLocomotive { /// /// скорость @@ -37,7 +37,7 @@ public class Entity_Monorail /// Вес /// Основной цвет - public Entity_Monorail(int speed, double weight, Color bodyColor) + public EntityLocomotive(int speed, double weight, Color bodyColor) { Speed = speed; Weight = weight; diff --git a/Monorail/Monorail/Entities/EntityMonorail.cs b/Monorail/Monorail/Entities/EntityMonorail.cs index 965f544..70f6377 100644 --- a/Monorail/Monorail/Entities/EntityMonorail.cs +++ b/Monorail/Monorail/Entities/EntityMonorail.cs @@ -2,7 +2,7 @@ /// /// Класс-сущность "Монорельс" /// -public class EntityMonorail : Entity_Monorail +public class EntityMonorail : EntityLocomotive { /// /// дополнительный цвет @@ -37,11 +37,4 @@ public class EntityMonorail : Entity_Monorail SecondCabin = secondCabin; } - - public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool magneticRail, bool secondCabin) - { - AdditionalColor = additionalColor; - MagneticRail = magneticRail; - SecondCabin = secondCabin; - } } \ No newline at end of file diff --git a/Monorail/Monorail/FormMonorail.Designer.cs b/Monorail/Monorail/FormMonorail.Designer.cs index a858c62..6c90d4f 100644 --- a/Monorail/Monorail/FormMonorail.Designer.cs +++ b/Monorail/Monorail/FormMonorail.Designer.cs @@ -34,7 +34,9 @@ buttonDown = new Button(); buttonRight = new Button(); buttonUp = new Button(); - buttonCreateMonorail = new Button(); + buttonCreateLocomotive = new Button(); + comboBoxStrategy = new ComboBox(); + buttonStrategyStep = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBox1Monorail).BeginInit(); SuspendLayout(); // @@ -54,7 +56,7 @@ buttonCreate.Name = "buttonCreate"; buttonCreate.Size = new Size(221, 23); buttonCreate.TabIndex = 1; - buttonCreate.Text = "создать монорельс"; + buttonCreate.Text = "создать Monorail"; buttonCreate.UseVisualStyleBackColor = true; buttonCreate.Click += buttonCreate_Click; // @@ -106,22 +108,45 @@ buttonUp.UseVisualStyleBackColor = true; buttonUp.Click += buttonMove_Click; // - // buttonCreateMonorail + // buttonCreateLocomotive // - buttonCreateMonorail.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - buttonCreateMonorail.Location = new Point(247, 358); - buttonCreateMonorail.Name = "buttonCreateMonorail"; - buttonCreateMonorail.Size = new Size(221, 23); - buttonCreateMonorail.TabIndex = 6; - buttonCreateMonorail.Text = "создать monorail"; - buttonCreateMonorail.UseVisualStyleBackColor = true; + buttonCreateLocomotive.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateLocomotive.Location = new Point(247, 358); + buttonCreateLocomotive.Name = "buttonCreateLocomotive"; + buttonCreateLocomotive.Size = new Size(221, 23); + buttonCreateLocomotive.TabIndex = 6; + buttonCreateLocomotive.Text = "создать Locomotive"; + buttonCreateLocomotive.UseVisualStyleBackColor = true; + buttonCreateLocomotive.Click += ButtonCreateLocomotive_Click; + // + // comboBoxStrategy + // + comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxStrategy.FormattingEnabled = true; + comboBoxStrategy.Items.AddRange(new object[] { "К центру", "К краю" }); + comboBoxStrategy.Location = new Point(625, 12); + comboBoxStrategy.Name = "comboBoxStrategy"; + comboBoxStrategy.Size = new Size(121, 23); + comboBoxStrategy.TabIndex = 7; + // + // buttonStrategyStep + // + buttonStrategyStep.Location = new Point(685, 41); + buttonStrategyStep.Name = "buttonStrategyStep"; + buttonStrategyStep.Size = new Size(61, 23); + buttonStrategyStep.TabIndex = 8; + buttonStrategyStep.Text = "Шаг"; + buttonStrategyStep.UseVisualStyleBackColor = true; + buttonStrategyStep.Click += buttonStrategyStep_Click; // // FormMonorail // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(755, 393); - Controls.Add(buttonCreateMonorail); + Controls.Add(buttonStrategyStep); + Controls.Add(comboBoxStrategy); + Controls.Add(buttonCreateLocomotive); Controls.Add(buttonUp); Controls.Add(buttonRight); Controls.Add(buttonDown); @@ -142,6 +167,8 @@ private Button buttonDown; private Button buttonRight; private Button buttonUp; - private Button buttonCreateMonorail; + private Button buttonCreateLocomotive; + private ComboBox comboBoxStrategy; + private Button buttonStrategyStep; } } \ No newline at end of file diff --git a/Monorail/Monorail/FormMonorail.cs b/Monorail/Monorail/FormMonorail.cs index 367116b..b0b0614 100644 --- a/Monorail/Monorail/FormMonorail.cs +++ b/Monorail/Monorail/FormMonorail.cs @@ -1,4 +1,5 @@ using Monorail.Drawnings; +using Monorail.MovementStrategy; namespace Monorail; /// @@ -9,7 +10,12 @@ public partial class FormMonorail : Form /// /// Поле-объект для прорисовки объекта /// - private Drawning_Monorail? _drawning_Monorail; + private DrawningLocomotive? _drawningLocomotive; + + /// + /// Стратегия перемещения + /// + private AbstractStrategy? _strategy; /// /// конструктор формы @@ -17,20 +23,21 @@ public partial class FormMonorail : Form public FormMonorail() { InitializeComponent(); + _strategy = null; } /// /// Метод прорисовки машины /// private void Draw() { - if (_drawning_Monorail == null) + if (_drawningLocomotive == null) { return; } Bitmap bmp = new(pictureBox1Monorail.Width, pictureBox1Monorail.Height); Graphics gr = Graphics.FromImage(bmp); - _drawning_Monorail.DrawTransport(gr); + _drawningLocomotive.DrawTransport(gr); pictureBox1Monorail.Image = bmp; } @@ -42,18 +49,21 @@ public partial class FormMonorail : Form } - + /// + /// Создание объекта класса-перемещения + /// + /// Тип создаваемого объекта private void CreateObject(string type) { Random random = new(); switch (type) { - case nameof(Drawning_Monorail): - _drawning_Monorail = new Drawning_Monorail(random.Next(100, 300), random.Next(1000, 3000), + case nameof(DrawningLocomotive): + _drawningLocomotive = new DrawningLocomotive(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(DrawningMonorail): - _drawning_Monorail = new DrawningMonorail(random.Next(100, 300), random.Next(1000, 3000), + _drawningLocomotive = new DrawningMonorail(random.Next(100, 300), random.Next(1000, 3000), Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2))); @@ -62,10 +72,10 @@ public partial class FormMonorail : Form return; } - _drawning_Monorail.SetPictureSize(pictureBox1Monorail.Width, pictureBox1Monorail.Height); - _drawning_Monorail.SetPosition(random.Next(10, 100), random.Next(10, 100)); - //_strategy = null; - //comboBoxStrategy.Enabled = true; + _drawningLocomotive.SetPictureSize(pictureBox1Monorail.Width, pictureBox1Monorail.Height); + _drawningLocomotive.SetPosition(random.Next(10, 100), random.Next(10, 100)); + _strategy = null; + comboBoxStrategy.Enabled = true; Draw(); } @@ -85,7 +95,7 @@ public partial class FormMonorail : Form /// /// /// - private void ButtonCreateMonorail_Click(object sender, EventArgs e) => CreateObject(nameof(Drawning_Monorail)); + private void ButtonCreateLocomotive_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningLocomotive)); /// @@ -95,7 +105,7 @@ public partial class FormMonorail : Form /// private void buttonMove_Click(object sender, EventArgs e) { - if (_drawning_Monorail == null) + if (_drawningLocomotive == null) { return; } @@ -105,16 +115,16 @@ public partial class FormMonorail : Form switch (name) { case "buttonUp": - result = _drawning_Monorail.MoveTransport(DirectionType.Up); + result = _drawningLocomotive.MoveTransport(DirectionType.Up); break; case "buttonDown": - result = _drawning_Monorail.MoveTransport(DirectionType.Down); + result = _drawningLocomotive.MoveTransport(DirectionType.Down); break; case "buttonLeft": - result = _drawning_Monorail.MoveTransport(DirectionType.Left); + result = _drawningLocomotive.MoveTransport(DirectionType.Left); break; case "buttonRight": - result = _drawning_Monorail.MoveTransport(DirectionType.Right); + result = _drawningLocomotive.MoveTransport(DirectionType.Right); break; } if (result) @@ -124,5 +134,46 @@ public partial class FormMonorail : Form } - + /// + /// + /// + /// + /// + private void buttonStrategyStep_Click(object sender, EventArgs e) + { + if (_drawningLocomotive == null) + { + return; + } + + if (comboBoxStrategy.Enabled) + { + _strategy = comboBoxStrategy.SelectedIndex switch + { + 0 => new MoveToCenter(), + 1 => new MoveToBorder(), + _ => null, + }; + if (_strategy == null) + { + return; + } + _strategy.SetData(new MoveableLocomotive(_drawningLocomotive), pictureBox1Monorail.Width, pictureBox1Monorail.Height); + } + + if (_strategy == null) + { + return; + } + + comboBoxStrategy.Enabled = false; + _strategy.MakeStep(); + Draw(); + + if (_strategy.GetStatus() == StrategyStatus.Finish) + { + comboBoxStrategy.Enabled = true; + _strategy = null; + } + } } diff --git a/Monorail/Monorail/MovementStrategy/AbstractStrategy.cs b/Monorail/Monorail/MovementStrategy/AbstractStrategy.cs new file mode 100644 index 0000000..7f3b4ce --- /dev/null +++ b/Monorail/Monorail/MovementStrategy/AbstractStrategy.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.MovementStrategy; + +public abstract class AbstractStrategy +{ + /// + /// Перемещаемый объект + /// + private IMoveableObject? _moveableObject; + + /// + /// Статус перемещения + /// + private StrategyStatus _state = StrategyStatus.NotInit; + + /// + /// Ширина поля + /// + protected int FieldWidth { get; private set; } + + /// + /// Высота поля + /// + protected int FieldHeight { get; private set; } + + /// + /// Статус перемещения + /// + public StrategyStatus GetStatus() { return _state; } + + /// + /// Установка данных + /// + /// Перемещаемый объект + /// Ширина поля + /// Высота поля + public void SetData(IMoveableObject moveableObject, int width, int height) + { + if (moveableObject == null) + { + _state = StrategyStatus.NotInit; + return; + } + + _state = StrategyStatus.InProgress; + _moveableObject = moveableObject; + FieldWidth = width; + FieldHeight = height; + } + + /// + /// Шаг перемещения + /// + public void MakeStep() + { + if (_state != StrategyStatus.InProgress) + { + return; + } + + if (IsTargetDestinaion()) + { + _state = StrategyStatus.Finish; + return; + } + + MoveToTarget(); + } + + /// + /// Перемещение влево + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveLeft() => MoveTo(MovementDirection.Left); + + /// + /// Перемещение вправо + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveRight() => MoveTo(MovementDirection.Right); + + /// + /// Перемещение вверх + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveUp() => MoveTo(MovementDirection.Up); + + /// + /// Перемещение вниз + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveDown() => MoveTo(MovementDirection.Down); + + /// + /// Параметры объекта + /// + protected ObjectParameters? GetObjectParameters => _moveableObject?.GetObjectPosition; + + /// + /// Шаг объекта + /// + /// + protected int? GetStep() + { + if (_state != StrategyStatus.InProgress) + { + return null; + } + return _moveableObject?.GetStep; + } + + /// + /// Перемещение к цели + /// + protected abstract void MoveToTarget(); + + /// + /// Достигнута ли цель + /// + /// + protected abstract bool IsTargetDestinaion(); + + /// + /// Попытка перемещения в требуемом направлении + /// + /// Направление + /// Результат попытки (true - удалось переместиться, false - неудача) + private bool MoveTo(MovementDirection movementDirection) + { + if (_state != StrategyStatus.InProgress) + { + return false; + } + + return _moveableObject?.TryMoveObject(movementDirection) ?? false; + } +} diff --git a/Monorail/Monorail/MovementStrategy/IMoveableObject.cs b/Monorail/Monorail/MovementStrategy/IMoveableObject.cs new file mode 100644 index 0000000..0f2fc6c --- /dev/null +++ b/Monorail/Monorail/MovementStrategy/IMoveableObject.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.MovementStrategy; + +/// +/// Интерфейс для работы с перемещаемым объектом +/// +public interface IMoveableObject +{ + /// + /// Получение координаты объекта + /// + ObjectParameters? GetObjectPosition { get; } + + /// + /// Шаг объекта + /// + int GetStep { get; } + + /// + /// Попытка переместить объект в указанном направлении + /// + /// Направление + /// + bool TryMoveObject(MovementDirection direction); +} diff --git a/Monorail/Monorail/MovementStrategy/MoveToBorder.cs b/Monorail/Monorail/MovementStrategy/MoveToBorder.cs new file mode 100644 index 0000000..cac9c6f --- /dev/null +++ b/Monorail/Monorail/MovementStrategy/MoveToBorder.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.MovementStrategy; + +public class MoveToBorder : AbstractStrategy +{ + protected override bool IsTargetDestinaion() + { + ObjectParameters? objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + return objParams.LeftBorder - GetStep() <= 0 || + objParams.RightBorder + GetStep() >= FieldWidth || + objParams.TopBorder - GetStep() <= 0 + || objParams.ObjectMiddleVertical + GetStep() >= FieldHeight; + } + + protected override void MoveToTarget() + { + ObjectParameters? objParams = GetObjectParameters; + if (objParams == null) + { + return; + } + //реализация в правый нижний угол + int x = objParams.RightBorder; + if (x + GetStep() < FieldWidth) MoveRight(); + int y = objParams.DowBorder; + if (y + GetStep() < FieldHeight) MoveDown(); + } +} diff --git a/Monorail/Monorail/MovementStrategy/MoveToCenter.cs b/Monorail/Monorail/MovementStrategy/MoveToCenter.cs new file mode 100644 index 0000000..6d254d4 --- /dev/null +++ b/Monorail/Monorail/MovementStrategy/MoveToCenter.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.MovementStrategy; + +/// +/// Стратегия перемещения объекта в центр экрана +/// +public class MoveToCenter : AbstractStrategy +{ + protected override bool IsTargetDestinaion() + { + ObjectParameters? objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + + return objParams.ObjectMiddleHorizontal - GetStep() <= FieldWidth / 2 && objParams.ObjectMiddleHorizontal + GetStep() >= FieldWidth / 2 && + objParams.ObjectMiddleVertical - GetStep() <= FieldHeight / 2 && objParams.ObjectMiddleVertical + GetStep() >= FieldHeight / 2; + } + + protected override void MoveToTarget() + { + 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(); + } + } + } +} diff --git a/Monorail/Monorail/MovementStrategy/MoveableLocomotive.cs b/Monorail/Monorail/MovementStrategy/MoveableLocomotive.cs new file mode 100644 index 0000000..9c753cf --- /dev/null +++ b/Monorail/Monorail/MovementStrategy/MoveableLocomotive.cs @@ -0,0 +1,71 @@ +using Monorail.Drawnings; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.MovementStrategy; + +/// +/// Класс-реализация IMoveableObject с использованием Drawning_Monorail +/// +public class MoveableLocomotive : IMoveableObject +{ + /// + /// Поле-объект класса Drawning_Monorail или его наследника + /// + private readonly DrawningLocomotive? Locomotive = null; + + /// + /// Конструктор + /// + /// Объект класса DrawningCar + public MoveableLocomotive(DrawningLocomotive locomotive) + { + Locomotive = locomotive; + } + + public ObjectParameters? GetObjectPosition + { + get + { + if ((Locomotive == null || Locomotive.EntityLocomotive == null || !Locomotive.GetPosX.HasValue || !Locomotive.GetPosY.HasValue)) + { + return null; + } + return new ObjectParameters(Locomotive.GetPosX.Value, Locomotive.GetPosY.Value, Locomotive.GetWidth, Locomotive.GetHeight); + } + } + + public int GetStep => (int)(Locomotive?.EntityLocomotive?.Step ?? 0); + + public bool TryMoveObject(MovementDirection direction) + { + if (Locomotive == null || Locomotive.EntityLocomotive == null) + { + return false; + } + + return Locomotive.MoveTransport(GetDirectionType(direction)); + + } + + /// + /// Конвертация из MovementDirection в DirectionType + /// + /// MovementDirection + /// DirectionType + private static DirectionType GetDirectionType(MovementDirection direction) + { + return direction switch + { + MovementDirection.Left => DirectionType.Left, + MovementDirection.Right => DirectionType.Right, + MovementDirection.Up => DirectionType.Up, + MovementDirection.Down => DirectionType.Down, + _ => DirectionType.Unknow, + }; + } + +} diff --git a/Monorail/Monorail/MovementStrategy/MovementDirection.cs b/Monorail/Monorail/MovementStrategy/MovementDirection.cs new file mode 100644 index 0000000..0bc23ff --- /dev/null +++ b/Monorail/Monorail/MovementStrategy/MovementDirection.cs @@ -0,0 +1,28 @@ + +namespace Monorail.MovementStrategy; + +/// +/// Направление перемещения +/// +public enum MovementDirection +{ + /// + /// Вверх + /// + Up = 1, + + /// + /// Вниз + /// + Down = 2, + + /// + /// Влево + /// + Left = 3, + + /// + /// Вправо + /// + Right = 4 +} diff --git a/Monorail/Monorail/MovementStrategy/ObjectParameters.cs b/Monorail/Monorail/MovementStrategy/ObjectParameters.cs new file mode 100644 index 0000000..f2439cd --- /dev/null +++ b/Monorail/Monorail/MovementStrategy/ObjectParameters.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.MovementStrategy; + +public class ObjectParameters +{ + /// + /// Координата X + /// + private readonly int _x; + + /// + /// Координата Y + /// + private readonly int _y; + + /// + /// Ширина объекта + /// + private readonly int _width; + + /// + /// Высота объекта + /// + private readonly int _height; + + /// + /// Левая граница + /// + public int LeftBorder => _x; + + /// + /// Верхняя граница + /// + public int TopBorder => _y; + + /// + /// Правая граница + /// + public int RightBorder => _x + _width; + + /// + /// Нижняя граница + /// + public int DowBorder => _y + _height; + + /// + /// Серидина объекта + /// + public int ObjectMiddleHorizontal => _x + _width / 2; + + /// + /// Серидина объекта + /// + public int ObjectMiddleVertical => _y + _height / 2; + + /// + /// Конструктор + /// + /// + /// + /// + /// + public ObjectParameters(int x, int y, int width, int height) + { + _x = x; + _y = y; + _width = width; + _height = height; + } +} diff --git a/Monorail/Monorail/MovementStrategy/StrategyStatus.cs b/Monorail/Monorail/MovementStrategy/StrategyStatus.cs new file mode 100644 index 0000000..464af51 --- /dev/null +++ b/Monorail/Monorail/MovementStrategy/StrategyStatus.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.MovementStrategy; + +public enum StrategyStatus +{ + /// + /// Все готово к началу + /// + NotInit, + + /// + /// Выполняется + /// + InProgress, + + /// + /// Завершено + /// + Finish +} -- 2.25.1 From 8661b0c7acd16505f89730135b6893ba0af514bc Mon Sep 17 00:00:00 2001 From: selli73 <145283432+selli73@users.noreply.github.com> Date: Sun, 17 Mar 2024 11:00:57 +0400 Subject: [PATCH 4/6] =?UTF-8?q?=D0=9A=D0=BE=D0=BB=D0=BB=D0=B5=D0=BA=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ICollectionGenericObjects.cs | 50 ++++++++++++++++ .../MassiveGenericObjects.cs | 57 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 Monorail/Monorail/CollectionGenericObjects/ICollectionGenericObjects.cs create mode 100644 Monorail/Monorail/CollectionGenericObjects/MassiveGenericObjects.cs diff --git a/Monorail/Monorail/CollectionGenericObjects/ICollectionGenericObjects.cs b/Monorail/Monorail/CollectionGenericObjects/ICollectionGenericObjects.cs new file mode 100644 index 0000000..f8b7c26 --- /dev/null +++ b/Monorail/Monorail/CollectionGenericObjects/ICollectionGenericObjects.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.CollectionGenericObjects; + +public interface ICollectionGenericObjects + where T : class +{ + /// + /// Количество объектов в коллекции + /// + int Count { get; } + + /// + /// Установка максимального количества элементов + /// + int SetMaxCount { set; } + + /// + /// Добавление объекта в коллекцию + /// + /// Добавляемый объект + /// true - вставка прошла удачно, false - вставка не удалась + bool Insert(T obj); + + /// + /// Добавление объекта в коллекцию на конкретную позицию + /// + /// Добавляемый объект + /// Позиция + /// true - вставка прошла удачно, false - вставка не удалась + bool Insert(T obj, int position); + + /// + /// Удаление объекта из коллекции с конкретной позиции + /// + /// Позиция + /// true - удаление прошло удачно, false - удаление не удалось + bool Remove(int position); + + /// + /// Получение объекта по позиции + /// + /// Позиция + /// Объект + T? Get(int position); +} diff --git a/Monorail/Monorail/CollectionGenericObjects/MassiveGenericObjects.cs b/Monorail/Monorail/CollectionGenericObjects/MassiveGenericObjects.cs new file mode 100644 index 0000000..1dc92e2 --- /dev/null +++ b/Monorail/Monorail/CollectionGenericObjects/MassiveGenericObjects.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.CollectionGenericObjects; + +public class MassiveGenericObjects : ICollectionGenericObjects + where T : class +{ + /// + /// Массив объектов, которые храним + /// + private T?[] _collection; + + public int Count => _collection.Length; + + public int SetMaxCount { set { if (value > 0) { _collection = new T?[value]; } } } + + /// + /// Конструктор + /// + public MassiveGenericObjects() + { + _collection = Array.Empty(); + } + + public T? Get(int position) + { + // Todo проверка позиции + return _collection[position]; + } + + public bool Insert(T obj) + { + // TODO вставка в свободное место набора + return false; + } + public bool Insert(T obj, int position) + { + // TODO проверка позиции + // TODO проверка, что элемент массива по этой позиции пустой, если нет, то + // ищется свободное место после этой позиции и идет вставка туда + // если нет после, ищем до + // TODO вставка + return false; + } + + public bool Remove(int position) + { + // TODO проверка позиции + // TODO удаление объекта из массива, присовив элементу массива значение null + return true; + } +} + -- 2.25.1 From f5991d3f6e86d614fb7cc30cc08c98b0c67ca72f Mon Sep 17 00:00:00 2001 From: selli73 <145283432+selli73@users.noreply.github.com> Date: Sat, 23 Mar 2024 18:01:47 +0400 Subject: [PATCH 5/6] =?UTF-8?q?=D0=9A=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Monorail/Monorail/FormMonorail.cs | 49 ------------------------------- 1 file changed, 49 deletions(-) diff --git a/Monorail/Monorail/FormMonorail.cs b/Monorail/Monorail/FormMonorail.cs index b0b0614..24b08c4 100644 --- a/Monorail/Monorail/FormMonorail.cs +++ b/Monorail/Monorail/FormMonorail.cs @@ -49,55 +49,6 @@ public partial class FormMonorail : Form } - /// - /// Создание объекта класса-перемещения - /// - /// Тип создаваемого объекта - private void CreateObject(string type) - { - Random random = new(); - switch (type) - { - case nameof(DrawningLocomotive): - _drawningLocomotive = new DrawningLocomotive(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(DrawningMonorail): - _drawningLocomotive = new DrawningMonorail(random.Next(100, 300), random.Next(1000, 3000), - Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), - Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), - Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2))); - break; - default: - return; - } - - _drawningLocomotive.SetPictureSize(pictureBox1Monorail.Width, pictureBox1Monorail.Height); - _drawningLocomotive.SetPosition(random.Next(10, 100), random.Next(10, 100)); - _strategy = null; - comboBoxStrategy.Enabled = true; - Draw(); - } - - - - /// - /// Обработка нажатия кнопки "Создать Монорельс" - /// - /// - /// - - private void buttonCreate_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningMonorail)); - - - /// - /// Обработка нажатия кнопки "Создать _Монорельс" - /// - /// - /// - private void ButtonCreateLocomotive_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningLocomotive)); - - /// /// Перемещение объекта по форме (нажатие кнопок навигации) /// -- 2.25.1 From 70325483aa2a65ac5925dcdc1f155a8259f9ccd8 Mon Sep 17 00:00:00 2001 From: selli73 <145283432+selli73@users.noreply.github.com> Date: Sun, 7 Apr 2024 11:07:13 +0400 Subject: [PATCH 6/6] =?UTF-8?q?4=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractCompany.cs | 121 +++++++ .../CollectionType.cs | 26 ++ .../ICollectionGenericObjects.cs | 6 +- .../ListGenericObjects.cs | 77 +++++ .../LocomotiveSharingService.cs | 65 ++++ .../MassiveGenericObjects.cs | 96 +++++- .../StorageCollection.cs | 77 +++++ .../FormLocomotiveCollection.Designer.cs | 302 +++++++++++++++++ Monorail/Monorail/FormLocomotiveCollection.cs | 303 ++++++++++++++++++ .../Monorail/FormLocomotiveCollection.resx | 120 +++++++ Monorail/Monorail/FormMonorail.Designer.cs | 28 -- Monorail/Monorail/FormMonorail.cs | 32 +- Monorail/Monorail/Program.cs | 2 +- 13 files changed, 1197 insertions(+), 58 deletions(-) create mode 100644 Monorail/Monorail/CollectionGenericObjects/AbstractCompany.cs create mode 100644 Monorail/Monorail/CollectionGenericObjects/CollectionType.cs create mode 100644 Monorail/Monorail/CollectionGenericObjects/ListGenericObjects.cs create mode 100644 Monorail/Monorail/CollectionGenericObjects/LocomotiveSharingService.cs create mode 100644 Monorail/Monorail/CollectionGenericObjects/StorageCollection.cs create mode 100644 Monorail/Monorail/FormLocomotiveCollection.Designer.cs create mode 100644 Monorail/Monorail/FormLocomotiveCollection.cs create mode 100644 Monorail/Monorail/FormLocomotiveCollection.resx diff --git a/Monorail/Monorail/CollectionGenericObjects/AbstractCompany.cs b/Monorail/Monorail/CollectionGenericObjects/AbstractCompany.cs new file mode 100644 index 0000000..3914aa2 --- /dev/null +++ b/Monorail/Monorail/CollectionGenericObjects/AbstractCompany.cs @@ -0,0 +1,121 @@ +using Monorail.Drawnings; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.CollectionGenericObjects; + +/// +/// Абстракция компании, хранящий коллекцию Локомотив +/// +public abstract class AbstractCompany +{ + /// + /// Размер места (ширина) + /// + protected readonly int _placeSizeWidth = 180; + + /// + /// Размер места (высота) + /// + protected readonly int _placeSizeHeight = 80; + + /// + /// Ширина окна + /// + protected readonly int _pictureWidth; + + /// + /// Высота окна + /// + protected readonly int _pictureHeight; + + /// + /// Коллекция Локомотив + /// + protected ICollectionGenericObjects? _collection = null; + + /// + /// Вычисление максимального количества элементов, который можно разместить в окне + /// + private int GetMaxCount => _pictureWidth * _pictureHeight / (_placeSizeWidth * _placeSizeHeight); + + /// + /// Конструктор + /// + /// Ширина окна + /// Высота окна + /// Коллекция Локомотив + public AbstractCompany(int picWidth, int picHeight, ICollectionGenericObjects collection) + { + _pictureWidth = picWidth; + _pictureHeight = picHeight; + _collection = collection; + _collection.SetMaxCount = GetMaxCount; + } + + /// + /// Перегрузка оператора сложения для класса + /// + /// Компания + /// Добавляемый объект + /// + public static int operator +(AbstractCompany company, DrawningLocomotive locomotive) + { + return company._collection.Insert(locomotive); + } + + /// + /// Перегрузка оператора удаления для класса + /// + /// Компания + /// Номер удаляемого объекта + /// + public static DrawningLocomotive operator -(AbstractCompany company, int position) + { + return company._collection?.Remove(position); + } + + /// + /// Получение случайного объекта из коллекции + /// + /// + public DrawningLocomotive? GetRandomObject() + { + Random rnd = new(); + return _collection?.Get(rnd.Next(GetMaxCount)); + } + + /// + /// Вывод всей коллекции + /// + /// + public Bitmap? Show() + { + Bitmap bitmap = new(_pictureWidth, _pictureHeight); + Graphics graphics = Graphics.FromImage(bitmap); + DrawBackgound(graphics); + + SetObjectsPosition(); + for (int i = 0; i < (_collection?.Count ?? 0); ++i) + { + DrawningLocomotive? obj = _collection?.Get(i); + obj?.DrawTransport(graphics); + } + + return bitmap; + } + + /// + /// Вывод заднего фона + /// + /// + protected abstract void DrawBackgound(Graphics g); + + /// + /// Расстановка объектов + /// + protected abstract void SetObjectsPosition(); +} diff --git a/Monorail/Monorail/CollectionGenericObjects/CollectionType.cs b/Monorail/Monorail/CollectionGenericObjects/CollectionType.cs new file mode 100644 index 0000000..2250906 --- /dev/null +++ b/Monorail/Monorail/CollectionGenericObjects/CollectionType.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.CollectionGenericObjects; + +/// +/// Тип коллекции +/// +public enum CollectionType +{ + /// + /// Неопределено + /// + None = 0, + /// + /// Массив + /// + Massive = 1, + /// + /// Список + /// + List = 2 +} diff --git a/Monorail/Monorail/CollectionGenericObjects/ICollectionGenericObjects.cs b/Monorail/Monorail/CollectionGenericObjects/ICollectionGenericObjects.cs index f8b7c26..2bc167a 100644 --- a/Monorail/Monorail/CollectionGenericObjects/ICollectionGenericObjects.cs +++ b/Monorail/Monorail/CollectionGenericObjects/ICollectionGenericObjects.cs @@ -24,7 +24,7 @@ public interface ICollectionGenericObjects /// /// Добавляемый объект /// true - вставка прошла удачно, false - вставка не удалась - bool Insert(T obj); + int Insert(T obj); /// /// Добавление объекта в коллекцию на конкретную позицию @@ -32,14 +32,14 @@ public interface ICollectionGenericObjects /// Добавляемый объект /// Позиция /// true - вставка прошла удачно, false - вставка не удалась - bool Insert(T obj, int position); + int Insert(T obj, int position); /// /// Удаление объекта из коллекции с конкретной позиции /// /// Позиция /// true - удаление прошло удачно, false - удаление не удалось - bool Remove(int position); + T Remove(int position); /// /// Получение объекта по позиции diff --git a/Monorail/Monorail/CollectionGenericObjects/ListGenericObjects.cs b/Monorail/Monorail/CollectionGenericObjects/ListGenericObjects.cs new file mode 100644 index 0000000..e3a745d --- /dev/null +++ b/Monorail/Monorail/CollectionGenericObjects/ListGenericObjects.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.CollectionGenericObjects; + +/// +/// Параметризованный набор объектов +/// +/// Параметр: ограничение - ссылочный тип +public class ListGenericObjects : ICollectionGenericObjects + where T : class +{ + /// + /// Список объектов, которые храним + /// + private readonly List _collection; + + /// + /// Максимально допустимое число объектов в списке + /// + private int _maxCount; + + /// + /// свойство, возвращающее количество элементов в списке. + /// + public int Count => _collection.Count; + + public int SetMaxCount { set { if (value > 0) { _maxCount = value; } } } + + /// + /// Конструктор + /// + public ListGenericObjects() + { + _collection = new(); + } + + public T? Get(int position) + { + // TODO проверка позиции + if (position >= Count || position < 0) return null; + return _collection[position]; + } + + public int Insert(T obj) + { + // TODO проверка, что не превышено максимальное количество элементов + // TODO вставка в конец набора + if (Count == _maxCount) return -1; + _collection.Add(obj); + return Count; + } + + public int Insert(T obj, int position) + { + // TODO проверка, что не превышено максимальное количество элементов + // TODO проверка позиции + // TODO вставка по позиции + if (Count == _maxCount) return -1; + if (position >= Count || position < 0) return -1; + _collection.Insert(position, obj); + return position; + } + + public T Remove(int position) + { + // TODO проверка позиции + // TODO удаление объекта из списка + if (position >= Count || position < 0) return null; + T obj = _collection[position]; + _collection.RemoveAt(position); + return obj; + } +} \ No newline at end of file diff --git a/Monorail/Monorail/CollectionGenericObjects/LocomotiveSharingService.cs b/Monorail/Monorail/CollectionGenericObjects/LocomotiveSharingService.cs new file mode 100644 index 0000000..4e245cb --- /dev/null +++ b/Monorail/Monorail/CollectionGenericObjects/LocomotiveSharingService.cs @@ -0,0 +1,65 @@ +using Monorail.Drawnings; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.CollectionGenericObjects; + +public class LocomotiveSharingService : AbstractCompany +{ + /// + /// Конструктор + /// + /// + /// + /// + public LocomotiveSharingService(int picWidth, int picHeight, ICollectionGenericObjects collection) : base(picWidth, picHeight, collection) + { + } + + /// + /// прорисовка стоянки + /// + /// + protected override void DrawBackgound(Graphics g) + { + Pen pen = new(Color.Black, 3); + int posX = 0; + for (int i = 0; i < _pictureWidth / _placeSizeWidth; i++) + { + int posY = 0; + g.DrawLine(pen, posX, posY, posX, posY + _placeSizeHeight * (_pictureHeight / _placeSizeHeight)); + for (int j = 0; j <= _pictureHeight / _placeSizeHeight; j++) + { + g.DrawLine(pen, posX, posY, posX + _placeSizeWidth - 30, posY); + posY += _placeSizeHeight; + } + posX += _placeSizeWidth; + + } + } + + protected override void SetObjectsPosition() + { + int posX = 0; + int posY = _pictureHeight / _placeSizeHeight - 1; + for (int i = 0; i < _collection?.Count; i++) + { + if (_collection.Get(i) != null) + { + _collection?.Get(i)?.SetPictureSize(_pictureWidth, _pictureHeight); + _collection?.Get(i)?.SetPosition(posX * _placeSizeWidth + 3, posY * _placeSizeHeight + 3); + } + posY--; + if (posY < 0) + { + posY = _pictureHeight / _placeSizeHeight - 1; + posX++; + } + if (posX >= _pictureWidth / _placeSizeWidth) { return; } + } + + } +} diff --git a/Monorail/Monorail/CollectionGenericObjects/MassiveGenericObjects.cs b/Monorail/Monorail/CollectionGenericObjects/MassiveGenericObjects.cs index 1dc92e2..b10502b 100644 --- a/Monorail/Monorail/CollectionGenericObjects/MassiveGenericObjects.cs +++ b/Monorail/Monorail/CollectionGenericObjects/MassiveGenericObjects.cs @@ -6,52 +6,116 @@ using System.Threading.Tasks; namespace Monorail.CollectionGenericObjects; +/// +/// Параметризованный набор объектов +/// +/// Параметр: ограничение - ссылочный тип public class MassiveGenericObjects : ICollectionGenericObjects where T : class { /// - /// Массив объектов, которые храним + /// массив объектов, которые храним /// private T?[] _collection; - public int Count => _collection.Length; - public int SetMaxCount { set { if (value > 0) { _collection = new T?[value]; } } } + public int SetMaxCount + { + set + { + if (value > 0) + { + if (_collection.Length > 0) + { + Array.Resize(ref _collection, value); + } + else + { + _collection = new T?[value]; + } + } + } + } /// - /// Конструктор + /// Конструктор /// public MassiveGenericObjects() { - _collection = Array.Empty(); + _collection = Array.Empty(); } public T? Get(int position) { - // Todo проверка позиции + // TODO проверка позиции + if (position >= _collection.Length || position < 0) + { return null; } return _collection[position]; } - - public bool Insert(T obj) + + public int Insert(T obj) { // TODO вставка в свободное место набора - return false; + int index = 0; + while (index < _collection.Length) + { + if (_collection[index] == null) + { + _collection[index] = obj; + return index; + } + + index++; + } + return -1; } - public bool Insert(T obj, int position) + + public int Insert(T obj, int position) { // TODO проверка позиции // TODO проверка, что элемент массива по этой позиции пустой, если нет, то - // ищется свободное место после этой позиции и идет вставка туда - // если нет после, ищем до + // ищется свободное место после этой позиции и идет вставка туда + // если нет после, ищем до // TODO вставка - return false; + if (position >= _collection.Length || position < 0) + { return -1; } + + if (_collection[position] == null) + { + _collection[position] = obj; + return position; + } + int index; + + for (index = position + 1; index < _collection.Length; ++index) + { + if (_collection[index] == null) + { + _collection[position] = obj; + return position; + } + } + + for (index = position - 1; index >= 0; --index) + { + if (_collection[index] == null) + { + _collection[position] = obj; + return position; + } + } + return -1; } - public bool Remove(int position) + public T Remove(int position) { // TODO проверка позиции - // TODO удаление объекта из массива, присовив элементу массива значение null - return true; + // TODO удаление объекта из массива, присвоив элементу массива значение null + if (position >= _collection.Length || position < 0) + { return null; } + T obj = _collection[position]; + _collection[position] = null; + return obj; } } diff --git a/Monorail/Monorail/CollectionGenericObjects/StorageCollection.cs b/Monorail/Monorail/CollectionGenericObjects/StorageCollection.cs new file mode 100644 index 0000000..cee6f8f --- /dev/null +++ b/Monorail/Monorail/CollectionGenericObjects/StorageCollection.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Monorail.CollectionGenericObjects; + +/// +/// Класс-хранилище коллекций +/// +/// +public class StorageCollection + where T : class +{ + /// + /// Словарь (хранилище) с коллекциями + /// + readonly Dictionary> _storages; + + /// + /// Возвращение списка названий коллекций + /// + public List Keys => _storages.Keys.ToList(); + + /// + /// Конструктор + /// + public StorageCollection() + { + _storages = new Dictionary>(); + } + + /// + /// Добавление коллекции в хранилище + /// + /// Название коллекции + /// тип коллекции + public void AddCollection(string name, CollectionType collectionType) + { + // TODO проверка, что name не пустой и нет в словаре записи с таким ключом + // TODO Прописать логику для добавления + if (_storages.ContainsKey(name)) return; + if (collectionType == CollectionType.None) return; + else if (collectionType == CollectionType.Massive) + _storages[name] = new MassiveGenericObjects(); + else if (collectionType == CollectionType.List) + _storages[name] = new ListGenericObjects(); + } + + /// + /// Удаление коллекции + /// + /// Название коллекции + public void DelCollection(string name) + { + // TODO Прописать логику для удаления коллекции + if (_storages.ContainsKey(name)) + _storages.Remove(name); + } + + /// + /// Доступ к коллекции + /// + /// Название коллекции + /// + public ICollectionGenericObjects? this[string name] + { + get + { + // TODO Продумать логику получения объекта + if (_storages.ContainsKey(name)) + return _storages[name]; + return null; + } + } +} diff --git a/Monorail/Monorail/FormLocomotiveCollection.Designer.cs b/Monorail/Monorail/FormLocomotiveCollection.Designer.cs new file mode 100644 index 0000000..8e1e794 --- /dev/null +++ b/Monorail/Monorail/FormLocomotiveCollection.Designer.cs @@ -0,0 +1,302 @@ +namespace Monorail +{ + partial class FormLocomotiveCollection + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + groupBoxTools = new GroupBox(); + panelCompanyTools = new Panel(); + buttonGoToCheck = new Button(); + buttonAddLocomotive = new Button(); + buttonRemoveLocomotiv = new Button(); + maskedTextBox = new MaskedTextBox(); + buttonRefresh = new Button(); + buttonAddMonorail = new Button(); + buttonCreateCompany = new Button(); + panelStorage = new Panel(); + buttonCollectionDel = new Button(); + listBoxCollection = new ListBox(); + buttonCollectionAdd = new Button(); + radioButtonList = new RadioButton(); + radioButtonMassive = new RadioButton(); + textBoxCollectionName = new TextBox(); + labelCollectionName = new Label(); + comboBoxSelectorCompany = new ComboBox(); + pictureBox = new PictureBox(); + groupBoxTools.SuspendLayout(); + panelCompanyTools.SuspendLayout(); + panelStorage.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox).BeginInit(); + SuspendLayout(); + // + // groupBoxTools + // + groupBoxTools.Controls.Add(panelCompanyTools); + groupBoxTools.Controls.Add(buttonCreateCompany); + groupBoxTools.Controls.Add(panelStorage); + groupBoxTools.Controls.Add(comboBoxSelectorCompany); + groupBoxTools.Dock = DockStyle.Right; + groupBoxTools.Location = new Point(752, 0); + groupBoxTools.Name = "groupBoxTools"; + groupBoxTools.Size = new Size(187, 572); + groupBoxTools.TabIndex = 0; + groupBoxTools.TabStop = false; + groupBoxTools.Text = "Инструменты"; + // + // panelCompanyTools + // + panelCompanyTools.Controls.Add(buttonGoToCheck); + panelCompanyTools.Controls.Add(buttonAddLocomotive); + panelCompanyTools.Controls.Add(buttonRemoveLocomotiv); + panelCompanyTools.Controls.Add(maskedTextBox); + panelCompanyTools.Controls.Add(buttonRefresh); + panelCompanyTools.Controls.Add(buttonAddMonorail); + panelCompanyTools.Dock = DockStyle.Bottom; + panelCompanyTools.Enabled = false; + panelCompanyTools.Location = new Point(3, 298); + panelCompanyTools.Name = "panelCompanyTools"; + panelCompanyTools.Size = new Size(181, 271); + panelCompanyTools.TabIndex = 9; + // + // buttonGoToCheck + // + buttonGoToCheck.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonGoToCheck.Location = new Point(13, 176); + buttonGoToCheck.Name = "buttonGoToCheck"; + buttonGoToCheck.Size = new Size(156, 39); + buttonGoToCheck.TabIndex = 5; + buttonGoToCheck.Text = "Передать на тесты"; + buttonGoToCheck.UseVisualStyleBackColor = true; + buttonGoToCheck.Click += ButtonGoToCheck_Click; + // + // buttonAddLocomotive + // + buttonAddLocomotive.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonAddLocomotive.Location = new Point(13, 12); + buttonAddLocomotive.Name = "buttonAddLocomotive"; + buttonAddLocomotive.Size = new Size(156, 39); + buttonAddLocomotive.TabIndex = 1; + buttonAddLocomotive.Text = "Добавление Локомотива"; + buttonAddLocomotive.UseVisualStyleBackColor = true; + buttonAddLocomotive.Click += ButtonAddLocomotive_Click; + // + // buttonRemoveLocomotiv + // + buttonRemoveLocomotiv.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonRemoveLocomotiv.Location = new Point(13, 131); + buttonRemoveLocomotiv.Name = "buttonRemoveLocomotiv"; + buttonRemoveLocomotiv.Size = new Size(156, 39); + buttonRemoveLocomotiv.TabIndex = 4; + buttonRemoveLocomotiv.Text = "Удаление Локомотива"; + buttonRemoveLocomotiv.UseVisualStyleBackColor = true; + buttonRemoveLocomotiv.Click += ButtonRemoveLocomotiv_Click; + // + // maskedTextBox + // + maskedTextBox.Location = new Point(13, 102); + maskedTextBox.Mask = "00"; + maskedTextBox.Name = "maskedTextBox"; + maskedTextBox.Size = new Size(156, 23); + maskedTextBox.TabIndex = 3; + maskedTextBox.ValidatingType = typeof(int); + // + // buttonRefresh + // + buttonRefresh.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonRefresh.Location = new Point(13, 221); + buttonRefresh.Name = "buttonRefresh"; + buttonRefresh.Size = new Size(156, 39); + buttonRefresh.TabIndex = 6; + buttonRefresh.Text = "Обновить"; + buttonRefresh.UseVisualStyleBackColor = true; + buttonRefresh.Click += ButtonRefresh_Click; + // + // buttonAddMonorail + // + buttonAddMonorail.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonAddMonorail.Location = new Point(13, 57); + buttonAddMonorail.Name = "buttonAddMonorail"; + buttonAddMonorail.Size = new Size(156, 39); + buttonAddMonorail.TabIndex = 2; + buttonAddMonorail.Text = "Добавление Монорельса"; + buttonAddMonorail.UseVisualStyleBackColor = true; + buttonAddMonorail.Click += ButtonAddMonorail_Click; + // + // buttonCreateCompany + // + buttonCreateCompany.Location = new Point(6, 269); + buttonCreateCompany.Name = "buttonCreateCompany"; + buttonCreateCompany.Size = new Size(169, 23); + buttonCreateCompany.TabIndex = 8; + buttonCreateCompany.Text = "Создать компанию"; + buttonCreateCompany.UseVisualStyleBackColor = true; + buttonCreateCompany.Click += ButtonCreateCompany_Click; + // + // panelStorage + // + panelStorage.Controls.Add(buttonCollectionDel); + panelStorage.Controls.Add(listBoxCollection); + panelStorage.Controls.Add(buttonCollectionAdd); + panelStorage.Controls.Add(radioButtonList); + panelStorage.Controls.Add(radioButtonMassive); + panelStorage.Controls.Add(textBoxCollectionName); + panelStorage.Controls.Add(labelCollectionName); + panelStorage.Dock = DockStyle.Top; + panelStorage.Location = new Point(3, 19); + panelStorage.Name = "panelStorage"; + panelStorage.Size = new Size(181, 215); + panelStorage.TabIndex = 7; + // + // buttonCollectionDel + // + buttonCollectionDel.Location = new Point(6, 181); + buttonCollectionDel.Name = "buttonCollectionDel"; + buttonCollectionDel.Size = new Size(169, 23); + buttonCollectionDel.TabIndex = 6; + buttonCollectionDel.Text = "Удалить коллекцию"; + buttonCollectionDel.UseVisualStyleBackColor = true; + buttonCollectionDel.Click += ButtonCollectionDel_Click; + // + // listBoxCollection + // + listBoxCollection.FormattingEnabled = true; + listBoxCollection.ItemHeight = 15; + listBoxCollection.Location = new Point(6, 111); + listBoxCollection.Name = "listBoxCollection"; + listBoxCollection.Size = new Size(169, 64); + listBoxCollection.TabIndex = 5; + // + // buttonCollectionAdd + // + buttonCollectionAdd.Location = new Point(3, 82); + buttonCollectionAdd.Name = "buttonCollectionAdd"; + buttonCollectionAdd.Size = new Size(169, 23); + buttonCollectionAdd.TabIndex = 4; + buttonCollectionAdd.Text = "Добавить коллекцию"; + buttonCollectionAdd.UseVisualStyleBackColor = true; + buttonCollectionAdd.Click += ButtonCollectionAdd_Click; + // + // radioButtonList + // + radioButtonList.AutoSize = true; + radioButtonList.Location = new Point(103, 57); + radioButtonList.Name = "radioButtonList"; + radioButtonList.Size = new Size(66, 19); + radioButtonList.TabIndex = 3; + radioButtonList.TabStop = true; + radioButtonList.Text = "Список"; + radioButtonList.UseVisualStyleBackColor = true; + // + // radioButtonMassive + // + radioButtonMassive.AutoSize = true; + radioButtonMassive.Location = new Point(12, 57); + radioButtonMassive.Name = "radioButtonMassive"; + radioButtonMassive.Size = new Size(67, 19); + radioButtonMassive.TabIndex = 2; + radioButtonMassive.TabStop = true; + radioButtonMassive.Text = "Массив"; + radioButtonMassive.UseVisualStyleBackColor = true; + // + // textBoxCollectionName + // + textBoxCollectionName.Location = new Point(3, 28); + textBoxCollectionName.Name = "textBoxCollectionName"; + textBoxCollectionName.Size = new Size(169, 23); + textBoxCollectionName.TabIndex = 1; + // + // labelCollectionName + // + labelCollectionName.AutoSize = true; + labelCollectionName.Location = new Point(30, 10); + labelCollectionName.Name = "labelCollectionName"; + labelCollectionName.Size = new Size(122, 15); + labelCollectionName.TabIndex = 0; + labelCollectionName.Text = "Название коллекции"; + // + // comboBoxSelectorCompany + // + comboBoxSelectorCompany.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + comboBoxSelectorCompany.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxSelectorCompany.FormattingEnabled = true; + comboBoxSelectorCompany.Items.AddRange(new object[] { "Хранилище" }); + comboBoxSelectorCompany.Location = new Point(6, 240); + comboBoxSelectorCompany.Name = "comboBoxSelectorCompany"; + comboBoxSelectorCompany.Size = new Size(175, 23); + comboBoxSelectorCompany.TabIndex = 0; + comboBoxSelectorCompany.SelectedIndexChanged += comboBoxSelectorCompany_SelectedIndexChanged; + // + // pictureBox + // + pictureBox.Dock = DockStyle.Fill; + pictureBox.Location = new Point(0, 0); + pictureBox.Name = "pictureBox"; + pictureBox.Size = new Size(752, 572); + pictureBox.TabIndex = 1; + pictureBox.TabStop = false; + // + // FormLocomotiveCollection + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(939, 572); + Controls.Add(pictureBox); + Controls.Add(groupBoxTools); + Name = "FormLocomotiveCollection"; + Text = "Коллекция Локомотивов"; + groupBoxTools.ResumeLayout(false); + panelCompanyTools.ResumeLayout(false); + panelCompanyTools.PerformLayout(); + panelStorage.ResumeLayout(false); + panelStorage.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox).EndInit(); + ResumeLayout(false); + } + + #endregion + + private GroupBox groupBoxTools; + private ComboBox comboBoxSelectorCompany; + private Button buttonAddMonorail; + private Button buttonAddLocomotive; + private PictureBox pictureBox; + private Button buttonGoToCheck; + private Button buttonRemoveLocomotiv; + private MaskedTextBox maskedTextBox; + private Button buttonRefresh; + private Panel panelStorage; + private Label labelCollectionName; + private TextBox textBoxCollectionName; + private RadioButton radioButtonMassive; + private RadioButton radioButtonList; + private Button buttonCollectionAdd; + private Button buttonCollectionDel; + private ListBox listBoxCollection; + private Button buttonCreateCompany; + private Panel panelCompanyTools; + } +} \ No newline at end of file diff --git a/Monorail/Monorail/FormLocomotiveCollection.cs b/Monorail/Monorail/FormLocomotiveCollection.cs new file mode 100644 index 0000000..b95be45 --- /dev/null +++ b/Monorail/Monorail/FormLocomotiveCollection.cs @@ -0,0 +1,303 @@ +using Monorail.CollectionGenericObjects; +using Monorail.Drawnings; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Monorail; + +/// +/// Форма работы с компанией и ее коллекцией +/// +public partial class FormLocomotiveCollection : Form +{ + /// + /// Хранилище коллекций + /// + private readonly StorageCollection _storageCollection; + + /// + /// Компания + /// + private AbstractCompany? _company = null; + + /// + /// Конструктор + /// + public FormLocomotiveCollection() + { + InitializeComponent(); + _storageCollection = new(); + } + + /// + /// Выбор компании + /// + /// + /// + private void comboBoxSelectorCompany_SelectedIndexChanged(object sender, EventArgs e) + { + panelCompanyTools.Enabled = false; + } + + /// + /// Добавление Локомотива + /// + /// + /// + private void ButtonAddLocomotive_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningLocomotive)); + + /// + /// Добавление Монорельса + /// + /// + /// + private void ButtonAddMonorail_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningMonorail)); + + + /// + /// Создание объекта класса-перемещения + /// + /// Тип создаваемого объекта + private void CreateObject(string type) + { + if (_company == null) + { + return; + } + DrawningLocomotive drawningLocomotive; + Random random = new(); + switch (type) + { + case nameof(DrawningLocomotive): + drawningLocomotive = new DrawningLocomotive(random.Next(100, 300), random.Next(1000, 3000), GetColor(random)); + break; + case nameof(DrawningMonorail): + // TODO выбор цветов + drawningLocomotive = new DrawningMonorail(random.Next(100, 300), random.Next(1000, 3000), + GetColor(random), GetColor(random), + Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2))); + break; + default: + return; + } + if (_company + drawningLocomotive != -1) + { + MessageBox.Show("Объект добавлен"); + pictureBox.Image = _company.Show(); + } + else + { + MessageBox.Show("Не удалось добавить объект"); + } + } + + + /// + /// Получение цвета + /// + /// Генератор случайных чисел + /// + private static Color GetColor(Random random) + { + Color color = Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)); + ColorDialog dialog = new(); + if (dialog.ShowDialog() == DialogResult.OK) + { + color = dialog.Color; + } + + return color; + } + + + + + + /// + /// Удаление объекта + /// + /// + /// + private void ButtonRemoveLocomotiv_Click(object sender, EventArgs e) + { + + if (string.IsNullOrEmpty(maskedTextBox.Text) || _company == null) + { + return; + } + + if (MessageBox.Show("Удалить объект?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + { + return; + } + + int pos = Convert.ToInt32(maskedTextBox.Text); + if (_company - pos != null) + { + MessageBox.Show("Объект удален"); + pictureBox.Image = _company.Show(); + } + else + { + MessageBox.Show("Не удалось удалить объект"); + } + + } + + + /// + /// Передача объекта в другую форму + /// + /// + /// + private void ButtonGoToCheck_Click(object sender, EventArgs e) + { + if (_company == null) + { + return; + } + + DrawningLocomotive? locomotive = null; + int counter = 100; + while (locomotive == null) + { + locomotive = _company.GetRandomObject(); + counter--; + if (counter <= 0) + { + break; + } + } + + if (locomotive == null) + { + return; + } + + FormMonorail form = new() + { + SetLocomotive = locomotive + }; + form.ShowDialog(); + } + + /// + /// Перерисовка коллекции + /// + /// + /// + private void ButtonRefresh_Click(object sender, EventArgs e) + { + if (_company == null) + { + return; + } + pictureBox.Image = _company.Show(); + } + + + /// + /// + /// + /// + /// + private void ButtonCollectionAdd_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(textBoxCollectionName.Text) || (!radioButtonList.Checked && !radioButtonMassive.Checked)) + { + MessageBox.Show("Не все данные заполнены", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + CollectionType collectionType = CollectionType.None; + if (radioButtonMassive.Checked) + { + collectionType = CollectionType.Massive; + } + else if (radioButtonList.Checked) + { + collectionType = CollectionType.List; + } + + _storageCollection.AddCollection(textBoxCollectionName.Text, collectionType); + RerfreshListBoxItems(); + } + /// + /// + /// + /// + /// + private void ButtonCollectionDel_Click(object sender, EventArgs e) + { + // TODO прописать логику удаления элемента из коллекции + // нужно убедиться, что есть выбранная коллекция + // спросить у пользователя через MessageBox, что он подтверждает, что хочет удалить запись + // удалить и обновить ListBox + if (listBoxCollection.SelectedIndex < 0 || listBoxCollection.SelectedItem == null) + { + MessageBox.Show("Коллекция не выбрана"); + return; + } + if (MessageBox.Show("Удалить коллекцию?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) + { + return; + } + _storageCollection.DelCollection(listBoxCollection.SelectedItem.ToString()); + RerfreshListBoxItems(); + } + + /// + /// Обновление списка в listBoxCollection + /// + private void RerfreshListBoxItems() + { + listBoxCollection.Items.Clear(); + for (int i = 0; i < _storageCollection.Keys?.Count; ++i) + { + string? colName = _storageCollection.Keys?[i]; + if (!string.IsNullOrEmpty(colName)) + { + listBoxCollection.Items.Add(colName); + } + } + + } + + /// + /// + /// + /// + /// + private void ButtonCreateCompany_Click(object sender, EventArgs e) + { + if (listBoxCollection.SelectedIndex < 0 || listBoxCollection.SelectedItem == null) + { + MessageBox.Show("Коллекция не выбрана"); + return; + } + + ICollectionGenericObjects? collection = _storageCollection[listBoxCollection.SelectedItem.ToString() ?? string.Empty]; + if (collection == null) + { + MessageBox.Show("Коллекция не проинициализирована"); + return; + } + + switch (comboBoxSelectorCompany.Text) + { + case "Хранилище": + _company = new LocomotiveSharingService(pictureBox.Width, pictureBox.Height, collection); + break; + } + + panelCompanyTools.Enabled = true; + RerfreshListBoxItems(); + } +} \ No newline at end of file diff --git a/Monorail/Monorail/FormLocomotiveCollection.resx b/Monorail/Monorail/FormLocomotiveCollection.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/Monorail/Monorail/FormLocomotiveCollection.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Monorail/Monorail/FormMonorail.Designer.cs b/Monorail/Monorail/FormMonorail.Designer.cs index 6c90d4f..daabc9a 100644 --- a/Monorail/Monorail/FormMonorail.Designer.cs +++ b/Monorail/Monorail/FormMonorail.Designer.cs @@ -29,12 +29,10 @@ private void InitializeComponent() { pictureBox1Monorail = new PictureBox(); - buttonCreate = new Button(); buttonLeft = new Button(); buttonDown = new Button(); buttonRight = new Button(); buttonUp = new Button(); - buttonCreateLocomotive = new Button(); comboBoxStrategy = new ComboBox(); buttonStrategyStep = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBox1Monorail).BeginInit(); @@ -49,17 +47,6 @@ pictureBox1Monorail.TabIndex = 0; pictureBox1Monorail.TabStop = false; // - // buttonCreate - // - buttonCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - buttonCreate.Location = new Point(10, 358); - buttonCreate.Name = "buttonCreate"; - buttonCreate.Size = new Size(221, 23); - buttonCreate.TabIndex = 1; - buttonCreate.Text = "создать Monorail"; - buttonCreate.UseVisualStyleBackColor = true; - buttonCreate.Click += buttonCreate_Click; - // // buttonLeft // buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; @@ -108,17 +95,6 @@ buttonUp.UseVisualStyleBackColor = true; buttonUp.Click += buttonMove_Click; // - // buttonCreateLocomotive - // - buttonCreateLocomotive.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - buttonCreateLocomotive.Location = new Point(247, 358); - buttonCreateLocomotive.Name = "buttonCreateLocomotive"; - buttonCreateLocomotive.Size = new Size(221, 23); - buttonCreateLocomotive.TabIndex = 6; - buttonCreateLocomotive.Text = "создать Locomotive"; - buttonCreateLocomotive.UseVisualStyleBackColor = true; - buttonCreateLocomotive.Click += ButtonCreateLocomotive_Click; - // // comboBoxStrategy // comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; @@ -146,12 +122,10 @@ ClientSize = new Size(755, 393); Controls.Add(buttonStrategyStep); Controls.Add(comboBoxStrategy); - Controls.Add(buttonCreateLocomotive); Controls.Add(buttonUp); Controls.Add(buttonRight); Controls.Add(buttonDown); Controls.Add(buttonLeft); - Controls.Add(buttonCreate); Controls.Add(pictureBox1Monorail); Name = "FormMonorail"; Text = "FormMonorail"; @@ -162,12 +136,10 @@ #endregion private PictureBox pictureBox1Monorail; - private Button buttonCreate; private Button buttonLeft; private Button buttonDown; private Button buttonRight; private Button buttonUp; - private Button buttonCreateLocomotive; private ComboBox comboBoxStrategy; private Button buttonStrategyStep; } diff --git a/Monorail/Monorail/FormMonorail.cs b/Monorail/Monorail/FormMonorail.cs index 24b08c4..3eb4d59 100644 --- a/Monorail/Monorail/FormMonorail.cs +++ b/Monorail/Monorail/FormMonorail.cs @@ -17,6 +17,23 @@ public partial class FormMonorail : Form /// private AbstractStrategy? _strategy; + + + /// + /// Получение объекта + /// + public DrawningLocomotive SetLocomotive + { + set + { + _drawningLocomotive = value; + _drawningLocomotive.SetPictureSize(pictureBox1Monorail.Width, pictureBox1Monorail.Height); + comboBoxStrategy.Enabled = true; + _strategy = null; + Draw(); + } + } + /// /// конструктор формы /// @@ -25,6 +42,7 @@ public partial class FormMonorail : Form InitializeComponent(); _strategy = null; } + /// /// Метод прорисовки машины /// @@ -40,15 +58,6 @@ public partial class FormMonorail : Form _drawningLocomotive.DrawTransport(gr); pictureBox1Monorail.Image = bmp; } - - - - private void FormMonorail_Load(object sender, EventArgs e) - { - - } - - /// /// Перемещение объекта по форме (нажатие кнопок навигации) /// @@ -86,7 +95,7 @@ public partial class FormMonorail : Form } /// - /// + /// Обработка нажатия кнопки "Шаг" /// /// /// @@ -127,4 +136,7 @@ public partial class FormMonorail : Form _strategy = null; } } + + + } diff --git a/Monorail/Monorail/Program.cs b/Monorail/Monorail/Program.cs index be64774..e9e2c6d 100644 --- a/Monorail/Monorail/Program.cs +++ b/Monorail/Monorail/Program.cs @@ -11,7 +11,7 @@ namespace Monorail // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - Application.Run(new FormMonorail()); + Application.Run(new FormLocomotiveCollection()); } } } \ No newline at end of file -- 2.25.1