diff --git a/lab1/AbstractStrategy.cs b/lab1/AbstractStrategy.cs new file mode 100644 index 0000000..926e0e2 --- /dev/null +++ b/lab1/AbstractStrategy.cs @@ -0,0 +1,79 @@ +namespace ElectricLocomotive; + +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(); + } + + protected bool MoveLeft() => MoveTo(DirectionType.Left); + + protected bool MoveRight() => MoveTo(DirectionType.Right); + + protected bool MoveUp() => MoveTo(DirectionType.Up); + + protected bool MoveDown() => MoveTo(DirectionType.Down); + + protected ObjectParameters? GetObjectParameters => +_moveableObject?.GetObjectPosition; + + protected int? GetStep() + { + if (_state != Status.InProgress) + { + return null; + } + return _moveableObject?.GetStep; + } + + protected abstract void MoveToTarget(); + + protected abstract bool IsTargetDestinaion(); + + private bool MoveTo(DirectionType 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/lab1/DrawingElectricLocomotiv.cs b/lab1/DrawingElectricLocomotiv.cs new file mode 100644 index 0000000..8782739 --- /dev/null +++ b/lab1/DrawingElectricLocomotiv.cs @@ -0,0 +1,28 @@ +namespace ElectricLocomotive; + +public class DrawingElectricLocomotiv : DrawingLocomotiv +{ + public DrawingElectricLocomotiv(int speed, double weight, int width, int height) : base(speed, weight, width, + height) + { + if (EntityLocomotiv != null) + { + EntityLocomotiv = new EntityElectricLocomotiv(speed, weight, Color.Crimson, Color.Blue); + } + } + + public override void DrawLoco(Graphics g) + { + if (EntityLocomotiv == null) return; + base.DrawLoco(g); + if (EntityLocomotiv is not EntityElectricLocomotiv electricLocomotiv) return; + SolidBrush batteryBrush = new(electricLocomotiv.BatteryColor); + Pen rogaPen = new(electricLocomotiv.RogaColor); + //Roga + g.DrawLine(rogaPen, new Point(_startPosX + _vehicleWidth / 2, _startPosY + 30), new Point(_startPosX + _vehicleWidth / 2 + 10, _startPosY + 15)); + g.DrawLine(rogaPen, new Point(_startPosX + _vehicleWidth / 2 + 10, _startPosY + 15), new Point(_startPosX + _vehicleWidth / 2, _startPosY)); + //battery + Point[] batteryPoints = { new Point(_startPosX + _vehicleWidth - 10,_startPosY + _vehicleHeight - 25), new Point(_startPosX + _vehicleWidth, _startPosY + _vehicleHeight - 20), new Point(_startPosX + _vehicleWidth, _startPosY + _vehicleHeight - 55), new Point(_startPosX + _vehicleWidth - 10, _startPosY + _vehicleHeight - 50) }; + g.FillPolygon(batteryBrush, batteryPoints); + } +} \ No newline at end of file diff --git a/lab1/DrawingLocomotiv.cs b/lab1/DrawingLocomotiv.cs index 054f22d..7941506 100644 --- a/lab1/DrawingLocomotiv.cs +++ b/lab1/DrawingLocomotiv.cs @@ -10,24 +10,47 @@ namespace ElectricLocomotive { public class DrawingLocomotiv { - public EntityLocomotiv? EntityLocomotiv { get; private set; } - private int _pictureWidth; - private int _pictureHeight; - private int _startPosX; - private int _startPosY; - private readonly int _vehicleWidth = 170; - private readonly int _vehicleHeight = 110; - - public bool Init(int speed, double weight,int width,int height) + public EntityLocomotiv? EntityLocomotiv { get; protected set; } + protected int _pictureWidth; + protected int _pictureHeight; + public int GetPosX => _startPosX; + public int GetPosY => _startPosY; + public int GetWidth => _vehicleWidth; + public int GetHeight => _vehicleHeight; + protected int _startPosX; + protected int _startPosY; + protected readonly int _vehicleWidth = 170; + protected readonly int _vehicleHeight = 110; + + public DrawingLocomotiv(int speed, double weight,int width,int height) { if (width <= _vehicleWidth || height <= _vehicleHeight) { - return false; + return; } _pictureWidth = width; _pictureHeight = height; - EntityLocomotiv = new EntityLocomotiv(); - EntityLocomotiv.Init(speed, weight); - return true; + EntityLocomotiv = new EntityLocomotiv(speed, weight); + } + protected DrawingLocomotiv(int speed, double weight,int width,int height, int vehicleHeight, int vehicleWidth) + { + if (width <= _vehicleWidth || height <= _vehicleHeight) { + return; + } + _pictureWidth = width; + _pictureHeight = height; + EntityLocomotiv = new EntityLocomotiv(speed, weight); + } + public bool CanMove(DirectionType direction) + { + if (EntityLocomotiv == null) + return false; + return direction switch + { + DirectionType.Left => _startPosX - EntityLocomotiv.Step > 0, + DirectionType.Up => _startPosY - EntityLocomotiv.Step > 0, + DirectionType.Right => _startPosX + EntityLocomotiv.Step < _pictureWidth, + DirectionType.Down => _startPosY -+ EntityLocomotiv.Step < _pictureHeight + }; } public void SetPosition(int x,int y) { @@ -72,21 +95,18 @@ namespace ElectricLocomotive break; } } - public void DrawLoco(Graphics g) + public virtual void DrawLoco(Graphics g) { if (EntityLocomotiv == null) return; Pen penBody = new(EntityLocomotiv.ColorBody, 3); Pen penWindow = new(EntityLocomotiv.ColorWindow, 3); SolidBrush doorBrush = new(EntityLocomotiv.ColorFillBody); Pen penWheel = new(EntityLocomotiv.ColorBody, 2); - SolidBrush batteryBrush = new(EntityLocomotiv.ColorBody); + //Body g.DrawRectangle(penBody, _startPosX, _startPosY + _vehicleHeight - 50, _vehicleWidth - 10, _vehicleHeight - 80); Point[] upBodyPoints = { new Point(_startPosX, _startPosY + 60), new Point(_startPosX + 10, _startPosY + 30), new Point(_startPosX + 150, _startPosY + 30), new Point(_startPosX + 160, _startPosY + 60) }; g.DrawPolygon(penBody, upBodyPoints); - //Roga - g.DrawLine(penBody, new Point(_startPosX + _vehicleWidth / 2, _startPosY + 30), new Point(_startPosX + _vehicleWidth / 2 + 10, _startPosY + 15)); - g.DrawLine(penBody, new Point(_startPosX + _vehicleWidth / 2 + 10, _startPosY + 15), new Point(_startPosX + _vehicleWidth / 2, _startPosY)); //Door g.DrawRectangle(penBody, _startPosX + _vehicleWidth / 2 - 15, _startPosY + 45, _vehicleWidth / 10, _vehicleHeight / 2 - 10); g.FillRectangle(doorBrush, _startPosX + _vehicleWidth / 2 - 14, _startPosY + 46, _vehicleWidth / 10 - 1, _vehicleHeight / 2 - 12); @@ -112,9 +132,6 @@ namespace ElectricLocomotive g.DrawEllipse(penWheel, xWheel, yWheel, 20, 20); xWheel += 40; } - //battery - Point[] batteryPoints = { new Point(_startPosX + _vehicleWidth - 10,_startPosY + _vehicleHeight - 25), new Point(_startPosX + _vehicleWidth, _startPosY + _vehicleHeight - 20), new Point(_startPosX + _vehicleWidth, _startPosY + _vehicleHeight - 55), new Point(_startPosX + _vehicleWidth - 10, _startPosY + _vehicleHeight - 50) }; - g.FillPolygon(batteryBrush, batteryPoints); } } } diff --git a/lab1/DrawingObjectLocomotiv.cs b/lab1/DrawingObjectLocomotiv.cs new file mode 100644 index 0000000..4ea7020 --- /dev/null +++ b/lab1/DrawingObjectLocomotiv.cs @@ -0,0 +1,29 @@ +namespace ElectricLocomotive; + +public class DrawingObjectLocomotiv : IMoveableObject +{ + private readonly DrawingLocomotiv? _drawingLocomotiv = null; + + public DrawingObjectLocomotiv(DrawingLocomotiv drawingLocomotiv) + { + _drawingLocomotiv = drawingLocomotiv; + } + public ObjectParameters? GetObjectPosition + { + get + { + if (_drawingLocomotiv == null || _drawingLocomotiv.EntityLocomotiv == + null) + { + return null; + } + return new ObjectParameters(_drawingLocomotiv.GetPosX, + _drawingLocomotiv.GetPosY, _drawingLocomotiv.GetWidth, _drawingLocomotiv.GetHeight); + } + } + public int GetStep => (int)(_drawingLocomotiv?.EntityLocomotiv?.Step ?? 0); + public bool CheckCanMove(DirectionType direction) => + _drawingLocomotiv?.CanMove(direction) ?? false; + public void MoveObject(DirectionType direction) => + _drawingLocomotiv?.MoveTransport(direction); +} \ No newline at end of file diff --git a/lab1/EntityElectricLocomotiv.cs b/lab1/EntityElectricLocomotiv.cs new file mode 100644 index 0000000..9d034eb --- /dev/null +++ b/lab1/EntityElectricLocomotiv.cs @@ -0,0 +1,12 @@ +namespace ElectricLocomotive; + +public class EntityElectricLocomotiv : EntityLocomotiv +{ + public Color BatteryColor { get; private set; } + public Color RogaColor { get; private set; } + public EntityElectricLocomotiv(int speed,double weight, Color batteryColor, Color rogaColor) : base(speed, weight) + { + BatteryColor = batteryColor; + RogaColor = rogaColor; + } +} \ No newline at end of file diff --git a/lab1/EntityLocomotiv.cs b/lab1/EntityLocomotiv.cs index 996ab24..c876dd6 100644 --- a/lab1/EntityLocomotiv.cs +++ b/lab1/EntityLocomotiv.cs @@ -15,7 +15,8 @@ namespace ElectricLocomotive public readonly Color ColorBody = Color.Black; public readonly Color ColorWindow = Color.Blue; public readonly Color ColorFillBody = Color.White; - public void Init(int speed,double weight) + + public EntityLocomotiv(int speed,double weight) { Speed = speed; Weight = weight; diff --git a/lab1/IMoveableObject.cs b/lab1/IMoveableObject.cs new file mode 100644 index 0000000..9edf66b --- /dev/null +++ b/lab1/IMoveableObject.cs @@ -0,0 +1,12 @@ +namespace ElectricLocomotive; + +public interface IMoveableObject +{ + ObjectParameters? GetObjectPosition { get; } + + int GetStep { get; } + + bool CheckCanMove(DirectionType direction); + + void MoveObject(DirectionType direction); +} \ No newline at end of file diff --git a/lab1/MainForm.Designer.cs b/lab1/MainForm.Designer.cs index 449a465..795c365 100644 --- a/lab1/MainForm.Designer.cs +++ b/lab1/MainForm.Designer.cs @@ -33,7 +33,10 @@ moveDownButton = new Button(); moveLeftButton = new Button(); moveUpButton = new Button(); - paintObjectButton = new Button(); + paintLocoButton = new Button(); + paintElectricLocoButton = new Button(); + movesBox = new ComboBox(); + moveButton = new Button(); ((System.ComponentModel.ISupportInitialize)locoBox).BeginInit(); SuspendLayout(); // @@ -56,7 +59,7 @@ moveRightButton.TabIndex = 4; moveRightButton.Text = "Вправо"; moveRightButton.UseVisualStyleBackColor = true; - moveRightButton.Click += MoveButton_Click; + moveRightButton.Click += MoveSideButton_Click; // // moveDownButton // @@ -67,7 +70,7 @@ moveDownButton.TabIndex = 3; moveDownButton.Text = "Вниз"; moveDownButton.UseVisualStyleBackColor = true; - moveDownButton.Click += MoveButton_Click; + moveDownButton.Click += MoveSideButton_Click; // // moveLeftButton // @@ -78,7 +81,7 @@ moveLeftButton.TabIndex = 2; moveLeftButton.Text = "Влево"; moveLeftButton.UseVisualStyleBackColor = true; - moveLeftButton.Click += MoveButton_Click; + moveLeftButton.Click += MoveSideButton_Click; // // moveUpButton // @@ -89,28 +92,60 @@ moveUpButton.TabIndex = 1; moveUpButton.Text = "Вверх"; moveUpButton.UseVisualStyleBackColor = true; - moveUpButton.Click += MoveButton_Click; + moveUpButton.Click += MoveSideButton_Click; // - // paintObjectButton + // paintLocoButton // - paintObjectButton.Location = new Point(36, 643); - paintObjectButton.Name = "paintObjectButton"; - paintObjectButton.Size = new Size(161, 68); - paintObjectButton.TabIndex = 0; - paintObjectButton.Text = "Нарисовать"; - paintObjectButton.UseVisualStyleBackColor = true; - paintObjectButton.Click += PaintObjectButton_click; + paintLocoButton.Location = new Point(36, 643); + paintLocoButton.Name = "paintLocoButton"; + paintLocoButton.Size = new Size(179, 68); + paintLocoButton.TabIndex = 0; + paintLocoButton.Text = "Нарисовать локомотив"; + paintLocoButton.UseVisualStyleBackColor = true; + paintLocoButton.Click += PaintLocoButton_click; + // + // paintElectricLocoButton + // + paintElectricLocoButton.Location = new Point(250, 647); + paintElectricLocoButton.Name = "paintElectricLocoButton"; + paintElectricLocoButton.Size = new Size(189, 64); + paintElectricLocoButton.TabIndex = 5; + paintElectricLocoButton.Text = "Нарисовать электровоз"; + paintElectricLocoButton.UseVisualStyleBackColor = true; + paintElectricLocoButton.Click += PaintElectricLocoButton_click; + // + // movesBox + // + movesBox.FormattingEnabled = true; + movesBox.Items.AddRange(new object[] { "Довести до края", "Довести до центра" }); + movesBox.Location = new Point(1093, 12); + movesBox.Name = "movesBox"; + movesBox.Size = new Size(151, 28); + movesBox.TabIndex = 6; + // + // moveButton + // + moveButton.Location = new Point(1093, 58); + moveButton.Name = "moveButton"; + moveButton.Size = new Size(151, 29); + moveButton.TabIndex = 7; + moveButton.Text = "Шаг"; + moveButton.UseVisualStyleBackColor = true; + moveButton.Click += MoveButton_Click; // // MainForm // AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(1265, 731); + Controls.Add(moveButton); + Controls.Add(movesBox); + Controls.Add(paintElectricLocoButton); Controls.Add(moveRightButton); Controls.Add(moveDownButton); Controls.Add(moveLeftButton); Controls.Add(moveUpButton); - Controls.Add(paintObjectButton); + Controls.Add(paintLocoButton); Controls.Add(locoBox); FormBorderStyle = FormBorderStyle.FixedSingle; Name = "MainForm"; @@ -122,11 +157,14 @@ } #endregion - private Button paintObjectButton; + private Button paintLocoButton; private Button moveRightButton; private Button moveDownButton; private Button moveLeftButton; private Button moveUpButton; private PictureBox locoBox; + private Button paintElectricLocoButton; + private ComboBox movesBox; + private Button moveButton; } } \ No newline at end of file diff --git a/lab1/MainForm.cs b/lab1/MainForm.cs index 7c6ee6a..46ec777 100644 --- a/lab1/MainForm.cs +++ b/lab1/MainForm.cs @@ -5,6 +5,7 @@ namespace ElectricLocomotive public partial class MainForm : Form { private DrawingLocomotiv? _drawingLocomotiv; + private AbstractStrategy _abstractStrategy; public MainForm() { InitializeComponent(); @@ -18,16 +19,23 @@ namespace ElectricLocomotive _drawingLocomotiv.DrawLoco(g); locoBox.Image = bmp; } - private void PaintObjectButton_click(object sender, EventArgs e) + private void PaintLocoButton_click(object sender, EventArgs e) { Random random = new(); - _drawingLocomotiv = new DrawingLocomotiv(); - _drawingLocomotiv.Init(random.Next(100, 300),random.Next(1000,3000),locoBox.Width,locoBox.Height); + _drawingLocomotiv = new DrawingLocomotiv(random.Next(100, 300), random.Next(1000, 3000), locoBox.Width, locoBox.Height); _drawingLocomotiv.SetPosition(random.Next(10, 100), random.Next(10, 100)); Draw(); } - private void MoveButton_Click(object sender, EventArgs e) + private void PaintElectricLocoButton_click(object sender, EventArgs e) + { + Random random = new(); + _drawingLocomotiv = new DrawingElectricLocomotiv(random.Next(100, 300), random.Next(1000, 3000), locoBox.Width, locoBox.Height); + _drawingLocomotiv.SetPosition(random.Next(10, 100), random.Next(10, 100)); + Draw(); + } + + private void MoveSideButton_Click(object sender, EventArgs e) { if (_drawingLocomotiv == null) return; @@ -51,5 +59,40 @@ namespace ElectricLocomotive } Draw(); } + + private void MoveButton_Click(object sender, EventArgs e) + { + if (_drawingLocomotiv == null) + return; + if (movesBox.Enabled) + { + _abstractStrategy = movesBox.SelectedIndex + switch + { + 0 => new MoveToEdge(), + 1 => new MoveToCenter(), + _ => null, + } ; + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.SetData(new + DrawingObjectLocomotiv(_drawingLocomotiv), locoBox.Width, + locoBox.Height); + movesBox.Enabled = false; + } + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.MakeStep(); + Draw(); + if (_abstractStrategy.GetStatus() == Status.Finish) + { + movesBox.Enabled = true; + _abstractStrategy = null; + } + } } } \ No newline at end of file diff --git a/lab1/MoveToCenter.cs b/lab1/MoveToCenter.cs new file mode 100644 index 0000000..f46596f --- /dev/null +++ b/lab1/MoveToCenter.cs @@ -0,0 +1,50 @@ +namespace ElectricLocomotive; + +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(); + } + } + } +} \ No newline at end of file diff --git a/lab1/MoveToEdge.cs b/lab1/MoveToEdge.cs new file mode 100644 index 0000000..1f665e9 --- /dev/null +++ b/lab1/MoveToEdge.cs @@ -0,0 +1,39 @@ +namespace ElectricLocomotive; + +public class MoveToEdge: AbstractStrategy +{ + protected override bool IsTargetDestinaion() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + return objParams.RightBorder < FieldWidth && objParams.RightBorder + GetStep() >= FieldWidth; + } + + protected override void MoveToTarget() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return; + } + var diffX = objParams.RightBorder - (FieldWidth-1); + if (Math.Abs(diffX) > GetStep()) + { + if (diffX < 0) + { + MoveRight(); + } + } + var diffY = objParams.DownBorder - (FieldHeight-1); + if (Math.Abs(diffY) > GetStep()) + { + if (diffY < 0) + { + MoveDown(); + } + } + } +} \ No newline at end of file diff --git a/lab1/ObjectParameters.cs b/lab1/ObjectParameters.cs new file mode 100644 index 0000000..5e89f41 --- /dev/null +++ b/lab1/ObjectParameters.cs @@ -0,0 +1,29 @@ +namespace ElectricLocomotive; + +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; + } +} \ No newline at end of file diff --git a/lab1/Status.cs b/lab1/Status.cs new file mode 100644 index 0000000..1250e0b --- /dev/null +++ b/lab1/Status.cs @@ -0,0 +1,8 @@ +namespace ElectricLocomotive; + +public enum Status +{ + NotInit = 1, + InProgress = 2, + Finish = 3 +} \ No newline at end of file