Compare commits

..

8 Commits
main ... lab8

Author SHA1 Message Date
shoot
ecedc8f04f PIbd22_NikiforovaMV_lab8 2023-12-29 22:22:08 +04:00
shoot
7b2ddc0d18 PIbd22_NikiforovaMV_lab7 2023-12-29 22:18:15 +04:00
shoot
515d6907cc Pibd22_NikiforovaMV_lab6 2023-12-16 11:18:38 +04:00
shoot
7a90a02332 Pibd22_NikiforovaMV_lab5 2023-12-16 11:16:37 +04:00
shoot
d97e259186 PIbd_NikiforovaMV_lab4 2023-12-16 11:14:14 +04:00
shoot
0a9220bf86 PIbd22_NikiforovaMV_lab3 2023-12-16 11:10:10 +04:00
shoot
5a3b9d61d8 PIbd22_NikiforovaMV_lab2 2023-11-25 12:44:21 +04:00
shoot
a0083358a9 PIbd22_NikiforovaMV_lab1 2023-11-25 12:27:56 +04:00
38 changed files with 3489 additions and 0 deletions

25
ContainerShip.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33530.505
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ContainerShip", "ContainerShip\ContainerShip.csproj", "{7B055446-4DCB-45DC-BA33-7682F200E99A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7B055446-4DCB-45DC-BA33-7682F200E99A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B055446-4DCB-45DC-BA33-7682F200E99A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B055446-4DCB-45DC-BA33-7682F200E99A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B055446-4DCB-45DC-BA33-7682F200E99A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8C73C00B-F826-4DA5-ABFF-F9E040CB549E}
EndGlobalSection
EndGlobal

View File

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

View File

@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ContainerShip
{
public enum DirectionType
{
Up = 1, Down = 2, Left = 3, Right = 4
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ContainerShip.Entities;
namespace ContainerShip.DrawningObjects
{
public class DrawingContainerShip : DrawningShip
{
public DrawingContainerShip(int speed, double weight, Color bodyColor, Color
additionalColor, bool load, bool crane, int width, int height) :
base(speed, weight, bodyColor, width, height, 140, 90)
{
if (EntityShip != null)
{
EntityShip = new EntityContainerShip(speed, weight, bodyColor,
additionalColor, load, crane);
}
}
public override void DrawTransport(Graphics g)
{
if (EntityShip is not EntityContainerShip containerShip)
{
return;
}
Pen pen = new(Color.Black);
Brush additionalBrush = new
SolidBrush(containerShip.AdditionalColor);
if (containerShip.Load)
{
g.FillRectangle(additionalBrush, _startPosX + 100, _startPosY + 32, 30, 20);
}
base.DrawTransport(g);
if (containerShip.Crane)
{
g.DrawLine(pen, _startPosX + 90, _startPosY + 32, _startPosX + 120, _startPosY);
g.DrawLine(pen, _startPosX + 80, _startPosY + 32, _startPosX + 120, _startPosY);
g.DrawLine(pen, _startPosX + 120, _startPosY, _startPosX + 120, _startPosY + 30);
}
}
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ContainerShip.DrawningObjects;
namespace ContainerShip.MovementStrategy
{
public class DrawingObjectShip : IMoveableObject
{
private readonly DrawningShip? _drawingShip = null;
public DrawingObjectShip(DrawningShip drawingShip)
{
_drawingShip = drawingShip;
}
public ObjectParameters? GetObjectPosition
{
get
{
if (_drawingShip == null || _drawingShip.EntityShip == null)
{
return null;
}
return new ObjectParameters(_drawingShip.GetPosX, _drawingShip.GetPosY, _drawingShip.GetWidth, _drawingShip.GetHeight);
}
}
public int GetStep => (int)(_drawingShip?.EntityShip?.Step ?? 0);
public bool CheckCanMove(DirectionType direction) => _drawingShip?.CanMove(direction) ?? false;
public void MoveObject(DirectionType direction) => _drawingShip?.MoveTransport(direction);
}
}

View File

@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ContainerShip.Entities;
using ContainerShip.MovementStrategy;
namespace ContainerShip.DrawningObjects
{
public class DrawningShip
{
public EntityShip? EntityShip { get; protected set; }
private int _pictureWidth;
private int _pictureHeight;
protected int _startPosX;
protected int _startPosY;
protected readonly int _shipWidth = 150;
protected readonly int _shipHeight = 65;
public int GetPosX => _startPosX;
public int GetPosY => _startPosY;
public int GetWidth => _shipWidth;
public int GetHeight => _shipHeight;
public DrawningShip(int speed, double weight, Color bodyColor, int width, int height)
{
if (width < _shipWidth || height < _shipHeight)
{
return;
}
_pictureWidth = width;
_pictureHeight = height;
EntityShip = new EntityShip(speed, weight, bodyColor);
}
protected DrawningShip(int speed, double weight, Color bodyColor, int width, int height, int shipWidth, int shipHeight)
{
if (width < _shipWidth || height < _shipHeight)
{
return;
}
_pictureWidth = width;
_pictureHeight = height;
_shipWidth = shipWidth;
_shipHeight = shipHeight;
EntityShip = new EntityShip(speed, weight, bodyColor);
}
public void SetPosition(int x, int y)
{
if (x > _pictureWidth || y > _pictureHeight)
{
return;
}
_startPosX = x;
_startPosY = y;
}
public void MoveTransport(DirectionType direction)
{
if (!CanMove(direction) || EntityShip == null)
{
return;
}
switch (direction)
{
case DirectionType.Left:
if (_startPosX - EntityShip.Step > 0)
{
_startPosX -= (int)EntityShip.Step;
}
break;
case DirectionType.Up:
if (_startPosY - EntityShip.Step > 0)
{
_startPosY -= (int)EntityShip.Step;
}
break;
case DirectionType.Right:
if (_startPosX + _shipWidth + EntityShip.Step < _pictureWidth)
{
_startPosX += (int)EntityShip.Step;
}
break;
case DirectionType.Down:
if (_startPosY + _shipHeight + EntityShip.Step < _pictureHeight)
{
_startPosY += (int)EntityShip.Step;
}
break;
}
}
public virtual void DrawTransport(Graphics g)
{
Pen pen = new(Color.Black);
Brush bodyBrush = new SolidBrush(EntityShip.BodyColor);
Point point1 = new Point(_startPosX, _startPosY + 52);
Point point2 = new Point(_startPosX + 137, _startPosY + 52);
Point point3 = new Point(_startPosX + 137 - 20, _startPosY + 52 + 46 - 10);
Point point4 = new Point(_startPosX + 20, _startPosY + 52 + 46 - 10);
Point[] p = { point1, point2, point3, point4 };
g.FillPolygon(bodyBrush, p);
g.FillRectangle(bodyBrush, _startPosX + 15, _startPosY + 32, 80, 20);
}
public bool CanMove(DirectionType direction)
{
if (EntityShip == null)
{
return false;
}
return direction switch
{
DirectionType.Left => _startPosX - EntityShip.Step > 0,
DirectionType.Up => _startPosY - EntityShip.Step > 0,
DirectionType.Right => _startPosX + _shipWidth + EntityShip.Step < _pictureWidth,
DirectionType.Down => _startPosY + _shipHeight + EntityShip.Step < _pictureHeight,
_ => false,
};
}
public IMoveableObject GetMoveableObject => new DrawingObjectShip(this);
public void ChangeBordersPicture(int width, int height)
{
_pictureWidth = width;
_pictureHeight = height;
}
}
}

View File

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;
using ContainerShip.Entities;
using ContainerShip.DrawningObjects;
namespace ContainerShip.Generic
{
internal class DrawningShipEqutables : IEqualityComparer<DrawningShip?>
{
public bool Equals(DrawningShip? x, DrawningShip? y)
{
if (x == null && x.EntityShip == null)
throw new ArgumentNullException(nameof(x));
if (y == null && y.EntityShip == null)
throw new ArgumentNullException(nameof(y));
if ((x.GetType().Name != y.GetType().Name))
return false;
if (x.EntityShip.Speed != y.EntityShip.Speed)
return false;
if (x.EntityShip.Weight != y.EntityShip.Weight)
return false;
if (x.EntityShip.BodyColor != y.EntityShip.BodyColor)
return false;
if (x is DrawingContainerShip && y is DrawingContainerShip)
{
var xPlane = (EntityContainerShip)x.EntityShip;
var yPlane = (EntityContainerShip)y.EntityShip;
if (xPlane.AdditionalColor != yPlane.AdditionalColor)
return false;
if (xPlane.Load != yPlane.Load)
return false;
if (xPlane.Crane != yPlane.Crane)
return false;
}
return true;
}
public int GetHashCode([DisallowNull] DrawningShip? obj)
{
return obj.GetHashCode();
}
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace ContainerShip.Entities
{
public class EntityContainerShip : EntityShip
{
public Color AdditionalColor { get; private set; }
public bool Load { get; private set; }
public bool Crane { get; private set; }
public EntityContainerShip(int speed, double weight, Color bodyColor, Color additionalColor, bool load, bool crane) : base(speed, weight, bodyColor)
{
AdditionalColor = additionalColor;
Load = load;
Crane = crane;
}
public void ChangeAdditionalColor(Color additionalColor)
{
AdditionalColor = additionalColor;
}
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ContainerShip.Entities
{
public class EntityShip
{
public int Speed { get; private set; }
public double Weight { get; private set; }
public Color BodyColor { get; private set; }
public double Step => (double)Speed * 100 / Weight;
public EntityShip(int speed, double weight, Color bodyColor)
{
Speed = speed;
Weight = weight;
BodyColor = bodyColor;
}
public void ChangeBodyColor(Color color)
{
BodyColor = color;
}
}
}

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ContainerShip.Entities;
namespace ContainerShip.DrawningObjects
{
public static class ExtentionDrawningShip
{
public static DrawningShip? CreateDrawningShip(this string info, char separatorForObject, int width, int height)
{
string[] strs = info.Split(separatorForObject);
if (strs.Length == 3)
{
return new DrawningShip(
Convert.ToInt32(strs[0]),
Convert.ToInt32(strs[1]),
Color.FromName(strs[2]), width, height);
}
if (strs.Length == 6)
{
return new DrawingContainerShip(
Convert.ToInt32(strs[0]), Convert.ToInt32(strs[1]),
Color.FromName(strs[2]), Color.FromName(strs[3]),
Convert.ToBoolean(strs[4]), Convert.ToBoolean(strs[5]),
width, height);
}
return null;
}
public static string GetDataForSave(this DrawningShip drawningShip, char separatorForObject)
{
var ship = drawningShip.EntityShip;
if (ship == null)
{
return string.Empty;
}
var str = $"{ship.Speed}{separatorForObject}{ship.Weight}{separatorForObject}{ship.BodyColor.Name}";
if (ship is not EntityContainerShip containerShip)
{
return str;
}
return $"{str}{separatorForObject}{containerShip.AdditionalColor.Name}{separatorForObject}{containerShip.Load}{separatorForObject}{containerShip.Crane}";
}
}
}

View File

@ -0,0 +1,275 @@
namespace ContainerShip
{
partial class FormShipCollection
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
buttonAdd = new Button();
buttonDelete = new Button();
labelTools = new Label();
maskedTextBoxNumber = new TextBox();
pictureBoxCollection = new PictureBox();
labelSet = new Label();
textBoxStorageName = new TextBox();
listBoxStorages = new ListBox();
buttonAddStorage = new Button();
buttonDeleteStorage = new Button();
buttonUpdate = new Button();
menuStrip = new MenuStrip();
toolStripMenuItem = new ToolStripMenuItem();
SaveToolStripMenuItem = new ToolStripMenuItem();
LoadToolStripMenuItem = new ToolStripMenuItem();
openFileDialog = new OpenFileDialog();
saveFileDialog = new SaveFileDialog();
buttonSortByColor = new Button();
buttonSortByType = new Button();
((System.ComponentModel.ISupportInitialize)pictureBoxCollection).BeginInit();
menuStrip.SuspendLayout();
SuspendLayout();
//
// buttonAdd
//
buttonAdd.Location = new Point(736, 480);
buttonAdd.Margin = new Padding(3, 4, 3, 4);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(165, 32);
buttonAdd.TabIndex = 0;
buttonAdd.Text = "Добавить корабль";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// buttonDelete
//
buttonDelete.Location = new Point(736, 555);
buttonDelete.Margin = new Padding(3, 4, 3, 4);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(163, 32);
buttonDelete.TabIndex = 1;
buttonDelete.Text = "Удалить корабль";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += buttonDelete_Click;
//
// labelTools
//
labelTools.AutoSize = true;
labelTools.Location = new Point(774, 12);
labelTools.Name = "labelTools";
labelTools.Size = new Size(103, 20);
labelTools.TabIndex = 3;
labelTools.Text = "Инструменты";
//
// maskedTextBoxNumber
//
maskedTextBoxNumber.Location = new Point(736, 520);
maskedTextBoxNumber.Margin = new Padding(3, 4, 3, 4);
maskedTextBoxNumber.Name = "maskedTextBoxNumber";
maskedTextBoxNumber.Size = new Size(162, 27);
maskedTextBoxNumber.TabIndex = 4;
//
// pictureBoxCollection
//
pictureBoxCollection.Location = new Point(0, 28);
pictureBoxCollection.Margin = new Padding(3, 4, 3, 4);
pictureBoxCollection.Name = "pictureBoxCollection";
pictureBoxCollection.Size = new Size(731, 581);
pictureBoxCollection.TabIndex = 5;
pictureBoxCollection.TabStop = false;
//
// labelSet
//
labelSet.AutoSize = true;
labelSet.Location = new Point(748, 41);
labelSet.Name = "labelSet";
labelSet.Size = new Size(55, 20);
labelSet.TabIndex = 6;
labelSet.Text = "Набор";
//
// textBoxStorageName
//
textBoxStorageName.Location = new Point(739, 65);
textBoxStorageName.Margin = new Padding(3, 4, 3, 4);
textBoxStorageName.Name = "textBoxStorageName";
textBoxStorageName.Size = new Size(162, 27);
textBoxStorageName.TabIndex = 7;
//
// listBoxStorages
//
listBoxStorages.FormattingEnabled = true;
listBoxStorages.ItemHeight = 20;
listBoxStorages.Location = new Point(739, 179);
listBoxStorages.Name = "listBoxStorages";
listBoxStorages.Size = new Size(165, 124);
listBoxStorages.TabIndex = 8;
listBoxStorages.SelectedIndexChanged += buttonUpdate_Click;
//
// buttonAddStorage
//
buttonAddStorage.Location = new Point(739, 100);
buttonAddStorage.Margin = new Padding(3, 4, 3, 4);
buttonAddStorage.Name = "buttonAddStorage";
buttonAddStorage.Size = new Size(165, 32);
buttonAddStorage.TabIndex = 9;
buttonAddStorage.Text = "Добавить набор";
buttonAddStorage.UseVisualStyleBackColor = true;
buttonAddStorage.Click += ButtonAddObject_Click;
//
// buttonDeleteStorage
//
buttonDeleteStorage.Location = new Point(739, 322);
buttonDeleteStorage.Margin = new Padding(3, 4, 3, 4);
buttonDeleteStorage.Name = "buttonDeleteStorage";
buttonDeleteStorage.Size = new Size(165, 32);
buttonDeleteStorage.TabIndex = 11;
buttonDeleteStorage.Text = "Удалить набор";
buttonDeleteStorage.UseVisualStyleBackColor = true;
buttonDeleteStorage.Click += ButtonDelObject_Click;
//
// buttonUpdate
//
buttonUpdate.Location = new Point(739, 140);
buttonUpdate.Margin = new Padding(3, 4, 3, 4);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(163, 32);
buttonUpdate.TabIndex = 2;
buttonUpdate.Text = "Обновить набор";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// menuStrip
//
menuStrip.ImageScalingSize = new Size(20, 20);
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(914, 28);
menuStrip.TabIndex = 13;
menuStrip.Text = "menuStrip1";
//
// toolStripMenuItem
//
toolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { SaveToolStripMenuItem, LoadToolStripMenuItem });
toolStripMenuItem.Name = "toolStripMenuItem";
toolStripMenuItem.Size = new Size(59, 24);
toolStripMenuItem.Text = "Файл";
//
// SaveToolStripMenuItem
//
SaveToolStripMenuItem.Name = "SaveToolStripMenuItem";
SaveToolStripMenuItem.Size = new Size(166, 26);
SaveToolStripMenuItem.Text = "Сохранить";
SaveToolStripMenuItem.Click += SaveToolStripMenuItem_Click;
//
// LoadToolStripMenuItem
//
LoadToolStripMenuItem.Name = "LoadToolStripMenuItem";
LoadToolStripMenuItem.Size = new Size(166, 26);
LoadToolStripMenuItem.Text = "Загрузить";
LoadToolStripMenuItem.Click += LoadToolStripMenuItem_Click;
//
// openFileDialog
//
openFileDialog.FileName = "openFileDialog1";
openFileDialog.Filter = "txt file | *.txt";
//
// saveFileDialog
//
saveFileDialog.Filter = "txt file | *.txt";
//
// buttonSortByColor
//
buttonSortByColor.Location = new Point(739, 374);
buttonSortByColor.Margin = new Padding(3, 4, 3, 4);
buttonSortByColor.Name = "buttonSortByColor";
buttonSortByColor.Size = new Size(165, 32);
buttonSortByColor.TabIndex = 14;
buttonSortByColor.Text = "Сортировка по цвету";
buttonSortByColor.UseVisualStyleBackColor = true;
buttonSortByColor.Click += buttonSortByColor_Click;
//
// buttonSortByType
//
buttonSortByType.Location = new Point(739, 414);
buttonSortByType.Margin = new Padding(3, 4, 3, 4);
buttonSortByType.Name = "buttonSortByType";
buttonSortByType.Size = new Size(165, 32);
buttonSortByType.TabIndex = 15;
buttonSortByType.Text = "Сортировка по типу";
buttonSortByType.UseVisualStyleBackColor = true;
buttonSortByType.Click += buttonSortByType_Click;
//
// FormShipCollection
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(914, 600);
Controls.Add(buttonSortByType);
Controls.Add(buttonSortByColor);
Controls.Add(menuStrip);
Controls.Add(buttonDeleteStorage);
Controls.Add(buttonAddStorage);
Controls.Add(listBoxStorages);
Controls.Add(textBoxStorageName);
Controls.Add(labelSet);
Controls.Add(pictureBoxCollection);
Controls.Add(maskedTextBoxNumber);
Controls.Add(labelTools);
Controls.Add(buttonUpdate);
Controls.Add(buttonDelete);
Controls.Add(buttonAdd);
Margin = new Padding(3, 4, 3, 4);
Name = "FormShipCollection";
Text = "Набор кораблей";
((System.ComponentModel.ISupportInitialize)pictureBoxCollection).EndInit();
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Button buttonAdd;
private Button buttonDelete;
private Label labelTools;
private TextBox maskedTextBoxNumber;
private PictureBox pictureBoxCollection;
private Label labelSet;
private TextBox textBoxStorageName;
private ListBox listBoxStorages;
private Button buttonAddStorage;
private Button buttonDeleteStorage;
private Button buttonUpdate;
private MenuStrip menuStrip;
private ToolStripMenuItem toolStripMenuItem;
private ToolStripMenuItem SaveToolStripMenuItem;
private ToolStripMenuItem LoadToolStripMenuItem;
private OpenFileDialog openFileDialog;
private SaveFileDialog saveFileDialog;
private Button buttonSortByColor;
private Button buttonSortByType;
}
}

View File

@ -0,0 +1,236 @@
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;
using ContainerShip.MovementStrategy;
using System.Xml.Linq;
using Microsoft.Extensions.Logging;
using ContainerShip.DrawningObjects;
using ContainerShip.Generic;
using ContainerShip.Exceptions;
using ContainerShip.Entities;
namespace ContainerShip
{
public partial class FormShipCollection : Form
{
private readonly ShipsGenericStorage _storage;
private readonly ILogger _logger;
public FormShipCollection(ILogger<FormShipCollection> logger)
{
InitializeComponent();
_storage = new ShipsGenericStorage(pictureBoxCollection.Width, pictureBoxCollection.Height);
_logger = logger;
}
private void buttonSortByType_Click(object sender, EventArgs e) => CompareShip(new ShipCompareByType());
private void buttonSortByColor_Click(object sender, EventArgs e) => CompareShip(new ShipCompareByColor());
private void CompareShip(IComparer<DrawningShip?> comparer)
{
if (listBoxStorages.SelectedIndex == -1)
{
return;
}
var obj = _storage[listBoxStorages.SelectedItem.ToString() ?? string.Empty];
if (obj == null)
{
return;
}
obj.Sort(comparer);
pictureBoxCollection.Image = obj.ShowShips();
}
private void ReloadObjects()
{
int index = listBoxStorages.SelectedIndex;
listBoxStorages.Items.Clear();
for (int i = 0; i < _storage.Keys.Count; i++)
{
listBoxStorages.Items.Add(_storage.Keys[i].Name);
}
if (listBoxStorages.Items.Count > 0 && (index == -1 || index >= listBoxStorages.Items.Count))
{
listBoxStorages.SelectedIndex = 0;
}
else if (listBoxStorages.Items.Count > 0 && index > -1 && index < listBoxStorages.Items.Count)
{
listBoxStorages.SelectedIndex = index;
}
}
private void ButtonAddObject_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxStorageName.Text))
{
MessageBox.Show("Не все данные заполнены", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_storage.AddSet(textBoxStorageName.Text);
ReloadObjects();
_logger.LogInformation($"Добавлен набор: {textBoxStorageName.Text}");
}
private void ListBoxObjects_SelectedIndexChanged(object sender, EventArgs e)
{
pictureBoxCollection.Image = _storage[listBoxStorages.SelectedItem?.ToString() ?? string.Empty]?.ShowShips();
}
private void ButtonDelObject_Click(object sender, EventArgs e)
{
if (listBoxStorages.SelectedIndex == -1)
{
return;
}
string name = listBoxStorages.SelectedItem.ToString() ?? string.Empty;
if (MessageBox.Show($"Удалить объект {listBoxStorages.SelectedItem}?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
_storage.DelSet(name);
ReloadObjects();
_logger.LogInformation($"Удалён набор: {name}");
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var formShipConfig = new FormShipConfig();
formShipConfig.AddEvent(AddShip);
formShipConfig.Show();
}
private void AddShip(DrawningShip _ship)
{
if (listBoxStorages.SelectedIndex == -1)
{
MessageBox.Show("Не выбран набор");
return;
}
var obj = _storage[listBoxStorages.SelectedItem.ToString() ?? string.Empty];
if (obj == null)
{
return;
}
_ship.ChangeBordersPicture(Width, Height);
try
{
if (obj + _ship != -1)
{
MessageBox.Show("Объект добавлен");
pictureBoxCollection.Image = obj.ShowShips();
_logger.LogInformation($"Добавлен объект: {_ship.EntityShip.BodyColor}");
}
else
{
MessageBox.Show("Не удалось добавить объект");
}
}
catch (StorageOverflowException ex)
{
MessageBox.Show(ex.Message);
_logger.LogWarning(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
_logger.LogWarning(ex.Message);
}
}
private void buttonDelete_Click(object sender, EventArgs e)
{
if (listBoxStorages.SelectedIndex == -1)
{
return;
}
var obj = _storage[listBoxStorages.SelectedItem.ToString() ?? string.Empty];
if (obj == null)
{
return;
}
if (MessageBox.Show("Удалить объект?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
return;
}
try
{
int pos = Convert.ToInt32(maskedTextBoxNumber.Text);
if (obj - pos)
{
MessageBox.Show("Объект удален");
pictureBoxCollection.Image = obj.ShowShips();
_logger.LogInformation($"Удалён объект по позиции : {pos}");
}
else
{
MessageBox.Show("Не удалось удалить объект");
}
}
catch (FormatException ex)
{
MessageBox.Show("Неверный формат ввода");
_logger.LogWarning("Неверный формат ввода");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
_logger.LogWarning(ex.Message);
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
if (listBoxStorages.SelectedIndex == -1)
{
return;
}
var obj = _storage[listBoxStorages.SelectedItem.ToString() ??
string.Empty];
if (obj == null)
{
return;
}
pictureBoxCollection.Image = obj.ShowShips();
}
private void SaveToolStripMenuItem_Click(object sender, EventArgs e)
{
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
_storage.SaveData(saveFileDialog.FileName);
MessageBox.Show("Сохранение прошло успешно", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
_logger.LogInformation($"Файл сохранён по пути: {saveFileDialog.FileName}");
}
catch (InvalidOperationException ex)
{
MessageBox.Show(ex.Message, "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error);
_logger.LogWarning(ex.Message);
}
}
}
private void LoadToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
_storage.LoadData(openFileDialog.FileName);
MessageBox.Show("Загрузка прошла успешно", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
_logger.LogInformation($"Файл загружен по пути: {openFileDialog.FileName}");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error);
_logger.LogWarning(ex.Message);
}
}
ReloadObjects();
}
}
}

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>44, 16</value>
</metadata>
<metadata name="openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>185, 16</value>
</metadata>
<metadata name="saveFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>344, 16</value>
</metadata>
</root>

357
ContainerShip/FormShipConfig.Designer.cs generated Normal file
View File

@ -0,0 +1,357 @@
namespace ContainerShip
{
partial class FormShipConfig
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
groupBoxConfig = new GroupBox();
labelAdvancedObject = new Label();
labelSimpleObject = new Label();
groupBoxColor = new GroupBox();
panelBlue = new Panel();
panelBlack = new Panel();
panelPink = new Panel();
panelGray = new Panel();
panelGreen = new Panel();
panelYellow = new Panel();
panelRoyalBlue = new Panel();
panelFirebrick = new Panel();
checkBoxCrane = new CheckBox();
checkBoxLoad = new CheckBox();
numericUpDownSpeed = new NumericUpDown();
numericUpDownWeight = new NumericUpDown();
labelWeight = new Label();
labelSpeed = new Label();
panelObject = new Panel();
labelAdditionalColor = new Label();
labelMainColor = new Label();
pictureBoxObject = new PictureBox();
buttonCancel = new Button();
buttonAdd = new Button();
groupBoxConfig.SuspendLayout();
groupBoxColor.SuspendLayout();
((System.ComponentModel.ISupportInitialize)numericUpDownSpeed).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownWeight).BeginInit();
panelObject.SuspendLayout();
((System.ComponentModel.ISupportInitialize)pictureBoxObject).BeginInit();
SuspendLayout();
//
// groupBoxConfig
//
groupBoxConfig.Controls.Add(labelAdvancedObject);
groupBoxConfig.Controls.Add(labelSimpleObject);
groupBoxConfig.Controls.Add(groupBoxColor);
groupBoxConfig.Controls.Add(checkBoxCrane);
groupBoxConfig.Controls.Add(checkBoxLoad);
groupBoxConfig.Controls.Add(numericUpDownSpeed);
groupBoxConfig.Controls.Add(numericUpDownWeight);
groupBoxConfig.Controls.Add(labelWeight);
groupBoxConfig.Controls.Add(labelSpeed);
groupBoxConfig.Location = new Point(47, 93);
groupBoxConfig.Name = "groupBoxConfig";
groupBoxConfig.Size = new Size(570, 251);
groupBoxConfig.TabIndex = 3;
groupBoxConfig.TabStop = false;
groupBoxConfig.Text = "Параметры";
//
// labelAdvancedObject
//
labelAdvancedObject.BorderStyle = BorderStyle.FixedSingle;
labelAdvancedObject.Location = new Point(440, 188);
labelAdvancedObject.Name = "labelAdvancedObject";
labelAdvancedObject.Size = new Size(120, 30);
labelAdvancedObject.TabIndex = 8;
labelAdvancedObject.Text = "Продвинутый";
labelAdvancedObject.TextAlign = ContentAlignment.MiddleCenter;
labelAdvancedObject.MouseDown += LabelObject_MouseDown;
//
// labelSimpleObject
//
labelSimpleObject.BorderStyle = BorderStyle.FixedSingle;
labelSimpleObject.Location = new Point(283, 188);
labelSimpleObject.Name = "labelSimpleObject";
labelSimpleObject.Size = new Size(120, 30);
labelSimpleObject.TabIndex = 7;
labelSimpleObject.Text = "Простой";
labelSimpleObject.TextAlign = ContentAlignment.MiddleCenter;
labelSimpleObject.MouseDown += LabelObject_MouseDown;
//
// groupBoxColor
//
groupBoxColor.Controls.Add(panelBlue);
groupBoxColor.Controls.Add(panelBlack);
groupBoxColor.Controls.Add(panelPink);
groupBoxColor.Controls.Add(panelGray);
groupBoxColor.Controls.Add(panelGreen);
groupBoxColor.Controls.Add(panelYellow);
groupBoxColor.Controls.Add(panelRoyalBlue);
groupBoxColor.Controls.Add(panelFirebrick);
groupBoxColor.Location = new Point(283, 32);
groupBoxColor.Name = "groupBoxColor";
groupBoxColor.Size = new Size(277, 145);
groupBoxColor.TabIndex = 6;
groupBoxColor.TabStop = false;
groupBoxColor.Text = "Цвета";
//
// panelBlue
//
panelBlue.BackColor = Color.Blue;
panelBlue.Location = new Point(5, 85);
panelBlue.Name = "panelBlue";
panelBlue.Size = new Size(50, 40);
panelBlue.TabIndex = 0;
//
// panelBlack
//
panelBlack.BackColor = Color.Black;
panelBlack.Location = new Point(75, 85);
panelBlack.Name = "panelBlack";
panelBlack.Size = new Size(50, 40);
panelBlack.TabIndex = 0;
//
// panelPink
//
panelPink.BackColor = Color.DeepPink;
panelPink.Location = new Point(145, 85);
panelPink.Name = "panelPink";
panelPink.Size = new Size(50, 40);
panelPink.TabIndex = 0;
//
// panelGray
//
panelGray.BackColor = Color.Gray;
panelGray.Location = new Point(215, 85);
panelGray.Name = "panelGray";
panelGray.Size = new Size(50, 40);
panelGray.TabIndex = 0;
//
// panelGreen
//
panelGreen.BackColor = Color.FromArgb(0, 192, 0);
panelGreen.Location = new Point(215, 25);
panelGreen.Name = "panelGreen";
panelGreen.Size = new Size(50, 40);
panelGreen.TabIndex = 0;
//
// panelYellow
//
panelYellow.BackColor = Color.Yellow;
panelYellow.Location = new Point(145, 25);
panelYellow.Name = "panelYellow";
panelYellow.Size = new Size(50, 40);
panelYellow.TabIndex = 0;
//
// panelRoyalBlue
//
panelRoyalBlue.BackColor = Color.RoyalBlue;
panelRoyalBlue.Location = new Point(75, 25);
panelRoyalBlue.Name = "panelRoyalBlue";
panelRoyalBlue.Size = new Size(50, 40);
panelRoyalBlue.TabIndex = 0;
//
// panelFirebrick
//
panelFirebrick.BackColor = Color.Firebrick;
panelFirebrick.Location = new Point(5, 25);
panelFirebrick.Name = "panelFirebrick";
panelFirebrick.Size = new Size(50, 40);
panelFirebrick.TabIndex = 0;
//
// checkBoxCrane
//
checkBoxCrane.AutoSize = true;
checkBoxCrane.Location = new Point(13, 149);
checkBoxCrane.Name = "checkBoxCrane";
checkBoxCrane.Size = new Size(137, 24);
checkBoxCrane.TabIndex = 5;
checkBoxCrane.Text = "Наличие крана";
checkBoxCrane.UseVisualStyleBackColor = true;
//
// checkBoxLoad
//
checkBoxLoad.AutoSize = true;
checkBoxLoad.Location = new Point(13, 119);
checkBoxLoad.Name = "checkBoxLoad";
checkBoxLoad.Size = new Size(133, 24);
checkBoxLoad.TabIndex = 4;
checkBoxLoad.Text = "Наличие груза";
checkBoxLoad.UseVisualStyleBackColor = true;
//
// numericUpDownSpeed
//
numericUpDownSpeed.Location = new Point(94, 32);
numericUpDownSpeed.Maximum = new decimal(new int[] { 1000, 0, 0, 0 });
numericUpDownSpeed.Minimum = new decimal(new int[] { 100, 0, 0, 0 });
numericUpDownSpeed.Name = "numericUpDownSpeed";
numericUpDownSpeed.Size = new Size(150, 27);
numericUpDownSpeed.TabIndex = 3;
numericUpDownSpeed.Value = new decimal(new int[] { 100, 0, 0, 0 });
//
// numericUpDownWeight
//
numericUpDownWeight.Location = new Point(94, 83);
numericUpDownWeight.Maximum = new decimal(new int[] { 1000, 0, 0, 0 });
numericUpDownWeight.Minimum = new decimal(new int[] { 100, 0, 0, 0 });
numericUpDownWeight.Name = "numericUpDownWeight";
numericUpDownWeight.Size = new Size(150, 27);
numericUpDownWeight.TabIndex = 2;
numericUpDownWeight.Value = new decimal(new int[] { 100, 0, 0, 0 });
//
// labelWeight
//
labelWeight.AutoSize = true;
labelWeight.Location = new Point(6, 85);
labelWeight.Name = "labelWeight";
labelWeight.Size = new Size(36, 20);
labelWeight.TabIndex = 1;
labelWeight.Text = "Вес:";
//
// labelSpeed
//
labelSpeed.AutoSize = true;
labelSpeed.Location = new Point(6, 32);
labelSpeed.Name = "labelSpeed";
labelSpeed.Size = new Size(76, 20);
labelSpeed.TabIndex = 0;
labelSpeed.Text = "Скорость:";
//
// panelObject
//
panelObject.AllowDrop = true;
panelObject.Controls.Add(labelAdditionalColor);
panelObject.Controls.Add(labelMainColor);
panelObject.Controls.Add(pictureBoxObject);
panelObject.Location = new Point(646, 74);
panelObject.Name = "panelObject";
panelObject.Size = new Size(401, 301);
panelObject.TabIndex = 4;
panelObject.DragDrop += PanelObject_DragDrop;
panelObject.DragEnter += PanelObject_DragEnter;
//
// labelAdditionalColor
//
labelAdditionalColor.AllowDrop = true;
labelAdditionalColor.BorderStyle = BorderStyle.FixedSingle;
labelAdditionalColor.Location = new Point(233, 19);
labelAdditionalColor.Name = "labelAdditionalColor";
labelAdditionalColor.Size = new Size(90, 50);
labelAdditionalColor.TabIndex = 3;
labelAdditionalColor.Text = "Доп. цвет";
labelAdditionalColor.TextAlign = ContentAlignment.MiddleCenter;
labelAdditionalColor.DragDrop += LabelAdditionalColor_DragDrop;
labelAdditionalColor.DragEnter += LabelColor_DragEnter;
//
// labelMainColor
//
labelMainColor.AllowDrop = true;
labelMainColor.BorderStyle = BorderStyle.FixedSingle;
labelMainColor.Location = new Point(77, 19);
labelMainColor.Name = "labelMainColor";
labelMainColor.Size = new Size(90, 50);
labelMainColor.TabIndex = 2;
labelMainColor.Text = "Цвет";
labelMainColor.TextAlign = ContentAlignment.MiddleCenter;
labelMainColor.DragDrop += LabelMainColor_DragDrop;
labelMainColor.DragEnter += LabelMainColor_DragEnter;
//
// pictureBoxObject
//
pictureBoxObject.BorderStyle = BorderStyle.FixedSingle;
pictureBoxObject.Location = new Point(35, 84);
pictureBoxObject.Name = "pictureBoxObject";
pictureBoxObject.Size = new Size(327, 205);
pictureBoxObject.TabIndex = 1;
pictureBoxObject.TabStop = false;
//
// buttonCancel
//
buttonCancel.Location = new Point(879, 394);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(94, 29);
buttonCancel.TabIndex = 6;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
//
// buttonAdd
//
buttonAdd.Location = new Point(722, 392);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(94, 29);
buttonAdd.TabIndex = 5;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// FormShipConfig
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1095, 449);
Controls.Add(buttonCancel);
Controls.Add(buttonAdd);
Controls.Add(groupBoxConfig);
Controls.Add(panelObject);
Name = "FormShipConfig";
Text = "FormShipConfig";
groupBoxConfig.ResumeLayout(false);
groupBoxConfig.PerformLayout();
groupBoxColor.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)numericUpDownSpeed).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownWeight).EndInit();
panelObject.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)pictureBoxObject).EndInit();
ResumeLayout(false);
}
#endregion
private GroupBox groupBoxConfig;
private Label labelAdvancedObject;
private Label labelSimpleObject;
private GroupBox groupBoxColor;
private Panel panelBlue;
private Panel panelBlack;
private Panel panelPink;
private Panel panelGray;
private Panel panelGreen;
private Panel panelYellow;
private Panel panelRoyalBlue;
private Panel panelFirebrick;
private CheckBox checkBoxCrane;
private CheckBox checkBoxLoad;
private NumericUpDown numericUpDownSpeed;
private NumericUpDown numericUpDownWeight;
private Label labelWeight;
private Label labelSpeed;
private Panel panelObject;
private Label labelAdditionalColor;
private Label labelMainColor;
private PictureBox pictureBoxObject;
private Button buttonCancel;
private Button buttonAdd;
}
}

View File

@ -0,0 +1,139 @@
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;
using ContainerShip.DrawningObjects;
using ContainerShip.Entities;
namespace ContainerShip
{
public partial class FormShipConfig : Form
{
DrawningShip? _ship = null;
private event Action<DrawningShip>? EventAddShip;
public FormShipConfig()
{
InitializeComponent();
panelFirebrick.MouseDown += PanelColor_MouseDown;
panelRoyalBlue.MouseDown += PanelColor_MouseDown;
panelYellow.MouseDown += PanelColor_MouseDown;
panelGreen.MouseDown += PanelColor_MouseDown;
panelBlue.MouseDown += PanelColor_MouseDown;
panelBlack.MouseDown += PanelColor_MouseDown;
panelPink.MouseDown += PanelColor_MouseDown;
panelGray.MouseDown += PanelColor_MouseDown;
buttonCancel.Click += (s, e) => Close();
}
private void DrawShip()
{
Bitmap bmp = new(pictureBoxObject.Width, pictureBoxObject.Height);
Graphics gr = Graphics.FromImage(bmp);
_ship?.SetPosition(5, 5);
_ship?.DrawTransport(gr);
pictureBoxObject.Image = bmp;
}
public void AddEvent(Action<DrawningShip> ev)
{
if (EventAddShip == null)
{
EventAddShip = ev;
}
else
{
EventAddShip += ev;
}
}
private void LabelObject_MouseDown(object sender, MouseEventArgs e)
{
(sender as Label)?.DoDragDrop((sender as Label)?.Name,
DragDropEffects.Move | DragDropEffects.Copy);
}
private void PanelObject_DragEnter(object sender, DragEventArgs e)
{
if (e.Data?.GetDataPresent(DataFormats.Text) ?? false)
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void PanelObject_DragDrop(object sender, DragEventArgs e)
{
switch (e.Data?.GetData(DataFormats.Text).ToString())
{
case "labelSimpleObject":
_ship = new DrawningShip(
(int)numericUpDownSpeed.Value,
(int)numericUpDownWeight.Value,
Color.White,
pictureBoxObject.Width, pictureBoxObject.Height);
break;
case "labelAdvancedObject":
_ship = new DrawingContainerShip(
(int)numericUpDownSpeed.Value,
(int)numericUpDownWeight.Value,
Color.White, Color.Black,
checkBoxLoad.Checked, checkBoxCrane.Checked,
pictureBoxObject.Width, pictureBoxObject.Height);
break;
}
DrawShip();
}
private void PanelColor_MouseDown(object sender, MouseEventArgs e)
{
(sender as Panel)?.DoDragDrop((sender as Panel)?.BackColor,
DragDropEffects.Move | DragDropEffects.Copy);
}
private void LabelMainColor_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(Color)) && _ship != null)
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void LabelMainColor_DragDrop(object sender, DragEventArgs e)
{
var color = (Color)e.Data.GetData(typeof(Color));
_ship.EntityShip.ChangeBodyColor(color);
DrawShip();
}
private void LabelColor_DragEnter(object sender, DragEventArgs e)
{
if (e.Data?.GetDataPresent(typeof(Color)) ?? false)
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void LabelAdditionalColor_DragDrop(object sender, DragEventArgs e)
{
Color addColor = (Color)e.Data?.GetData(typeof(Color));
if (_ship is DrawingContainerShip)
{
EntityContainerShip _containerShip = _ship.EntityShip as EntityContainerShip;
_containerShip.ChangeAdditionalColor(addColor);
}
DrawShip();
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
EventAddShip?.Invoke(_ship);
Close();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

203
ContainerShip/FormShips.Designer.cs generated Normal file
View File

@ -0,0 +1,203 @@
namespace ContainerShip
{
partial class FormShips
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormShips));
pictureBoxShips = new PictureBox();
buttonCreateContainerShip = new Button();
buttonCreateShip = new Button();
buttonRight = new Button();
buttonDown = new Button();
buttonLeft = new Button();
buttonUp = new Button();
buttonStep = new Button();
comboBoxStrategy = new ComboBox();
button1 = new Button();
((System.ComponentModel.ISupportInitialize)pictureBoxShips).BeginInit();
SuspendLayout();
//
// pictureBoxShips
//
pictureBoxShips.Dock = DockStyle.Fill;
pictureBoxShips.Location = new Point(0, 0);
pictureBoxShips.Margin = new Padding(3, 2, 3, 2);
pictureBoxShips.Name = "pictureBoxShips";
pictureBoxShips.Size = new Size(772, 340);
pictureBoxShips.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBoxShips.TabIndex = 0;
pictureBoxShips.TabStop = false;
//
// buttonCreateContainerShip
//
buttonCreateContainerShip.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonCreateContainerShip.Location = new Point(10, 273);
buttonCreateContainerShip.Margin = new Padding(3, 2, 3, 2);
buttonCreateContainerShip.Name = "buttonCreateContainerShip";
buttonCreateContainerShip.Size = new Size(115, 58);
buttonCreateContainerShip.TabIndex = 1;
buttonCreateContainerShip.Text = "Создать контейнеровоз";
buttonCreateContainerShip.UseVisualStyleBackColor = true;
buttonCreateContainerShip.Click += ButtonCreateContainerShip_Click;
//
// buttonCreateShip
//
buttonCreateShip.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonCreateShip.Location = new Point(130, 273);
buttonCreateShip.Margin = new Padding(3, 2, 3, 2);
buttonCreateShip.Name = "buttonCreateShip";
buttonCreateShip.Size = new Size(115, 58);
buttonCreateShip.TabIndex = 6;
buttonCreateShip.Text = "Создать корабль";
buttonCreateShip.UseVisualStyleBackColor = true;
buttonCreateShip.Click += ButtonCreateShip_Click;
//
// buttonRight
//
buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonRight.BackgroundImage = (Image)resources.GetObject("buttonRight.BackgroundImage");
buttonRight.BackgroundImageLayout = ImageLayout.Zoom;
buttonRight.Location = new Point(735, 308);
buttonRight.Margin = new Padding(3, 2, 3, 2);
buttonRight.Name = "buttonRight";
buttonRight.Size = new Size(26, 22);
buttonRight.TabIndex = 2;
buttonRight.UseVisualStyleBackColor = true;
buttonRight.Click += buttonMove_Click;
//
// buttonDown
//
buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonDown.BackgroundImage = (Image)resources.GetObject("buttonDown.BackgroundImage");
buttonDown.BackgroundImageLayout = ImageLayout.Zoom;
buttonDown.Location = new Point(704, 308);
buttonDown.Margin = new Padding(3, 2, 3, 2);
buttonDown.Name = "buttonDown";
buttonDown.Size = new Size(26, 22);
buttonDown.TabIndex = 3;
buttonDown.UseVisualStyleBackColor = true;
buttonDown.Click += buttonMove_Click;
//
// buttonLeft
//
buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonLeft.BackgroundImage = (Image)resources.GetObject("buttonLeft.BackgroundImage");
buttonLeft.BackgroundImageLayout = ImageLayout.Zoom;
buttonLeft.Location = new Point(672, 308);
buttonLeft.Margin = new Padding(3, 2, 3, 2);
buttonLeft.Name = "buttonLeft";
buttonLeft.Size = new Size(26, 22);
buttonLeft.TabIndex = 4;
buttonLeft.UseVisualStyleBackColor = true;
buttonLeft.Click += buttonMove_Click;
//
// buttonUp
//
buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonUp.BackgroundImage = (Image)resources.GetObject("buttonUp.BackgroundImage");
buttonUp.BackgroundImageLayout = ImageLayout.Zoom;
buttonUp.Location = new Point(704, 281);
buttonUp.Margin = new Padding(3, 2, 3, 2);
buttonUp.Name = "buttonUp";
buttonUp.Size = new Size(26, 22);
buttonUp.TabIndex = 5;
buttonUp.UseVisualStyleBackColor = true;
buttonUp.Click += buttonMove_Click;
//
// buttonStep
//
buttonStep.Location = new Point(638, 34);
buttonStep.Margin = new Padding(3, 2, 3, 2);
buttonStep.Name = "buttonStep";
buttonStep.Size = new Size(112, 23);
buttonStep.TabIndex = 8;
buttonStep.Text = "Шаг";
buttonStep.UseVisualStyleBackColor = true;
buttonStep.Click += ButtonStep_Click;
//
// comboBoxStrategy
//
comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxStrategy.FormattingEnabled = true;
comboBoxStrategy.Items.AddRange(new object[] { "К центру", "К правому нижнему краю" });
comboBoxStrategy.Location = new Point(622, 9);
comboBoxStrategy.Margin = new Padding(3, 2, 3, 2);
comboBoxStrategy.Name = "comboBoxStrategy";
comboBoxStrategy.Size = new Size(140, 23);
comboBoxStrategy.TabIndex = 7;
//
// button1
//
button1.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
button1.Location = new Point(251, 273);
button1.Margin = new Padding(3, 2, 3, 2);
button1.Name = "button1";
button1.Size = new Size(115, 58);
button1.TabIndex = 9;
button1.Text = "Выбрать корабль";
button1.UseVisualStyleBackColor = true;
button1.Click += buttonSelectedContainerShip_Click;
//
// FormShips
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(772, 340);
Controls.Add(button1);
Controls.Add(buttonStep);
Controls.Add(comboBoxStrategy);
Controls.Add(buttonCreateShip);
Controls.Add(buttonUp);
Controls.Add(buttonLeft);
Controls.Add(buttonDown);
Controls.Add(buttonRight);
Controls.Add(buttonCreateContainerShip);
Controls.Add(pictureBoxShips);
Margin = new Padding(3, 2, 3, 2);
Name = "FormShips";
StartPosition = FormStartPosition.CenterScreen;
Text = "ContainerShip";
((System.ComponentModel.ISupportInitialize)pictureBoxShips).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private PictureBox pictureBoxShips;
private Button buttonCreateContainerShip;
private Button buttonCreateShip;
private Button buttonRight;
private Button buttonDown;
private Button buttonLeft;
private Button buttonUp;
private Button buttonStep;
private ComboBox comboBoxStrategy;
private Button button1;
}
}

167
ContainerShip/FormShips.cs Normal file
View File

@ -0,0 +1,167 @@
using ContainerShip.DrawningObjects;
using ContainerShip.MovementStrategy;
namespace ContainerShip
{
public partial class FormShips : Form
{
private DrawningShip? _drawningShip;
/// <summary>
/// Ñòðàòåãèÿ ïåðåìåùåíèÿ
/// </summary>
private AbstractStrategy? _abstractStrategy;
/// </summary>
/// Âûáðàííûé êîðàáëü
/// </summary>
public DrawningShip? SelectedShip { get; private set; }
public FormShips()
{
InitializeComponent();
_abstractStrategy = null;
SelectedShip = null;
}
private void Draw()
{
if (_drawningShip == null)
{
return;
}
Bitmap bmp = new(pictureBoxShips.Width,
pictureBoxShips.Height);
Graphics gr = Graphics.FromImage(bmp);
_drawningShip.DrawTransport(gr);
pictureBoxShips.Image = bmp;
}
/// <summary>
/// Îáðàáîòêà íàæàòèÿ êíîïêè "Ñîçäàòü êîíòåéíåðîâîç"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCreateContainerShip_Click(object sender, EventArgs e)
{
Random random = new Random();
Color color = Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256));
//TODO âûáîð îñíîâíîãî öâåòà
ColorDialog dialog = new();
if (dialog.ShowDialog() == DialogResult.OK)
{
color = dialog.Color;
}
Color dopColor = Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256));
//TODO âûáîð äîïîëíèòåëüíîãî öâåòà
if (dialog.ShowDialog() == DialogResult.OK)
{
dopColor = dialog.Color;
}
_drawningShip = new DrawingContainerShip(random.Next(200, 400), random.Next(1000, 3000),
color, dopColor, Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2)),
pictureBoxShips.Width, pictureBoxShips.Height);
_drawningShip.SetPosition(random.Next(10, 200), random.Next(10, 200));
Draw();
}
/// <summary>
/// Îáðàáîòêà íàæàòèÿ êíîïêè "Ñîçäàòü êîðàáëü"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCreateShip_Click(object sender, EventArgs e)
{
Random random = new();
Color color = Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256));
//TODO âûáîð îñíîâíîãî öâåòà
ColorDialog dialog = new();
if (dialog.ShowDialog() == DialogResult.OK)
{
color = dialog.Color;
}
_drawningShip = new DrawningShip(random.Next(100, 300),
random.Next(1000, 3000), color,
pictureBoxShips.Width, pictureBoxShips.Height);
_drawningShip.SetPosition(random.Next(10, 100), random.Next(10, 100));
Draw();
}
private void buttonMove_Click(object sender, EventArgs e)
{
if (_drawningShip == null)
{
return;
}
string name = ((Button)sender)?.Name ?? string.Empty;
switch (name)
{
case "buttonUp":
_drawningShip.MoveTransport(DirectionType.Up);
break;
case "buttonDown":
_drawningShip.MoveTransport(DirectionType.Down);
break;
case "buttonLeft":
_drawningShip.MoveTransport(DirectionType.Left);
break;
case "buttonRight":
_drawningShip.MoveTransport(DirectionType.Right);
break;
}
Draw();
}
/// <summary>
/// Îáðàáîòêà íàæàòèÿ êíîïêè "Øàã"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonStep_Click(object sender, EventArgs e)
{
if (_drawningShip == null)
{
return;
}
if (comboBoxStrategy.Enabled)
{
_abstractStrategy = comboBoxStrategy.SelectedIndex
switch
{
0 => new MoveToCenter(),
1 => new MoveToBorder(),
_ => null,
};
if (_abstractStrategy == null)
{
return;
}
_abstractStrategy.SetData(new
DrawingObjectShip(_drawningShip), pictureBoxShips.Width,
pictureBoxShips.Height);
comboBoxStrategy.Enabled = false;
}
if (_abstractStrategy == null)
{
return;
}
_abstractStrategy.MakeStep();
Draw();
if (_abstractStrategy.GetStatus() == Status.Finish)
{
comboBoxStrategy.Enabled = true;
_abstractStrategy = null;
}
}
private void buttonSelectedContainerShip_Click(object sender, EventArgs e)
{
SelectedShip = _drawningShip;
DialogResult = DialogResult.OK;
}
}
}

View File

@ -0,0 +1,431 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="buttonRight.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<data name="buttonDown.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<data name="buttonLeft.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
66z/B3WfwOzuK8ExAAAAAElFTkSuQmCC
</value>
</data>
<data name="buttonUp.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
</root>

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ContainerShip.MovementStrategy
{
public interface IMoveableObject
{
ObjectParameters? GetObjectPosition { get; }
int GetStep { get; }
bool CheckCanMove(DirectionType direction);
void MoveObject(DirectionType direction);
}
}

View File

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

View File

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

View File

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

46
ContainerShip/Program.cs Normal file
View File

@ -0,0 +1,46 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Serilog;
namespace ContainerShip
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
var services = new ServiceCollection();
ConfigureServices(services);
using (ServiceProvider serviceProvider = services.BuildServiceProvider())
{
Application.Run(serviceProvider.GetRequiredService<FormShipCollection>());
}
}
private static void ConfigureServices(ServiceCollection services)
{
services.AddSingleton<FormShipCollection>().AddLogging(option =>
{
string[] path = Directory.GetCurrentDirectory().Split('\\');
string pathNeed = "";
for (int i = 0; i < path.Length - 3; i++)
{
pathNeed += path[i] + "\\";
}
var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile(path: $"{pathNeed}serilog.json", optional: false, reloadOnChange: true).Build();
var logger = new LoggerConfiguration().ReadFrom.Configuration(configuration).CreateLogger();
option.SetMinimumLevel(LogLevel.Information);
option.AddSerilog(logger);
});
}
}
}

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ContainerShip.Properties {
using System;
/// <summary>
/// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д.
/// </summary>
// Этот класс создан автоматически классом 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() {
}
/// <summary>
/// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом.
/// </summary>
[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("ContainerShip.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Перезаписывает свойство CurrentUICulture текущего потока для всех
/// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ContainerShip.Exceptions;
namespace ContainerShip.Generic
{
internal class SetGeneric<T>
where T : class
{
private readonly List<T?> _places;
public int Count => _places.Count;
private readonly int _maxCount;
public SetGeneric(int count)
{
_maxCount = count;
_places = new List<T?>(count);
}
public void SortSet(IComparer<T?> comparer) => _places.Sort(comparer);
public int Insert(T ship, IEqualityComparer<T?>? equal = null)
{
return Insert(ship, 0, equal);
}
public int Insert(T ship, int position, IEqualityComparer<T?>? equal = null)
{
if (Count >= _maxCount)
{
throw new StorageOverflowException(_maxCount);
}
if (position < 0 || position >= _maxCount)
{
throw new IndexOutOfRangeException("Индекс вне границ коллекции");
}
if (equal != null && _places.Contains(ship, equal))
{
throw new ArgumentException("Данный объект уже есть в коллекции");
}
_places.Insert(position, ship);
return 0;
}
public bool Remove(int position)
{
if (position < 0 || position >= Count)
{
throw new ShipNotFoundException(position);
}
_places.RemoveAt(position);
return true;
}
public T? this[int position]
{
get
{
if (position < 0 || position >= Count)
{
return null;
}
return _places[position];
}
set
{
if (position < 0 || Count >= _maxCount)
{
return;
}
_places.Insert(position, value);
}
}
public IEnumerable<T?> GetShip(int? maxShip = null)
{
for (int i = 0; i < _places.Count; ++i)
{
yield return _places[i];
if (maxShip.HasValue && i == maxShip.Value)
{
yield break;
}
}
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ContainerShip.DrawningObjects;
using ContainerShip.Entities;
namespace ContainerShip.Entities
{
internal class ShipCompareByColor : IComparer<DrawningShip>
{
public int Compare(DrawningShip? x, DrawningShip? y)
{
if (x == null || x.EntityShip == null)
throw new ArgumentNullException(nameof(x));
if (y == null || y.EntityShip == null)
throw new ArgumentNullException(nameof(y));
var xPlane = x.EntityShip;
var yPlane = y.EntityShip;
if (xPlane.BodyColor != yPlane.BodyColor)
return xPlane.BodyColor.Name.CompareTo(yPlane.BodyColor.Name);
var speedCompare = x.EntityShip.Speed.CompareTo(y.EntityShip.Speed);
if (speedCompare != 0)
return speedCompare;
return x.EntityShip.Weight.CompareTo(y.EntityShip.Weight);
}
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ContainerShip.DrawningObjects;
using ContainerShip.Entities;
namespace ContainerShip.Entities
{
internal class ShipCompareByType : IComparer<DrawningShip>
{
public int Compare(DrawningShip? x, DrawningShip? y)
{
if (x == null || x.EntityShip == null)
throw new ArgumentNullException(nameof(x));
if (y == null || y.EntityShip == null)
throw new ArgumentNullException(nameof(y));
if (x.GetType().Name != y.GetType().Name)
return x.GetType().Name.CompareTo(y.GetType().Name);
var speedCompare = x.EntityShip.Speed.CompareTo(y.EntityShip.Speed);
if (speedCompare != 0)
return speedCompare;
return x.EntityShip.Weight.CompareTo(y.EntityShip.Weight);
}
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace ContainerShip.Exceptions
{
internal class ShipNotFoundException : ApplicationException
{
public ShipNotFoundException(int i) : base($"Не найден объект по позиции {i}") { }
public ShipNotFoundException() : base() { }
public ShipNotFoundException(string message) : base(message) { }
public ShipNotFoundException(string message, Exception exception) : base(message, exception) { }
protected ShipNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ContainerShip.Generic
{
internal class ShipsCollectionInfo : IEquatable<ShipsCollectionInfo>
{
public string Name { get; private set; }
public string Description { get; private set; }
public ShipsCollectionInfo(string name, string description)
{
Name = name;
Description = description;
}
public bool Equals(ShipsCollectionInfo? other)
{
if (ReferenceEquals(other, null))
return false;
return Name.Equals(other.Name);
}
public override int GetHashCode() => Name.GetHashCode();
}
}

View File

@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ContainerShip.Generic;
using ContainerShip.MovementStrategy;
using ContainerShip.DrawningObjects;
using ContainerShip.Exceptions;
namespace ContainerShip.Generic
{
internal class ShipsGenericCollection<T, U>
where T : DrawningShip
where U : IMoveableObject
{
public int count => _collection.Count;
private readonly int _pictureWidth;
private readonly int _pictureHeight;
private readonly int _placeSizeWidth = 210;
private readonly int _placeSizeHeight = 90;
private readonly SetGeneric<T> _collection;
public ShipsGenericCollection(int picWidth, int picHeight)
{
int width = picWidth / _placeSizeWidth;
int height = picHeight / _placeSizeHeight;
_pictureWidth = picWidth;
_pictureHeight = picHeight;
_collection = new SetGeneric<T>(width * height);
}
public void Sort(IComparer<T?> comparer) => _collection.SortSet(comparer);
public static int operator +(ShipsGenericCollection<T, U> collect, T? obj)
{
if (obj != null)
{
return collect._collection.Insert(obj, new DrawningShipEqutables());
}
return -1;
}
public static bool operator -(ShipsGenericCollection<T, U> collect, int pos)
{
if (collect._collection[pos] == null)
{
throw new ShipNotFoundException(pos);
}
return collect?._collection.Remove(pos) ?? false;
}
public U? GetU(int pos)
{
return (U?)_collection[pos]?.GetMoveableObject;
}
public Bitmap ShowShips()
{
Bitmap bmp = new(_pictureWidth, _pictureHeight);
Graphics gr = Graphics.FromImage(bmp);
DrawBackground(gr);
DrawObjects(gr);
return bmp;
}
private void DrawBackground(Graphics g)
{
Pen pen = new(Color.Black, 3);
for (int i = 0; i < _pictureWidth / _placeSizeWidth; i++)
{
for (int j = 0; j < _pictureHeight / _placeSizeHeight +
1; ++j)
{//линия разметки места
g.DrawLine(pen, i * _placeSizeWidth, j *
_placeSizeHeight, i * _placeSizeWidth + _placeSizeWidth / 2, j *
_placeSizeHeight);
}
g.DrawLine(pen, i * _placeSizeWidth, 0, i *
_placeSizeWidth, _pictureHeight / _placeSizeHeight * _placeSizeHeight);
}
}
private void DrawObjects(Graphics g)
{
// координаты
int x = _pictureWidth / _placeSizeWidth - 1;
int y = _pictureHeight / _placeSizeHeight - 1;
for (int i = 0; i < _collection.Count; i++)
{
DrawningShip _ship = _collection[i];
if (_ship != null) {
if (x < 0)
{
x = _pictureWidth / _placeSizeWidth - 1;
y--;
}
_ship.SetPosition(_placeSizeWidth * x, _placeSizeHeight * y);
_ship.DrawTransport(g);
x--;
}
}
}
public IEnumerable<T?> GetShip => _collection.GetShip();
}
}

View File

@ -0,0 +1,172 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ContainerShip.MovementStrategy;
using ContainerShip.DrawningObjects;
using ContainerShip.Entities;
namespace ContainerShip.Generic
{
internal class ShipsGenericStorage
{
//Словарь (хранилище)
readonly Dictionary<ShipsCollectionInfo, ShipsGenericCollection<DrawningShip, DrawingObjectShip>> _shipStorages;
//Возвращение списка названий наборов
public List<ShipsCollectionInfo> Keys => _shipStorages.Keys.ToList();
//Ширина окна отрисовки
private readonly int _pictureWidth;
//Высота окна отрисовки
private readonly int _pictureHeight;
// Разделитель для записи ключа и значения элемента словаря
private static readonly char _separatorForKeyValue = '|';
// Разделитель для записей коллекции данных в файл
private readonly char _separatorRecords = ';';
// Разделитель для записи информации по объекту в файл
private static readonly char _separatorForObject = ':';
public ShipsGenericStorage(int pictureWidth, int pictureHeight)
{
_shipStorages = new Dictionary<ShipsCollectionInfo, ShipsGenericCollection<DrawningShip, DrawingObjectShip>>();
_pictureWidth = pictureWidth;
_pictureHeight = pictureHeight;
}
// Добавление набора
public void AddSet(string name)
{
ShipsCollectionInfo set = new ShipsCollectionInfo(name, string.Empty);
if (_shipStorages.ContainsKey(set))
return;
_shipStorages.Add(set, new ShipsGenericCollection<DrawningShip, DrawingObjectShip>(_pictureWidth, _pictureHeight));
}
// Удаление набора
public void DelSet(string name)
{
ShipsCollectionInfo set = new ShipsCollectionInfo(name, string.Empty);
// проверка, что нет набора с таким именем
if (!_shipStorages.ContainsKey(set))
return;
_shipStorages.Remove(set);
}
// Доступ к набору
public ShipsGenericCollection<DrawningShip, DrawingObjectShip>? this[string ind]
{
get
{
ShipsCollectionInfo set = new ShipsCollectionInfo(ind, string.Empty);
if (!_shipStorages.ContainsKey(set))
{
return null;
}
return _shipStorages[set];
}
}
// Сохранение информации по автомобилям в хранилище в файл
public bool SaveData(string filename)
{
if (_shipStorages.Count == 0)
{
throw new InvalidOperationException("Невалидная операция, нет данных для сохранения");
}
if (File.Exists(filename))
{
File.Delete(filename);
}
using (StreamWriter sw = File.CreateText(filename))
{
sw.WriteLine($"ShipStorage");
foreach (var record in _shipStorages)
{
StringBuilder records = new();
if (record.Value.count <= 0)
{
throw new InvalidOperationException("Невалидная операция, нет данных для сохранения");
}
foreach (DrawningShip? elem in record.Value.GetShip)
{
records.Append($"{elem?.GetDataForSave(_separatorForObject)}{_separatorRecords}");
}
sw.WriteLine($"{record.Key}{_separatorForKeyValue}{records}");
}
}
return true;
}
// Загрузка информации по автомобилям в хранилище из файла
public bool LoadData(string filename)
{
if (!File.Exists(filename))
{
throw new FileNotFoundException($"Файл {filename} не найден");
}
using (StreamReader sr = File.OpenText(filename))
{
// 1-ая строка
string? curLine = sr.ReadLine();
// пустая или не те данные
if (curLine == null || curLine.Length == 0 || !curLine.StartsWith("ShipStorage"))
{
throw new ArgumentException("Неверный формат данных");
}
// очищаем
_shipStorages.Clear();
// загружаем данные построчно
curLine = sr.ReadLine();
if (curLine == null || curLine.Length == 0)
{
throw new ArgumentException("Нет данных");
}
while (curLine != null)
{
// загружаем запись
if (!curLine.Contains(_separatorRecords))
{
throw new ArgumentException("Коллекция пуста");
}
string[] record = curLine.Split(_separatorForKeyValue, StringSplitOptions.RemoveEmptyEntries);
// загружаем набор
ShipsGenericCollection<DrawningShip, DrawingObjectShip> collection = new(_pictureWidth, _pictureHeight);
// record[0] - название набора, record[1] - куча объектов
string[] set = record[1].Split(_separatorRecords, StringSplitOptions.RemoveEmptyEntries);
foreach (string elem in set)
{
DrawningShip? ship = elem?.CreateDrawningShip(_separatorForObject, _pictureWidth, _pictureHeight);
// проверяем, не переполнится ли коллекция
if (ship != null)
{
if (collection + ship == -1)
{
throw new InvalidOperationException("Невалидная операция, ошибка добавления в коллекцию");
}
}
}
_shipStorages.Add(new ShipsCollectionInfo(record[0], string.Empty), collection);
curLine = sr.ReadLine();
}
}
return true;
}
}
}

15
ContainerShip/Status.cs Normal file
View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ContainerShip.MovementStrategy
{
public enum Status
{
NotInit,
InProgress,
Finish
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace ContainerShip.Exceptions
{
[Serializable]
internal class StorageOverflowException : ApplicationException
{
public StorageOverflowException(int count) : base($"В наборе превышено допустимое количество: {count}") { }
public StorageOverflowException() : base() { }
public StorageOverflowException(string message) : base(message) { }
public StorageOverflowException(string message, Exception exception) : base(message, exception) { }
protected StorageOverflowException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}

11
ContainerShip/nlog.config Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="Info">
<targets>
<target xsi:type="File" name="tofile" fileName="carlog-${shortdate}.log" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="tofile" />
</rules>
</nlog>
</configuration>

View File

@ -0,0 +1,20 @@
{
"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "Logs/carlog.log",
"rollingInterval": "Day",
"outputTemplate": "[{Timestamp:HH:mm:ss.fff}]{Level:u4}: {Message:lj}{NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
"Properties": {
"Application": "ContainerShip"
}
}
}