diff --git a/Tank/Tank/AbstractStrategy.cs b/Tank/Tank/AbstractStrategy.cs new file mode 100644 index 0000000..b5acb9c --- /dev/null +++ b/Tank/Tank/AbstractStrategy.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tank.MovementStrategy +{ + /// + /// Класс-стратегия перемещения объекта + /// + public abstract class AbstractStrategy + { + /// + /// Перемещаемый объект + /// + private IMoveableObject? _moveableObject; + /// + /// Статус перемещения + /// + private Status _state = Status.NotInit; + + /// + /// Ширина поля + /// + protected int FieldWidth { get; private set; } + /// + /// Высота поля + /// + protected int FieldHeight { get; private set; } + /// + /// Статус перемещения + /// + public Status GetStatus() { return _state; } + /// + /// Установка данных + /// + /// Перемещаемый объект + /// Ширина поля + /// Высота поля + public void SetData(IMoveableObject moveableObject, int width, int + height) + { + if (moveableObject == null) + { + _state = Status.NotInit; + return; + } + _state = Status.InProgress; + _moveableObject = moveableObject; + FieldWidth = width; + FieldHeight = height; + } + /// + /// Шаг перемещения + /// + public void MakeStep() + { + if (_state != Status.InProgress) + { + return; + } + if (IsTargetDestinaion()) + { + _state = Status.Finish; + return; + } + MoveToTarget(); + } + /// + /// Перемещение влево + /// + /// Результат перемещения (true - удалось переместиться, false - + // неудача) + protected bool MoveLeft() => MoveTo(Direction.Left); + /// + /// Перемещение вправо + /// + /// Результат перемещения (true - удалось переместиться, + // false - неудача) + protected bool MoveRight() => MoveTo(Direction.Right); + /// + /// Перемещение вверх + /// + /// Результат перемещения (true - удалось переместиться, + // false - неудача) + protected bool MoveUp() => MoveTo(Direction.Up); + /// + /// Перемещение вниз + /// + /// Результат перемещения (true - удалось переместиться, + // false - неудача) + protected bool MoveDown() => MoveTo(Direction.Down); + /// + /// Параметры объекта + /// + protected ObjectParameters? GetObjectParameters => + _moveableObject?.GetObjectPosition; + /// + /// Шаг объекта + /// + /// + protected int? GetStep() + { + if (_state != Status.InProgress) + { + return null; + } + return _moveableObject?.GetStep; + } + /// + /// Перемещение к цели + /// + protected abstract void MoveToTarget(); + /// + /// Достигнута ли цель + /// + /// + protected abstract bool IsTargetDestinaion(); + /// + /// Попытка перемещения в требуемом направлении + /// + /// Направление + /// Результат попытки (true - удалось переместиться, false - + // неудача) + private bool MoveTo(Direction directionType) + { + if (_state != Status.InProgress) + { + return false; + } + if (_moveableObject?.CheckCanMove(directionType) ?? false) + { + _moveableObject.MoveObject(directionType); + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/Tank/Tank/DrawingArmoredCar.cs b/Tank/Tank/DrawingArmoredCar.cs new file mode 100644 index 0000000..3e53db0 --- /dev/null +++ b/Tank/Tank/DrawingArmoredCar.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tank.Entites; + +namespace Tank.DrawingObjects +{ + /// Класс, отвечающий за прорисовку и перемещение объекта-сущности + public class DrawingArmoredCar + { + /// Класс-сущность + public EntityArmoredCar? EntityArmoredCar { get; protected set; } + public EntityArmoredCar? Tank { get; protected set; } + /// Координата X объекта + public int GetPosX => _startPosX; + /// Координата Y объекта + public int GetPosY => _startPosY; + /// Ширина объекта + public int GetWidth => _ArmoredcarWidth; + /// Высота объекта + public int GetHeight => _ArmoredcarHeight; + /// Ширина окна + private int _pictureWidth; + /// Высота окна + private int _pictureHeight; + /// Левая координата прорисовки автомобиля + protected int _startPosX; + /// Верхняя кооридната прорисовки автомобиля + protected int _startPosY; + /// Ширина прорисовки автомобиля + protected readonly int _ArmoredcarWidth = 100; + /// Высота прорисовки автомобиля + protected readonly int _ArmoredcarHeight = 55; + /// Конструктор + /// Скорость + /// Вес + /// Основной цвет + /// Ширина картинки + /// Высота картинки + public DrawingArmoredCar(int speed, double weight, Color bodyColor, int + width, int height) + { + _pictureWidth = width; + _pictureHeight = height; + //EntityArmoredCar = new EntityArmoredCar(speed, weight, bodyColor); + if (_pictureHeight < _ArmoredcarHeight || _pictureWidth < _ArmoredcarWidth) + { + return; + } + Tank = new EntityArmoredCar(speed, weight, bodyColor); + } + /// Конструктор + /// Скорость + /// Вес + /// Основной цвет + /// Ширина картинки + /// Высота картинки + /// Ширина прорисовки автомобиля + /// Высота прорисовки автомобиля + protected DrawingArmoredCar(int speed, double weight, Color bodyColor, int + width, int height, int tankWidth, int tankHeight) + { + _pictureWidth = width; + _pictureHeight = height; + _ArmoredcarWidth = tankWidth; + _ArmoredcarHeight = tankHeight; + // EntityArmoredCar = new EntityArmoredCar(speed, weight, bodyColor); + if (_pictureHeight < _ArmoredcarHeight || _pictureWidth < _ArmoredcarWidth) + { + return; + } + Tank = new EntityArmoredCar(speed, weight, bodyColor); + } + /// Установка позиции + /// Координата X + /// Координата Y + + public void SetPosition(int x, int y) + { + // TODO: Изменение x, y, если при установке объект выходит зaf границы + + _startPosX = x; + _startPosY = y; + } + /// Проверка, что объект может переместится по указанному направлению + /// true - можно переместится по указанному + /// направлению + public bool CanMove(Direction direction) + { + if (EntityArmoredCar == null) + { + return false; + } + return direction switch + { + Direction.Left => _startPosX - EntityArmoredCar.Step > 0, + Direction.Up => _startPosY - EntityArmoredCar.Step > 0, + Direction.Right => _startPosX + _ArmoredcarWidth + EntityArmoredCar.Step < _pictureWidth, + Direction.Down => _startPosX + _ArmoredcarHeight + EntityArmoredCar.Step < _pictureHeight, + _ => false, + }; + } + + /// Изменение направления перемещения + public void MoveTransport(Direction direction) + { + if (EntityArmoredCar == null) + { + return; + } + switch (direction) + { + case Direction.Left: + if (_startPosX - EntityArmoredCar.Step > 0) + { + _startPosX -= (int)EntityArmoredCar.Step; + } + break; + case Direction.Up: + if (_startPosY - EntityArmoredCar.Step > 0) + { + _startPosY -= (int)EntityArmoredCar.Step; + } + break; + case Direction.Right: + if (_startPosX + EntityArmoredCar.Step + _ArmoredcarWidth < _pictureWidth) + { + _startPosX += (int)EntityArmoredCar.Step; + } + break; + case Direction.Down: + if (_startPosY + EntityArmoredCar.Step + _ArmoredcarHeight < _pictureHeight) + { + _startPosY += (int)EntityArmoredCar.Step; + } + break; + } + } + /// Прорисовка объекта + public virtual void DrawTransport(Graphics g) + { + if (EntityArmoredCar == null) + { + return; + } + + //кузов + Brush br = new SolidBrush(EntityArmoredCar.BodyColor); + g.FillRectangle(br, _startPosX + 10, _startPosY + 15, 10, 30); + + + // не мое + Brush BrushRandom = new SolidBrush(EntityArmoredCar?.BodyColor ?? Color.Black); + + + // Корпус + Point[] pointsbody = { new Point(_startPosX + 5, _startPosY + 30), new Point(_startPosX + 110, _startPosY + 30), + new Point(_startPosX + 142, _startPosY + 30), new Point(_startPosX + 120, _startPosY + 45), new Point(_startPosX + 12, _startPosY + 45) }; + g.FillPolygon(BrushRandom, pointsbody); + + // Колеса, катки + Brush ColorBlack = new SolidBrush(Color.Black); + g.FillEllipse(ColorBlack, 10 + _startPosX, 42 + _startPosY, 20, 20); + g.FillEllipse(ColorBlack, 35 + _startPosX, 42 + _startPosY, 20, 20); + g.FillEllipse(ColorBlack, 60 + _startPosX, 42 + _startPosY, 20, 20); + g.FillEllipse(ColorBlack, 85 + _startPosX, 42 + _startPosY, 20, 20); + g.FillEllipse(ColorBlack, 110 + _startPosX, 42 + _startPosY, 20, 20); + + } + } +} diff --git a/Tank/Tank/DrawingObjectArmoredCar.cs b/Tank/Tank/DrawingObjectArmoredCar.cs new file mode 100644 index 0000000..457a477 --- /dev/null +++ b/Tank/Tank/DrawingObjectArmoredCar.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tank.DrawingObjects; + +namespace Tank.MovementStrategy +{ + /// Реализация интерфейса IDrawningObject для работы с объектом DrawningCar + /// (паттерн Adapter) + public class DrawningObjectArmoredCar : IMoveableObject + { + private readonly DrawingArmoredCar? _drawningArmoredCar = null; + public DrawningObjectArmoredCar(DrawingArmoredCar drawningArmoredCar) + { + _drawningArmoredCar = drawningArmoredCar; + } + public ObjectParameters? GetObjectPosition + { + get + { + if (_drawningArmoredCar == null || _drawningArmoredCar.EntityArmoredCar == + null) + { + return null; + } + return new ObjectParameters(_drawningArmoredCar.GetPosX, + _drawningArmoredCar.GetPosY, _drawningArmoredCar.GetWidth, _drawningArmoredCar.GetHeight); + } + } + public int GetStep => (int)(_drawningArmoredCar?.EntityArmoredCar?.Step ?? 0); + public bool CheckCanMove(Direction direction) => + _drawningArmoredCar?.CanMove(direction) ?? false; + public void MoveObject(Direction direction) => + _drawningArmoredCar?.MoveTransport(direction); + } +} diff --git a/Tank/Tank/DrawingTank.cs b/Tank/Tank/DrawingTank.cs index a92ada5..08311c2 100644 --- a/Tank/Tank/DrawingTank.cs +++ b/Tank/Tank/DrawingTank.cs @@ -4,141 +4,53 @@ using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tank.Entites; -namespace Tank +namespace Tank.DrawingObjects { - /// /// Класс, отвечающий за прорисовку и перемещение объекта-сущности - /// - public class DrawningTank + public class DrawingTank : DrawingArmoredCar { - /// - /// Класс-сущность - /// - public EntityTank? EntityTank { get; private set; } - /// - /// Ширина окна - /// - private int _pictureWidth = 900; - /// - /// Высота окна - /// - private int _pictureHeight = 500; - /// - /// Левая координата прорисовки автомобиля - /// - private int _startPosX; - /// - /// Верхняя кооридната прорисовки автомобиля - /// - private int _startPosY; - /// - /// Ширина прорисовки автомобиля - /// - private readonly int _tankWidth = 110; - /// - /// Высота прорисовки автомобиля - /// - private readonly int _tankHeight = 60; - /// - /// Инициализация свойств - /// + /// Конструктор /// Скорость /// Вес - /// Цвет кузова + /// Основной цвет /// Дополнительный цвет /// Признак наличия обвеса - /// Признак наличия антикрыла + /// Признак наличия антикрыла /// Признак наличия гоночной полосы /// Ширина картинки /// Высота картинки - /// true - объект создан, false - проверка не пройдена, - /// нельзя создать объект в этих размерах - public bool Init(int speed, double weight, Color bodyColor, Color - additionalColor, bool bodyKit, bool trunk, bool sportLine, int width, int height) + public DrawingTank(int speed, double weight, Color bodyColor, Color + additionalColor, bool bodyKit, bool wing, bool sportLine, int width, int height) : + base(speed, weight, bodyColor, width, height, 110, 60) { - // TODO: Продумать проверки - if (width > _tankWidth && height > _tankHeight && speed > 0 && weight > 0) + if (Tank != null) { - _pictureWidth = width; - _pictureHeight = height; - EntityTank = new EntityTank(); - EntityTank.Init(speed, weight, bodyColor, additionalColor, - bodyKit, trunk, sportLine); - return true; - } - return false; - } - /// - /// Установка позиции - /// - /// Координата X - /// Координата Y - public void SetPosition(int x, int y) - { - // проверки - if (x >= 0 && x + _tankWidth <= _pictureWidth && - y >= 0 && y + _tankHeight <= _pictureHeight) - { - _startPosX = x; - _startPosY = y; + Tank = new EntityTank(speed, weight, bodyColor, + additionalColor, bodyKit, wing, sportLine); } } - /// - /// Изменение направления перемещения - /// - /// Направление - public void MoveTransport(Direction direction) + ///// Установка позиции + //public void SetPosition(int x, int y) + //{ + // if (x >= 0 && x + _tankWidth <= _pictureWidth && + // y >= 0 && y + _tankHeight <= _pictureHeight) + // { + // _startPosX = x; + // _startPosY = y; + // } + //} + public override void DrawTransport(Graphics g) { - if (EntityTank == null) - { - return; - } - switch (direction) - { - //влево - case Direction.Left: - if (_startPosX - EntityTank.Step > 0) - { - _startPosX -= (int)EntityTank.Step; - } - break; - //вверх - case Direction.Up: - if (_startPosY - EntityTank.Step > 0) - { - _startPosY -= (int)EntityTank.Step; - } - break; - // вправо - case Direction.Right: - if (_startPosX + EntityTank.Step + _tankWidth < _pictureWidth) - { - _startPosX += (int)EntityTank.Step; - } - break; - //вниз - case Direction.Down: - if (_startPosY + EntityTank.Step + _tankHeight < _pictureHeight) - { - _startPosY += (int)EntityTank.Step; - } - break; - } - } - /// - /// Прорисовка объекта - /// - /// - public void DrawTransport(Graphics g) - { - if (EntityTank == null) + if (Tank is not EntityTank ArmoredCar) { return; } + // base.DrawTransport(g); Pen pen = new(Color.Black); Brush additionalBrush = new - SolidBrush(EntityTank.AdditionalColor); + SolidBrush(ArmoredCar.AdditionalColor); // гусеница Rectangle Caterpillar = new Rectangle(_startPosX + 2, _startPosY + 35, 16, 22); float startAngle_Caterpillar = 90; @@ -166,7 +78,7 @@ namespace Tank g.FillEllipse(brBlack, _startPosX + 75, _startPosY + 32, 10, 10); //кузов - Brush br = new SolidBrush(EntityTank.BodyColor); + Brush br = new SolidBrush(ArmoredCar.BodyColor); g.FillRectangle(br, _startPosX + 5, _startPosY + 17, 110, 18); g.FillRectangle(br, _startPosX + 30, _startPosY, 50, 15); @@ -186,22 +98,22 @@ namespace Tank g.DrawRectangle(pen, _startPosX + 80, _startPosY + 3, 25, 5); g.DrawRectangle(pen, _startPosX + 40, _startPosY - 10, 20, 5); - // обвесы - if (EntityTank.BodyKit) - { - Brush brAdd = new SolidBrush(EntityTank.AdditionalColor); + //// обвесы + //if (Tank.BodyKit) // entityTank + //{ + // Brush brAdd = new SolidBrush(EntityTank.AdditionalColor); - g.FillRectangle(brAdd, _startPosX + 5, _startPosY + 17, 20, 18); - g.FillRectangle(brAdd, _startPosX + 95, _startPosY + 17, 20, 18); - g.DrawRectangle(pen, _startPosX + 5, _startPosY + 17, 20, 18); - g.DrawRectangle(pen, _startPosX + 95, _startPosY + 17, 20, 18); + // g.FillRectangle(brAdd, _startPosX + 5, _startPosY + 17, 20, 18); + // g.FillRectangle(brAdd, _startPosX + 95, _startPosY + 17, 20, 18); + // g.DrawRectangle(pen, _startPosX + 5, _startPosY + 17, 20, 18); + // g.DrawRectangle(pen, _startPosX + 95, _startPosY + 17, 20, 18); - g.FillRectangle(brAdd, _startPosX + 100, _startPosY + 4, 5, 4); + // g.FillRectangle(brAdd, _startPosX + 100, _startPosY + 4, 5, 4); - } + //} //// спортивная линия - //if (EntityTank.SportLine) + //if (Tank.SportLine) //{ // g.FillRectangle(additionalBrush, _startPosX + 75, // _startPosY + 23, 25, 15); @@ -210,12 +122,58 @@ namespace Tank // g.FillRectangle(additionalBrush, _startPosX + 10, // _startPosY + 23, 20, 15); //} - // багажник - if (EntityTank.Trunk) - { - g.FillRectangle(additionalBrush, _startPosX + 23, _startPosY + 4, 8, 10); - g.DrawRectangle(pen, _startPosX + 23, _startPosY + 4 , 8, 10); - } + + //// багажник + //if (EntityTank.Trunk) // Tank + //{ + // g.FillRectangle(additionalBrush, _startPosX + 23, _startPosY + 4, 8, 10); + // g.DrawRectangle(pen, _startPosX + 23, _startPosY + 4, 8, 10); + //} + + + /// + // /// Инициализация свойств + // /// + // /// Скорость + // /// Вес + // /// Цвет кузова + // /// Дополнительный цвет + // /// Признак наличия обвеса + // /// Признак наличия антикрыла + // /// Признак наличия гоночной полосы + // /// Ширина картинки + // /// Высота картинки + // /// true - объект создан, false - проверка не пройдена, + // /// нельзя создать объект в этих размерах + // public bool Init(int speed, double weight, Color bodyColor, Color + //additionalColor, bool bodyKit, bool trunk, bool sportLine, int width, int height) + //{ + // // TODO: Продумать проверки + // if (width > _tankWidth && height > _tankHeight && speed > 0 && weight > 0) + // { + // _pictureWidth = width; + // _pictureHeight = height; + // EntityTank = new EntityTank(); + // EntityTank.Init(speed, weight, bodyColor, additionalColor, + // bodyKit, trunk, sportLine); + // return true; + // } + // return false; + //} + ///// + + /// + /// Прорисовка объекта + /// + /// + //public void DrawTransport(Graphics g) + //{ + // if (EntityTank == null) + // { + // return; + // } + // + } diff --git a/Tank/Tank/EntityArmoredCar.cs b/Tank/Tank/EntityArmoredCar.cs new file mode 100644 index 0000000..81a0640 --- /dev/null +++ b/Tank/Tank/EntityArmoredCar.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tank.Entites +{ + /// Класс-сущность "Бронированная машина" + public class EntityArmoredCar + { + /// Скорость + public int Speed { get; set; } + /// Вес + public double Weight { get; set; } + /// Основной цвет + public Color BodyColor { get; set; } + /// Шаг перемещения автомобиля + public double Step => (double)Speed * 300 / Weight; + /// Конструктор с параметрами + /// Скорость + /// Вес автомобиля + /// Основной цвет + public EntityArmoredCar(int speed, double weight, Color bodyColor) + { + Speed = speed; + Weight = weight; + BodyColor = bodyColor; + } + + } +} diff --git a/Tank/Tank/EntityTank.cs b/Tank/Tank/EntityTank.cs index 35be974..fbe4cd4 100644 --- a/Tank/Tank/EntityTank.cs +++ b/Tank/Tank/EntityTank.cs @@ -4,45 +4,27 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Tank +namespace Tank.Entites { - public class EntityTank + public class EntityTank : EntityArmoredCar { - /// /// Скорость - /// public int Speed { get; private set; } - /// /// Вес - /// - public double Weight { get; private set; } - /// + // public double Weight { get; private set; } /// Основной цвет - /// - public Color BodyColor { get; private set; } - /// + // public Color BodyColor { get; private set; } /// Дополнительный цвет (для опциональных элементов) - /// public Color AdditionalColor { get; private set; } - /// - /// Признак (опция) наличия обвеса - /// + // Признак (опция) наличия обвеса public bool BodyKit { get; private set; } - /// - /// Признак (опция) наличия Багажника - /// + // Признак (опция) наличия Багажника public bool Trunk { get; private set; } - /// - /// Признак (опция) наличия гоночной полосы - /// + // Признак (опция) наличия гоночной полосы public bool SportLine { get; private set; } - /// - /// Шаг перемещения танка - /// - public double Step => (double)Speed * 200 / Weight; - /// + // Шаг перемещения танка + // public double Step => (double)Speed * 200 / Weight; /// Инициализация полей объекта-класса спортивного автомобиля - /// /// Скорость /// Вес Танка /// Основной цвет @@ -50,12 +32,9 @@ namespace Tank /// Признак наличия обвеса /// Признак наличия багажника /// Признак наличия гоночной полосы - public void Init(int speed, double weight, Color bodyColor, Color - additionalColor, bool bodyKit, bool trunk, bool sportLine) + public EntityTank(int speed, double weight, Color bodyColor, Color + additionalColor, bool bodyKit, bool trunk, bool sportLine) : base(speed, weight, bodyColor) { - Speed = speed; - Weight = weight; - BodyColor = bodyColor; AdditionalColor = additionalColor; BodyKit = bodyKit; Trunk = trunk; diff --git a/Tank/Tank/FormTank.Designer.cs b/Tank/Tank/FormTank.Designer.cs index 58c303f..2fd9343 100644 --- a/Tank/Tank/FormTank.Designer.cs +++ b/Tank/Tank/FormTank.Designer.cs @@ -34,6 +34,9 @@ this.buttonLeft = new System.Windows.Forms.Button(); this.buttonDown = new System.Windows.Forms.Button(); this.buttonRight = new System.Windows.Forms.Button(); + this.buttonCreateArmoredCar = new System.Windows.Forms.Button(); + this.buttonStep = new System.Windows.Forms.Button(); + this.comboBoxStrategy = new System.Windows.Forms.ComboBox(); ((System.ComponentModel.ISupportInitialize)(this.pictureBoxTank)).BeginInit(); this.SuspendLayout(); // @@ -52,9 +55,9 @@ // this.buttonCreate.Location = new System.Drawing.Point(26, 417); this.buttonCreate.Name = "buttonCreate"; - this.buttonCreate.Size = new System.Drawing.Size(75, 23); + this.buttonCreate.Size = new System.Drawing.Size(97, 23); this.buttonCreate.TabIndex = 1; - this.buttonCreate.Text = "Создать"; + this.buttonCreate.Text = "Создать Танк"; this.buttonCreate.UseVisualStyleBackColor = true; this.buttonCreate.Click += new System.EventHandler(this.buttonCreate_Click); // @@ -102,11 +105,47 @@ this.buttonRight.UseVisualStyleBackColor = true; this.buttonRight.Click += new System.EventHandler(this.buttonMove_Click); // + // buttonCreateArmoredCar + // + this.buttonCreateArmoredCar.Location = new System.Drawing.Point(129, 417); + this.buttonCreateArmoredCar.Name = "buttonCreateArmoredCar"; + this.buttonCreateArmoredCar.Size = new System.Drawing.Size(210, 23); + this.buttonCreateArmoredCar.TabIndex = 7; + this.buttonCreateArmoredCar.Text = "Создать Бронированную машину\r\n"; + this.buttonCreateArmoredCar.UseVisualStyleBackColor = true; + this.buttonCreateArmoredCar.Click += new System.EventHandler(this.buttonCreateArmoredCar_Click); + // + // buttonStep + // + this.buttonStep.Location = new System.Drawing.Point(752, 74); + this.buttonStep.Name = "buttonStep"; + this.buttonStep.Size = new System.Drawing.Size(75, 23); + this.buttonStep.TabIndex = 9; + this.buttonStep.Text = "Шаг"; + this.buttonStep.UseVisualStyleBackColor = true; + this.buttonStep.Click += new System.EventHandler(this.buttonStep_Click); + // + // comboBoxStrategy + // + this.comboBoxStrategy.FormattingEnabled = true; + this.comboBoxStrategy.Items.AddRange(new object[] { + "1", + "2", + "3", + "4"}); + this.comboBoxStrategy.Location = new System.Drawing.Point(725, 45); + this.comboBoxStrategy.Name = "comboBoxStrategy"; + this.comboBoxStrategy.Size = new System.Drawing.Size(121, 23); + this.comboBoxStrategy.TabIndex = 10; + // // FormTank // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(884, 461); + this.Controls.Add(this.comboBoxStrategy); + this.Controls.Add(this.buttonStep); + this.Controls.Add(this.buttonCreateArmoredCar); this.Controls.Add(this.buttonRight); this.Controls.Add(this.buttonDown); this.Controls.Add(this.buttonLeft); @@ -131,5 +170,8 @@ private Button buttonLeft; private Button buttonDown; private Button buttonRight; + private Button buttonCreateArmoredCar; + private Button buttonStep; + private ComboBox comboBoxStrategy; } } \ No newline at end of file diff --git a/Tank/Tank/FormTank.cs b/Tank/Tank/FormTank.cs index 12f09f4..b18af0a 100644 --- a/Tank/Tank/FormTank.cs +++ b/Tank/Tank/FormTank.cs @@ -1,3 +1,6 @@ +using Tank.DrawingObjects; +using Tank.MovementStrategy; + namespace Tank { /// @@ -5,34 +8,31 @@ namespace Tank /// public partial class FormTank : Form { - /// /// - - /// - private DrawningTank? _drawningTank; - /// + // private DrawningArmoredCar? _drawningArmoredCar; + private DrawingArmoredCar? _Tank; + /// + private AbstractStrategy? _abstractStrategy; /// - /// public FormTank() { InitializeComponent(); } - /// /// - /// private void Draw() { - if (_drawningTank == null) + if (_Tank == null) // _drawingArmoredCar { return; } Bitmap bmp = new(pictureBoxTank.Width, pictureBoxTank.Height); Graphics gr = Graphics.FromImage(bmp); - _drawningTank.DrawTransport(gr); + _Tank.DrawTransport(gr); pictureBoxTank.Image = bmp; } /// - /// "" + /// " " /// /// /// @@ -50,29 +50,21 @@ namespace Tank private void buttonCreate_Click(object sender, EventArgs e) { Random random = new(); - _drawningTank = new DrawningTank(); - _drawningTank.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)), + _Tank = new DrawingTank(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)), Convert.ToBoolean(random.Next(0, 2)), - Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2)), pictureBoxTank.Width, pictureBoxTank.Height); - _drawningTank.SetPosition(random.Next(10, 100), + _Tank.SetPosition(random.Next(10, 100), random.Next(10, 100)); Draw(); } - /// - /// - /// - /// - /// + private void buttonMove_Click(object sender, EventArgs e) { - if (_drawningTank == null) + if (_Tank == null) { return; } @@ -80,20 +72,69 @@ namespace Tank switch (name) { case "buttonUp": - _drawningTank.MoveTransport(Direction.Up); + _Tank.MoveTransport(Direction.Up); break; case "buttonDown": - _drawningTank.MoveTransport(Direction.Down); + _Tank.MoveTransport(Direction.Down); break; case "buttonLeft": - _drawningTank.MoveTransport(Direction.Left); + _Tank.MoveTransport(Direction.Left); break; case "buttonRight": - _drawningTank.MoveTransport(Direction.Right); + _Tank.MoveTransport(Direction.Right); break; } Draw(); } + // " " + private void buttonCreateArmoredCar_Click(object sender, EventArgs e) + { + Random random = new(); + _Tank = new DrawingArmoredCar(random.Next(100,300), random.Next(1000,3000), + Color.FromArgb(random.Next(0,256), random.Next(0,256), random.Next(0,256)), + pictureBoxTank.Width, pictureBoxTank.Height); + + _Tank.SetPosition(random.Next(10, 100), random.Next(10, 100)); + Draw(); + } + + private void buttonStep_Click(object sender, EventArgs e) + { + if (_Tank == null) + { + return; + } + if (comboBoxStrategy.Enabled) + { + _abstractStrategy = comboBoxStrategy.SelectedIndex + switch + { + 0 => new MoveToCenter(), + 1 => new MoveToBorder(), + _ => null, + }; + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.SetData(new + DrawningObjectArmoredCar(_Tank), pictureBoxTank.Width, + pictureBoxTank.Height); + comboBoxStrategy.Enabled = false; + } + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.MakeStep(); + Draw(); + if (_abstractStrategy.GetStatus() == Status.Finish) + { + comboBoxStrategy.Enabled = true; + _abstractStrategy = null; + } + + } } } \ No newline at end of file diff --git a/Tank/Tank/IMoveableObject.cs b/Tank/Tank/IMoveableObject.cs new file mode 100644 index 0000000..6155166 --- /dev/null +++ b/Tank/Tank/IMoveableObject.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tank.DrawingObjects; + +namespace Tank.MovementStrategy +{ + /// Интерфейс для работы с перемещаемым объектом + public interface IMoveableObject + { + /// Получение координаты X объекта + ObjectParameters? GetObjectPosition { get; } + /// Шаг объекта + int GetStep { get; } + /// Проверка, можно ли переместиться по нужному направлению + bool CheckCanMove(Direction direction); + /// Изменение направления пермещения объекта + void MoveObject(Direction direction); + } +} diff --git a/Tank/Tank/MoveToBorder.cs b/Tank/Tank/MoveToBorder.cs new file mode 100644 index 0000000..2a802d1 --- /dev/null +++ b/Tank/Tank/MoveToBorder.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tank.MovementStrategy +{ + /// Стратегия перемещения объекта в центр экрана + public class MoveToBorder : AbstractStrategy + { + protected override bool IsTargetDestinaion() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + return objParams.RightBorder + GetStep() >= FieldWidth && objParams.DownBorder + GetStep() >= FieldHeight; + } + protected override void MoveToTarget() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return; + } + var diffX = objParams.RightBorder - FieldWidth; + + var diffY = objParams.DownBorder - FieldHeight; + if (Math.Abs(diffY) > GetStep()) + { + if (diffX > 0) + { + MoveDown(); + } + else if (diffY > 0) + { + MoveRight(); + } + else if (Math.Abs(diffX) > Math.Abs(diffY)) + { + MoveRight(); + } + else + { + MoveDown(); + } + } + } + } +} diff --git a/Tank/Tank/MoveToCenter.cs b/Tank/Tank/MoveToCenter.cs new file mode 100644 index 0000000..b3570c5 --- /dev/null +++ b/Tank/Tank/MoveToCenter.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tank.MovementStrategy +{ + /// Стратегия перемещения объекта в центр экрана + public class MoveToCenter : AbstractStrategy + { + protected override bool IsTargetDestinaion() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + return objParams.ObjectMiddleHorizontal <= FieldWidth / 2 && + objParams.ObjectMiddleHorizontal + GetStep() >= FieldWidth / 2 && + objParams.ObjectMiddleVertical <= FieldHeight / 2 && + objParams.ObjectMiddleVertical + GetStep() >= FieldHeight / 2; + } + protected override void MoveToTarget() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return; + } + var diffX = objParams.ObjectMiddleHorizontal - FieldWidth / 2; + if (Math.Abs(diffX) > GetStep()) + { + if (diffX > 0) + { + MoveLeft(); + } + else + { + MoveRight(); + } + } + var diffY = objParams.ObjectMiddleVertical - FieldHeight / 2; + if (Math.Abs(diffY) > GetStep()) + { + if (diffY > 0) + { + MoveUp(); + } + else + { + MoveDown(); + } + } + } + } +} diff --git a/Tank/Tank/ObjectParameters.cs b/Tank/Tank/ObjectParameters.cs new file mode 100644 index 0000000..f277013 --- /dev/null +++ b/Tank/Tank/ObjectParameters.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tank.MovementStrategy +{ + /// Параметры-координаты объекта + public class ObjectParameters + { + private readonly int _x; + private readonly int _y; + private readonly int _width; + private readonly int _height; + /// Левая граница + public int LeftBorder => _x; + /// Верхняя граница + public int TopBorder => _y; + /// Правая граница + public int RightBorder => _x + _width; + /// Нижняя граница + public int DownBorder => _y + _height; + /// Середина объекта + public int ObjectMiddleHorizontal => _x + _width / 2; + /// Середина объекта + public int ObjectMiddleVertical => _y + _height / 2; + /// Конструктор + public ObjectParameters(int x, int y, int width, int height) + { + _x = x; + _y = y; + _width = width; + _height = height; + } + } +} diff --git a/Tank/Tank/Status.cs b/Tank/Tank/Status.cs new file mode 100644 index 0000000..fb5ca21 --- /dev/null +++ b/Tank/Tank/Status.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tank.MovementStrategy +{ + /// Статус выполнения операции перемещения + public enum Status + { + NotInit, + InProgress, + Finish + + } +} diff --git a/Tank/Tank/Tank.csproj b/Tank/Tank/Tank.csproj index 13ee123..b9e8e53 100644 --- a/Tank/Tank/Tank.csproj +++ b/Tank/Tank/Tank.csproj @@ -23,4 +23,10 @@ + + + + + + \ No newline at end of file