Compare commits

..

No commits in common. "7595185259507ef9fe786be82fa7a9fc26a39b84" and "dcc4f2c688c35e8cac2b65cc2ae29edc47e7fbe5" have entirely different histories.

16 changed files with 152 additions and 783 deletions

View File

@ -4,12 +4,13 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace SelfPropelledArtilleryUnit.MovementStrategy; namespace SelfPropelledArtilleryUnit;
public enum MovementDirection public enum DirectionType
{ {
Up = 1, Up = 1,
Down = 2, Down = 2,
Left = 3, Left = 3,
Right = 4 Right = 4
} }

View File

@ -1,18 +1,13 @@
using SelfPropelledArtilleryUnit.Entities; namespace SelfPropelledArtilleryUnit;
using System; /// <summary>
using System.Collections.Generic; /// Класс, отвечающий за прорисовку и перемещение объекта-сущности
using System.Linq; /// </summary>
using System.Text; public class DrawningArtillery
using System.Threading.Tasks;
namespace SelfPropelledArtilleryUnit.Drawnings;
public class DrawningTank
{ {
/// <summary> /// <summary>
/// Класс-сущность /// Класс-сущность
/// </summary> /// </summary>
public EntityTank? EntityTank { get; protected set; } public EntityArtillery? EntityArtillery { get; private set; }
/// <summary> /// <summary>
/// Ширина окна /// Ширина окна
/// </summary> /// </summary>
@ -24,58 +19,39 @@ public class DrawningTank
/// <summary> /// <summary>
/// Левая координата прорисовки автомобиля /// Левая координата прорисовки автомобиля
/// </summary> /// </summary>
protected private int? _startPosX; private int? _startPosX;
/// <summary> /// <summary>
/// Верхняя кооридната прорисовки автомобиля /// Верхняя кооридната прорисовки автомобиля
/// </summary> /// </summary>
protected private int? _startPosY; private int? _startPosY;
/// <summary> /// <summary>
/// Ширина прорисовки автомобиля /// Ширина прорисовки автомобиля
/// </summary> /// </summary>
private readonly int _drawningTankWidth = 130; private readonly int _drawningArtilleryWidth = 130;
/// <summary> /// <summary>
/// Высота прорисовки автомобиля /// Высота прорисовки автомобиля
/// </summary> /// </summary>
private readonly int _drawningTankHeight = 70; private readonly int _drawningArtilleryHeight = 70;
/// <summary> /// <summary>
/// Пустой конструктор /// Инициализация свойств
/// </summary> /// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodyColor">Основной цвет</param>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="cannon">Признак наличия пушки</param>
/// <param name="rocket">Признак наличия залповой установки</param>
/// <summary> public void Init(int speed, double weight, Color bodyColor, Color
/// Координата X объекта additionalColor, bool cannon, bool rocket)
/// </summary>
public int? GetPosX => _startPosX;
/// <summary>
/// Координата Y объекта
/// </summary>
public int? GetPosY => _startPosY;
/// <summary>
/// Ширина объекта
/// </summary>
public int GetWidth => _drawningTankWidth;
/// <summary>
/// Высота объекта
/// </summary>
public int GetHeight => _drawningTankHeight;
private DrawningTank()
{ {
EntityArtillery = new EntityArtillery();
EntityArtillery.Init(speed, weight, bodyColor, additionalColor, cannon, rocket);
_pictureWidth = null; _pictureWidth = null;
_pictureHeight = null; _pictureHeight = null;
_startPosX = null; _startPosX = null;
_startPosY = null; _startPosY = null;
} }
public DrawningTank(int speed, double weight, Color bodyColor) : this()
{
EntityTank = new EntityTank(speed, weight, bodyColor);
}
protected DrawningTank(int drawningTankWidth, int drawningTankHeight) : this()
{
_drawningTankWidth = drawningTankWidth;
_pictureHeight = drawningTankHeight;
}
/// <summary> /// <summary>
/// Установка границ поля /// Установка границ поля
/// </summary> /// </summary>
@ -84,7 +60,7 @@ public class DrawningTank
/// <returns>true - границы заданы, false - проверка не пройдена, нельзя разместить объект в этих размерах</returns> /// <returns>true - границы заданы, false - проверка не пройдена, нельзя разместить объект в этих размерах</returns>
public bool SetPictureSize(int width, int height) public bool SetPictureSize(int width, int height)
{ {
if (_drawningTankHeight > height || _drawningTankWidth > width) if (_drawningArtilleryHeight > height || _drawningArtilleryWidth > width)
{ {
return false; return false;
} }
@ -112,18 +88,18 @@ public class DrawningTank
} }
// TODO если при установке объекта в эти координаты, он будет "выходить" за границы формы // TODO если при установке объекта в эти координаты, он будет "выходить" за границы формы
// то надо изменить координаты, чтобы он оставался в этих границах // то надо изменить координаты, чтобы он оставался в этих границах
if (x < 0 || x + _drawningTankWidth > _pictureWidth) if (x < 0 || x + _drawningArtilleryWidth > _pictureWidth)
{ {
_startPosX = _pictureWidth - _drawningTankWidth; _startPosX = _pictureWidth - _drawningArtilleryWidth;
} }
else else
{ {
_startPosX = x; _startPosX = x;
} }
if (y < 0 || y + _drawningTankHeight > _pictureHeight) if (y < 0 || y + _drawningArtilleryHeight > _pictureHeight)
{ {
_startPosY = _pictureHeight - _drawningTankHeight; _startPosY = _pictureHeight - _drawningArtilleryHeight;
} }
else else
{ {
@ -137,7 +113,7 @@ public class DrawningTank
/// <returns>true - перемещене выполнено, false - перемещение невозможно</returns> /// <returns>true - перемещене выполнено, false - перемещение невозможно</returns>
public bool MoveTransport(DirectionType direction) public bool MoveTransport(DirectionType direction)
{ {
if (EntityTank == null || !_startPosX.HasValue || if (EntityArtillery == null || !_startPosX.HasValue ||
!_startPosY.HasValue) !_startPosY.HasValue)
{ {
return false; return false;
@ -146,31 +122,31 @@ public class DrawningTank
{ {
//влево //влево
case DirectionType.Left: case DirectionType.Left:
if (_startPosX.Value - EntityTank.Step > 0) if (_startPosX.Value - EntityArtillery.Step > 0)
{ {
_startPosX -= (int)EntityTank.Step; _startPosX -= (int)EntityArtillery.Step;
} }
return true; return true;
//вверх //вверх
case DirectionType.Up: case DirectionType.Up:
if (_startPosY.Value - EntityTank.Step > 0) if (_startPosY.Value - EntityArtillery.Step > 0)
{ {
_startPosY -= (int)EntityTank.Step; _startPosY -= (int)EntityArtillery.Step;
} }
return true; return true;
// вправо // вправо
case DirectionType.Right: case DirectionType.Right:
if (_startPosX.Value + EntityTank.Step + _drawningTankWidth < _pictureWidth) if (_startPosX.Value + EntityArtillery.Step + _drawningArtilleryWidth < _pictureWidth)
{ {
_startPosX += (int)EntityTank.Step; _startPosX += (int)EntityArtillery.Step;
} }
return true; return true;
//вниз //вниз
case DirectionType.Down: case DirectionType.Down:
if (_startPosY.Value + EntityTank.Step + _drawningTankHeight < _pictureHeight) if (_startPosY.Value + EntityArtillery.Step + _drawningArtilleryHeight < _pictureHeight)
{ {
_startPosY += (int)EntityTank.Step; _startPosY += (int)EntityArtillery.Step;
} }
return true; return true;
default: default:
@ -181,16 +157,18 @@ public class DrawningTank
/// Прорисовка объекта /// Прорисовка объекта
/// </summary> /// </summary>
/// <param name="g"></param> /// <param name="g"></param>
public virtual void DrawTransport(Graphics g) public void DrawTransport(Graphics g)
{ {
if (EntityTank == null || !_startPosX.HasValue || if (EntityArtillery == null || !_startPosX.HasValue ||
!_startPosY.HasValue) !_startPosY.HasValue)
{ {
return; return;
} }
Pen pen = new(Color.Black); Pen pen = new(Color.Black);
Brush brush = new SolidBrush(EntityTank.BodyColor); Brush additionalBrush = new
SolidBrush(EntityArtillery.AdditionalColor);
Brush brush = new SolidBrush(EntityArtillery.BodyColor);
Brush grayBrush = new SolidBrush(Color.Gray); Brush grayBrush = new SolidBrush(Color.Gray);
Brush blackBrush = new SolidBrush(Color.Black); Brush blackBrush = new SolidBrush(Color.Black);
//тело //тело
@ -198,8 +176,8 @@ public class DrawningTank
g.DrawRectangle(pen, _startPosX.Value, _startPosY.Value + 40, 110, 20); g.DrawRectangle(pen, _startPosX.Value, _startPosY.Value + 40, 110, 20);
//башня //башня
g.FillRectangle(brush, _startPosX.Value + 30, _startPosY.Value + 20, 50, 20); g.FillRectangle(brush, _startPosX.Value+30, _startPosY.Value+20,50,20);
g.DrawRectangle(pen, _startPosX.Value + 30, _startPosY.Value + 20, 50, 20); g.DrawRectangle(pen, _startPosX.Value+30, _startPosY.Value + 20, 50, 20);
//ходовая //ходовая
//основа //основа
g.DrawEllipse(pen, _startPosX.Value, _startPosY.Value + 50, 110, 20); g.DrawEllipse(pen, _startPosX.Value, _startPosY.Value + 50, 110, 20);
@ -227,7 +205,25 @@ public class DrawningTank
//6-ПравБол //6-ПравБол
g.DrawEllipse(pen, _startPosX.Value + 7, _startPosY.Value + 52, 15, 15); g.DrawEllipse(pen, _startPosX.Value + 7, _startPosY.Value + 52, 15, 15);
g.FillEllipse(blackBrush, _startPosX.Value + 7, _startPosY.Value + 52, 15, 15); g.FillEllipse(blackBrush, _startPosX.Value + 7, _startPosY.Value + 52, 15, 15);
//орудие
if (EntityArtillery.Cannon)
{
g.FillRectangle(additionalBrush, _startPosX.Value+80, _startPosY.Value + 25, 50, 5);
g.DrawRectangle(pen, _startPosX.Value+80, _startPosY.Value + 25, 50, 5);
}
//установка
if (EntityArtillery.Cannon)
{
//колонна
g.FillRectangle(additionalBrush, _startPosX.Value +5, _startPosY.Value + 10, 5, 30);
g.DrawRectangle(pen, _startPosX.Value +5, _startPosY.Value + 10, 5, 30);
//контейнер
g.FillRectangle(additionalBrush, _startPosX.Value + 3, _startPosY.Value + 5, 50, 13);
g.DrawRectangle(pen, _startPosX.Value + 3, _startPosY.Value + 5, 50, 13);
//ракеты
g.DrawRectangle(pen, _startPosX.Value + 52, _startPosY.Value + 5, 10, 3);
g.DrawRectangle(pen, _startPosX.Value + 52, _startPosY.Value + 10, 10, 3);
g.DrawRectangle(pen, _startPosX.Value + 52, _startPosY.Value + 15, 10, 3);
}
} }
} }

View File

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SelfPropelledArtilleryUnit.Drawnings;
public enum DirectionType
{
/// <summary>
/// Неизвестное направление
/// </summary>
Unknow = -1,
Up = 1,
Down = 2,
Left = 3,
Right = 4
}

View File

@ -1,58 +0,0 @@
using SelfPropelledArtilleryUnit.Entities;
namespace SelfPropelledArtilleryUnit.Drawnings;
/// <summary>
/// Класс, отвечающий за прорисовку и перемещение объекта-сущности
/// </summary>
public class DrawningArtillery : DrawningTank
{
/// <summary>
/// конструктор
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodyColor">Основной цвет</param>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="cannon">Признак наличия пушки</param>
/// <param name="rocket">Признак наличия залповой установки</param>
public DrawningArtillery(int speed, double weight, Color bodyColor, Color additionalColor, bool cannon, bool rocket) : base(130,70)
{
EntityTank = new EntityArtillery(speed, weight, bodyColor, additionalColor, cannon, rocket);
}
public override void DrawTransport(Graphics g)
{
if (EntityTank == null || EntityTank is not EntityArtillery artillery || !_startPosX.HasValue || !_startPosY.HasValue)
{
return;
}
Pen pen = new(Color.Black);
Brush additionalBrush = new SolidBrush(artillery.AdditionalColor);
//орудие
if (artillery.Cannon)
{
g.FillRectangle(additionalBrush, _startPosX.Value + 80, _startPosY.Value + 25, 50, 5);
g.DrawRectangle(pen, _startPosX.Value + 80, _startPosY.Value + 25, 50, 5);
}
//установка
if (artillery.Cannon)
{
//колонна
g.FillRectangle(additionalBrush, _startPosX.Value + 5, _startPosY.Value + 10, 5, 30);
g.DrawRectangle(pen, _startPosX.Value + 5, _startPosY.Value + 10, 5, 30);
//контейнер
g.FillRectangle(additionalBrush, _startPosX.Value + 3, _startPosY.Value + 5, 50, 13);
g.DrawRectangle(pen, _startPosX.Value + 3, _startPosY.Value + 5, 50, 13);
//ракеты
g.DrawRectangle(pen, _startPosX.Value + 52, _startPosY.Value + 5, 10, 3);
g.DrawRectangle(pen, _startPosX.Value + 52, _startPosY.Value + 10, 10, 3);
g.DrawRectangle(pen, _startPosX.Value + 52, _startPosY.Value + 15, 10, 3);
}
base.DrawTransport(g);
}
}

View File

@ -1,39 +0,0 @@
namespace SelfPropelledArtilleryUnit.Entities;
/// <summary>
/// Класс-сущность "САУ"
/// </summary>
public class EntityArtillery : EntityTank
{
/// <summary>
/// Дополнительный цвет (для опциональных элементов)
/// </summary>
public Color AdditionalColor { get; private set; }
/// <summary>
/// Признак (опция) наличия пушки
/// </summary>
public bool Cannon { get; private set; }
/// <summary>
/// Признак (опция) наличия залповой установки
/// </summary>
public bool Rocket { get; private set; }
/// <summary>
/// Инициализация полей объекта-класса спортивного автомобиля
/// </summary>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="cannon">Признак наличия пушки</param>
/// <param name="rocket">Признак наличия залповой установки</param>
public EntityArtillery(int speed, double weight, Color bodyColor, Color additionalColor, bool cannon, bool rocket) : base(speed, weight, bodyColor)
{
AdditionalColor = additionalColor;
Cannon = cannon;
Rocket = rocket;
}
}

View File

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

View File

@ -0,0 +1,60 @@
namespace SelfPropelledArtilleryUnit;
/// <summary>
/// Класс-сущность "САУ"
/// </summary>
public class EntityArtillery
{
/// <summary>
/// Скорость
/// </summary>
public int Speed { get; private set; }
/// <summary>
/// Вес
/// </summary>
public double Weight { get; private set; }
/// <summary>
/// Основной цвет
/// </summary>
public Color BodyColor { get; private set; }
/// <summary>
/// Дополнительный цвет (для опциональных элементов)
/// </summary>
public Color AdditionalColor { get; private set; }
/// <summary>
/// Признак (опция) наличия пушки
/// </summary>
public bool Cannon { get; private set; }
/// <summary>
/// Признак (опция) наличия залповой установки
/// </summary>
public bool Rocket { get; private set; }
/// <summary>
/// Шаг перемещения автомобиля
/// </summary>
public double Step => Speed * 100 / Weight;
/// <summary>
/// Инициализация полей объекта-класса спортивного автомобиля
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес автомобиля</param>
/// <param name="bodyColor">Основной цвет</param>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="cannon">Признак наличия пушки</param>
/// <param name="rocket">Признак наличия залповой установки</param>
public void Init(int speed, double weight, Color bodyColor, Color
additionalColor, bool cannon, bool rocket)
{
Speed = speed;
Weight = weight;
BodyColor = bodyColor;
AdditionalColor = additionalColor;
Cannon = cannon;
Rocket = rocket;
}
}

View File

@ -35,9 +35,6 @@
buttonUp = new Button(); buttonUp = new Button();
buttonDown = new Button(); buttonDown = new Button();
buttonRight = new Button(); buttonRight = new Button();
buttonCreateTank = new Button();
comboBoxStrategy = new ComboBox();
buttonStrategyStep = new Button();
((System.ComponentModel.ISupportInitialize)pictureBoxArtillery).BeginInit(); ((System.ComponentModel.ISupportInitialize)pictureBoxArtillery).BeginInit();
SuspendLayout(); SuspendLayout();
// //
@ -55,9 +52,9 @@
buttonCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; buttonCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonCreate.Location = new Point(12, 417); buttonCreate.Location = new Point(12, 417);
buttonCreate.Name = "buttonCreate"; buttonCreate.Name = "buttonCreate";
buttonCreate.Size = new Size(90, 23); buttonCreate.Size = new Size(75, 23);
buttonCreate.TabIndex = 1; buttonCreate.TabIndex = 1;
buttonCreate.Text = "Создать САУ"; buttonCreate.Text = "Создать";
buttonCreate.UseVisualStyleBackColor = true; buttonCreate.UseVisualStyleBackColor = true;
buttonCreate.Click += ButtonCreate_Click; buttonCreate.Click += ButtonCreate_Click;
// //
@ -109,45 +106,11 @@
buttonRight.UseVisualStyleBackColor = true; buttonRight.UseVisualStyleBackColor = true;
buttonRight.Click += ButtonMove_Click; buttonRight.Click += ButtonMove_Click;
// //
// buttonCreateTank
//
buttonCreateTank.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonCreateTank.Location = new Point(117, 417);
buttonCreateTank.Name = "buttonCreateTank";
buttonCreateTank.Size = new Size(138, 23);
buttonCreateTank.TabIndex = 6;
buttonCreateTank.Text = "Создать самоходку";
buttonCreateTank.UseVisualStyleBackColor = true;
buttonCreateTank.Click += ButtonCreateTank_Click;
//
// comboBoxStrategy
//
comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxStrategy.FormattingEnabled = true;
comboBoxStrategy.Items.AddRange(new object[] { "К центру", "К краю" });
comboBoxStrategy.Location = new Point(679, 12);
comboBoxStrategy.Name = "comboBoxStrategy";
comboBoxStrategy.Size = new Size(121, 23);
comboBoxStrategy.TabIndex = 7;
//
// buttonStrategyStep
//
buttonStrategyStep.Location = new Point(719, 41);
buttonStrategyStep.Name = "buttonStrategyStep";
buttonStrategyStep.Size = new Size(75, 23);
buttonStrategyStep.TabIndex = 8;
buttonStrategyStep.Text = "Шаг";
buttonStrategyStep.UseVisualStyleBackColor = true;
buttonStrategyStep.Click += ButtonStrategyStep_Click;
//
// FormArtillery // FormArtillery
// //
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 461); ClientSize = new Size(800, 461);
Controls.Add(buttonStrategyStep);
Controls.Add(comboBoxStrategy);
Controls.Add(buttonCreateTank);
Controls.Add(buttonRight); Controls.Add(buttonRight);
Controls.Add(buttonDown); Controls.Add(buttonDown);
Controls.Add(buttonUp); Controls.Add(buttonUp);
@ -168,8 +131,5 @@
private Button buttonUp; private Button buttonUp;
private Button buttonDown; private Button buttonDown;
private Button buttonRight; private Button buttonRight;
private Button buttonCreateTank;
private ComboBox comboBoxStrategy;
private Button buttonStrategyStep;
} }
} }

View File

@ -7,82 +7,51 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using SelfPropelledArtilleryUnit.Drawnings;
using SelfPropelledArtilleryUnit.MovementStrategy;
namespace SelfPropelledArtilleryUnit namespace SelfPropelledArtilleryUnit
{ {
public partial class FormArtillery : Form public partial class FormArtillery : Form
{ {
/// <summary> private DrawningArtillery? _drawningArtillery;
/// Поле-объект для прорисовки объекта
/// </summary>
private DrawningTank? _drawningTank;
/// <summary>
/// Стратегия перемещения
/// </summary>
private AbstractStrategy? _strategy;
public FormArtillery() public FormArtillery()
{ {
InitializeComponent(); InitializeComponent();
_strategy = null;
} }
private void Draw() private void Draw()
{ {
if (_drawningTank == null) if (_drawningArtillery == null)
{ {
return; return;
} }
Bitmap bmp = new(pictureBoxArtillery.Width, pictureBoxArtillery.Height); Bitmap bmp = new(pictureBoxArtillery.Width, pictureBoxArtillery.Height);
Graphics gr = Graphics.FromImage(bmp); Graphics gr = Graphics.FromImage(bmp);
_drawningTank.DrawTransport(gr); _drawningArtillery.DrawTransport(gr);
pictureBoxArtillery.Image = bmp; pictureBoxArtillery.Image = bmp;
} }
private void CreateObject(string type)
private void ButtonCreate_Click(object sender, EventArgs e)
{ {
Random random = new(); Random random = new();
switch (type) _drawningArtillery = new DrawningArtillery();
{ _drawningArtillery.Init(random.Next(100, 300), random.Next(1000, 3000),
case nameof(DrawningTank):
_drawningTank = new DrawningTank(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(DrawningArtillery):
_drawningTank = new DrawningArtillery(random.Next(100, 300), random.Next(1000, 3000),
Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)),
Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)),
Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2))); Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2)));
break;
default: _drawningArtillery.SetPictureSize(pictureBoxArtillery.Width, pictureBoxArtillery.Height);
return; _drawningArtillery.SetPosition(random.Next(10, 100), random.Next(10, 100));
}
_drawningTank.SetPictureSize(pictureBoxArtillery.Width, pictureBoxArtillery.Height);
_drawningTank.SetPosition(random.Next(10, 100), random.Next(10, 100));
_strategy = null;
comboBoxStrategy.Enabled = true;
Draw(); Draw();
} }
/// <summary>
/// Обработка нажатия кнопки "Создать сау"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCreate_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningArtillery));
/// <summary>
/// Обработка нажатия кнопки "Создать самоходку"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCreateTank_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningTank));
private void ButtonMove_Click(object sender, EventArgs e) private void ButtonMove_Click(object sender, EventArgs e)
{ {
if (_drawningTank == null) if (_drawningArtillery == null)
{ {
return; return;
} }
@ -92,16 +61,16 @@ namespace SelfPropelledArtilleryUnit
switch (name) switch (name)
{ {
case "buttonUp": case "buttonUp":
result = _drawningTank.MoveTransport(DirectionType.Up); result = _drawningArtillery.MoveTransport(DirectionType.Up);
break; break;
case "buttonDown": case "buttonDown":
result = _drawningTank.MoveTransport(DirectionType.Down); result = _drawningArtillery.MoveTransport(DirectionType.Down);
break; break;
case "buttonLeft": case "buttonLeft":
result = _drawningTank.MoveTransport(DirectionType.Left); result = _drawningArtillery.MoveTransport(DirectionType.Left);
break; break;
case "buttonRight": case "buttonRight":
result = _drawningTank.MoveTransport(DirectionType.Right); result = _drawningArtillery.MoveTransport(DirectionType.Right);
break; break;
} }
@ -110,47 +79,5 @@ namespace SelfPropelledArtilleryUnit
Draw(); Draw();
} }
} }
/// <summary>
/// Обработка нажатия кнопки "Шаг"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonStrategyStep_Click(object sender, EventArgs e)
{
if (_drawningTank == null)
{
return;
}
if (comboBoxStrategy.Enabled)
{
_strategy = comboBoxStrategy.SelectedIndex switch
{
0 => new MoveToCenter(),
1 => new MoveToBorder(),
_ => null,
};
if (_strategy == null)
{
return;
}
_strategy.SetData(new MoveableTank(_drawningTank), pictureBoxArtillery.Width, pictureBoxArtillery.Height);
}
if (_strategy == null)
{
return;
}
comboBoxStrategy.Enabled = false;
_strategy.MakeStep();
Draw();
if (_strategy.GetStatus() == StrategyStatus.Finish)
{
comboBoxStrategy.Enabled = true;
_strategy = null;
}
}
} }
} }

View File

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

View File

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

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SelfPropelledArtilleryUnit.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.DownBorder;
if (y + GetStep() < FieldHeight) MoveDown();
}
}

View File

@ -1,57 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SelfPropelledArtilleryUnit.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();
}
}
}
}

View File

@ -1,56 +0,0 @@
using SelfPropelledArtilleryUnit.Drawnings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SelfPropelledArtilleryUnit.MovementStrategy;
public class MoveableTank : IMoveableObject
{
private readonly DrawningTank? _tank;
public MoveableTank(DrawningTank tank)
{
_tank = tank;
}
public ObjectParameters? GetObjectPosition
{
get
{
if (_tank == null || _tank.EntityTank == null || !_tank.GetPosX.HasValue || !_tank.GetPosY.HasValue)
{
return null;
}
return new ObjectParameters(_tank.GetPosX.Value, _tank.GetPosY.Value, _tank.GetWidth, _tank.GetHeight);
}
}
public int GetStep => (int)(_tank?.EntityTank?.Step ?? 0);
public bool TryMoveObject(MovementDirection direction)
{
if (_tank == null || _tank.EntityTank == null)
{
return false;
}
return _tank.MoveTransport(GetDirectionType(direction));
}
/// <summary>
/// Конвертация из MovementDirection в DirectionType
/// </summary>
/// <param name="direction">MovementDirection</param>
/// <returns>DirectionType</returns>
private static DirectionType GetDirectionType(MovementDirection direction)
{
return direction switch
{
MovementDirection.Left => DirectionType.Left,
MovementDirection.Right => DirectionType.Right,
MovementDirection.Up => DirectionType.Up,
MovementDirection.Down => DirectionType.Down,
_ => DirectionType.Unknow,
};
}
}

View File

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

View File

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SelfPropelledArtilleryUnit.MovementStrategy;
public enum StrategyStatus
{
/// <summary>
/// Все готово к началу
/// </summary>
NotInit,
/// <summary>
/// Выполняется
/// </summary>
InProgress,
/// <summary>
/// Завершено
/// </summary>
Finish
}