In Process : check array and add list implementation

This commit is contained in:
Inna Pruidze 2024-06-13 00:05:05 +04:00
parent cb015204b9
commit 8733297af1
9 changed files with 700 additions and 1 deletions

View File

@ -0,0 +1,70 @@
using ProjectCruiser.DrawningSamples;
namespace ProjectCruiser;
/// Абстракция компании, хранящий коллекцию автомобилей
/// </summary>
public abstract class AbstractCompany
{
// Размеры места
protected readonly int _placeSizeWidth = 312; // ширина
protected readonly int _placeSizeHeight = 56; // высота
// Ширина окна
protected readonly int _pictureWidth;
// Высота окна
protected readonly int _pictureHeight;
// Коллекция автомобилей
protected ICollectionGenObj<DrawningBase>? _collection = null;
private int GetMaxCount => _pictureWidth * _pictureHeight /
(_placeSizeWidth * _placeSizeHeight);
public AbstractCompany(int picWidth, int picHeight,
ICollectionGenObj<DrawningBase>? collection)
{
_pictureWidth = picWidth;
_pictureHeight = picHeight;
_collection = collection;
_collection.SetMaxCount = GetMaxCount;
}
// Перегрузка оператора сложения для класса
// [ ! ] insted of bool:
public static int operator +(AbstractCompany cmp,
DrawningBase trasport) => (cmp._collection.Insert(trasport));
// Перегрузка оператора удаления для класса
public static DrawningBase operator -(AbstractCompany cmp,
int pos) => (cmp._collection.Remove(pos));
// Получение случайного объекта из коллекции
public DrawningBase? GetRandomObject()
{
Random rnd = new();
return _collection?.GetItem(rnd.Next(GetMaxCount));
}
// Вывод всей коллекции
public Bitmap? Show()
{
Bitmap bitmap = new(_pictureWidth, _pictureHeight);
Graphics graphics = Graphics.FromImage(bitmap);
DrawBackground(graphics);
SetObjectsPosition();
for (int i = 0; i < (_collection?.Count ?? 0); ++i)
{
DrawningBase? obj = _collection?.GetItem(i);
obj?.DrawTransport(graphics);
}
return bitmap;
}
// Вывод заднего фона
protected abstract void DrawBackground(Graphics g);
// Расстановка объектов
protected abstract void SetObjectsPosition();
}

View File

@ -0,0 +1,94 @@
namespace ProjectCruiser;
public class ArrayGenObj<T> : ICollectionGenObj<T>
where T : class
{
// Массив объектов, которые храним
private T?[] _collection;
public int Count => _collection.Length;
public int SetMaxCount
{
set
{
if (value > 0)
{
if (_collection.Length > 0) Array.Resize(ref _collection, value);
else _collection = new T?[value];
}
}
}
// public int SetMaxCount { set { if (value > 0) { _collection = new T?[value]; } } }
public ArrayGenObj()
{
_collection = Array.Empty<T?>();
}
// methods :
public T? GetItem(int index)
{
if (index > Count || index < 0)
{
return null;
}
return _collection[index];
}
public int Insert(T? item)
{
// any empty place
for (int i = 0; i < Count; i++)
{
if (_collection[i] == null)
{
_collection[i] = item;
return i;
}
}
return -1;
}
public int Insert(T? item, int index)
{
if (_collection[index] == null)
{
_collection[index] = item;
return index;
}
else
{
int min_diff = 100, min_index = 100;
for (int i = 0; i < Count; i++)
{
if (_collection[i] == null
&& min_diff > Math.Abs(index - i))
{
min_diff = Math.Abs(index - i);
min_index = i;
}
}
_collection[min_index] = item;
return min_index;
}
return -1;
}
public T? Remove(int index)
{
T? item;
if (index < Count && index >= 0)
{
item = _collection[index];
_collection[index] = null;
return item;
}
return null;
}
}

View File

@ -0,0 +1,24 @@
namespace ProjectCruiser;
public interface ICollectionGenObj<T> where T : class
{
// Кол-во объектов в коллекции
int Count { get; }
// Установка max кол-ва элементов
int SetMaxCount { set; }
/// Добавление объекта в коллекцию
/// <param name="obj">Добавляемый объект</param>
/// <returns>true - вставка прошла удачно, false - вставка не удалась</returns>
int Insert(T obj);
int Insert(T obj, int position);
/// Удаление объекта из коллекции с конкретной позиции
/// <param name="position">Позиция</param>
/// <returns>true - удаление прошло удачно, false - удаление не удалось</returns>
T? Remove(int position);
// Получение объекта по позиции
T? GetItem(int position);
}

View File

@ -11,6 +11,19 @@ namespace ProjectCruiser
// Стратегия перемещения // Стратегия перемещения
private AbstractStrategy? _strategy; private AbstractStrategy? _strategy;
// Получение объекта
public DrawningBase SetShip
{
set
{
_drawningCruiser = value;
_drawningCruiser.SetPictureSize(pictureBoxCr.Width, pictureBoxCr.Height);
comboBoxStrategy.Enabled = true;
_strategy = null;
Draw();
}
}
public OceanForm1() public OceanForm1()
{ {
InitializeComponent(); InitializeComponent();

View File

@ -11,7 +11,8 @@ namespace ProjectCruiser
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize(); ApplicationConfiguration.Initialize();
Application.Run(new OceanForm1()); Application.Run(new ServiceForm2());
// -> OceanForm1() inside*
} }
} }
} }

172
ProjectCruiser/ServiceForm2.Designer.cs generated Normal file
View File

@ -0,0 +1,172 @@
namespace ProjectCruiser
{
partial class ServiceForm2
{
/// <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()
{
comboBoxArrList = new ComboBox();
btnAddBase = new Button();
groupBox = new GroupBox();
btnUpdate = new Button();
btnTest = new Button();
btnDelete = new Button();
maskedTextBoxPosition = new MaskedTextBox();
btnAddCruiser = new Button();
pictureBox = new PictureBox();
groupBox.SuspendLayout();
((System.ComponentModel.ISupportInitialize)pictureBox).BeginInit();
SuspendLayout();
//
// comboBoxArrList
//
comboBoxArrList.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
comboBoxArrList.FormattingEnabled = true;
comboBoxArrList.Location = new Point(17, 54);
comboBoxArrList.Name = "comboBoxArrList";
comboBoxArrList.Size = new Size(242, 40);
comboBoxArrList.TabIndex = 0;
comboBoxArrList.SelectedIndexChanged += SelectorCompany_SelectedIndexChanged;
//
// btnAddBase
//
btnAddBase.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
btnAddBase.Location = new Point(17, 561);
btnAddBase.Name = "btnAddBase";
btnAddBase.Size = new Size(242, 46);
btnAddBase.TabIndex = 1;
btnAddBase.Text = "Add ship";
btnAddBase.UseVisualStyleBackColor = true;
btnAddBase.Click += btnAddBase_Click;
//
// groupBox
//
groupBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
groupBox.Controls.Add(btnUpdate);
groupBox.Controls.Add(btnTest);
groupBox.Controls.Add(btnDelete);
groupBox.Controls.Add(maskedTextBoxPosition);
groupBox.Controls.Add(btnAddCruiser);
groupBox.Controls.Add(btnAddBase);
groupBox.Controls.Add(comboBoxArrList);
groupBox.Location = new Point(1006, 12);
groupBox.Name = "groupBox";
groupBox.Size = new Size(274, 938);
groupBox.TabIndex = 2;
groupBox.TabStop = false;
groupBox.Text = "Tool panel";
//
// btnUpdate
//
btnUpdate.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
btnUpdate.Location = new Point(17, 865);
btnUpdate.Name = "btnUpdate";
btnUpdate.Size = new Size(242, 46);
btnUpdate.TabIndex = 6;
btnUpdate.Text = "Update";
btnUpdate.UseVisualStyleBackColor = true;
btnUpdate.Click += btnRefresh_Click;
//
// btnTest
//
btnTest.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
btnTest.Location = new Point(17, 795);
btnTest.Name = "btnTest";
btnTest.Size = new Size(242, 64);
btnTest.TabIndex = 5;
btnTest.Text = "Choose for testing";
btnTest.UseVisualStyleBackColor = true;
btnTest.Click += btnChooseforTest_Click;
//
// btnDelete
//
btnDelete.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
btnDelete.Location = new Point(17, 732);
btnDelete.Name = "btnDelete";
btnDelete.Size = new Size(242, 46);
btnDelete.TabIndex = 4;
btnDelete.Text = "Delete";
btnDelete.UseVisualStyleBackColor = true;
btnDelete.Click += btnRemoveCar_Click;
//
// maskedTextBoxPosition
//
maskedTextBoxPosition.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
maskedTextBoxPosition.Location = new Point(17, 682);
maskedTextBoxPosition.Mask = "00";
maskedTextBoxPosition.Name = "maskedTextBoxPosition";
maskedTextBoxPosition.Size = new Size(242, 39);
maskedTextBoxPosition.TabIndex = 3;
maskedTextBoxPosition.ValidatingType = typeof(int);
//
// btnAddCruiser
//
btnAddCruiser.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
btnAddCruiser.Location = new Point(17, 613);
btnAddCruiser.Name = "btnAddCruiser";
btnAddCruiser.Size = new Size(242, 46);
btnAddCruiser.TabIndex = 2;
btnAddCruiser.Text = "Add cruiser";
btnAddCruiser.UseVisualStyleBackColor = true;
btnAddCruiser.Click += btnAddAdvanced_Click;
//
// pictureBox
//
pictureBox.Dock = DockStyle.Left;
pictureBox.Location = new Point(0, 0);
pictureBox.Name = "pictureBox";
pictureBox.Size = new Size(988, 959);
pictureBox.TabIndex = 3;
pictureBox.TabStop = false;
//
// ServiceForm2
//
AutoScaleDimensions = new SizeF(13F, 32F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1292, 959);
Controls.Add(pictureBox);
Controls.Add(groupBox);
Name = "ServiceForm2";
Text = "ServiceForm2";
groupBox.ResumeLayout(false);
groupBox.PerformLayout();
((System.ComponentModel.ISupportInitialize)pictureBox).EndInit();
ResumeLayout(false);
}
#endregion
private ComboBox comboBoxArrList;
private Button btnAddBase;
private GroupBox groupBox;
private Button btnAddCruiser;
private Button btnUpdate;
private Button btnTest;
private Button btnDelete;
private MaskedTextBox maskedTextBoxPosition;
private PictureBox pictureBox;
}
}

View File

@ -0,0 +1,137 @@
using System.Windows.Forms;
using ProjectCruiser.DrawningSamples;
namespace ProjectCruiser;
public partial class ServiceForm2 : Form
{
// Компания
private AbstractCompany? _company = null;
public ServiceForm2()
{
InitializeComponent();
}
// Выбор компании
private void SelectorCompany_SelectedIndexChanged(object sender, EventArgs e)
{
switch (comboBoxArrList.Text)
{
case "Storage":
_company = new ShipSharingService(pictureBox.Width, pictureBox.Height,
new ArrayGenObj<DrawningBase>());
break;
}
}
// Color picker
private static Color pickColor(Random r)
{
Color cl = Color.FromArgb(r.Next(0, 256), r.Next(0, 256), r.Next(0, 256));
ColorDialog dialog = new();
if (dialog.ShowDialog() == DialogResult.OK)
{ cl = dialog.Color; }
return cl;
}
// Добавление обычного корабля
private void btnAddBase_Click(object sender, EventArgs e) =>
CreateObject(nameof(DrawningBase));
// Добавление продвинутого
private void btnAddAdvanced_Click(object sender, EventArgs e) =>
CreateObject(nameof(DrawningCruiser));
// Создание объекта класса-перемещения
private void CreateObject(string type)
{
if (_company == null)
{
return;
}
Random random = new();
DrawningBase drawningCar;
switch (type)
{
case nameof(DrawningBase):
drawningCar = new DrawningBase(random.Next(100, 300),
random.Next(1000, 3000), pickColor(random));
break;
case nameof(DrawningCruiser):
// (TODO) вызов диалогового окна для выбора цвета >>>
drawningCar = new DrawningCruiser(random.Next(100, 300),
random.Next(1000, 3000), pickColor(random), pickColor(random),
Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2)));
break;
default:
return;
}
if (_company + drawningCar > 0)
{
MessageBox.Show("> Object was added");
pictureBox.Image = _company.Show();
}
else
{
MessageBox.Show("[!] Failed to add object");
}
}
// Удаление объекта
private void btnRemoveCar_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(maskedTextBoxPosition.Text)
|| _company == null) return;
if (MessageBox.Show("[*] Remove object: Are you sure?", "Remove",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) return;
int pos = Convert.ToInt32(maskedTextBoxPosition.Text);
if (_company - Convert.ToInt32(maskedTextBoxPosition.Text) != null)
{
MessageBox.Show("> Object was removed");
pictureBox.Image = _company.Show();
}
else MessageBox.Show("[!] Failed to remove object");
}
// Передача объекта в другую форму
private void btnChooseforTest_Click(object sender, EventArgs e)
{
if (_company == null)
{
return;
}
DrawningBase? car = null;
int counter = 100;
while (car == null)
{
car = _company.GetRandomObject();
counter--;
if (counter <= 0)
{
break;
}
}
if (car == null)
{
return;
}
OceanForm1 form = new() { SetShip = car };
form.ShowDialog();
}
// Перерисовка коллекции
private void btnRefresh_Click(object sender, EventArgs e)
{
if (_company == null)
{
return;
}
pictureBox.Image = _company.Show();
}
}

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,68 @@
using ProjectCruiser.DrawningSamples;
namespace ProjectCruiser;
public class ShipSharingService : AbstractCompany
{
protected int MaxInRow { get; private set; }
protected int MaxInColon { get; private set; }
private int fromBorder = 20, fromCeiling = 20, between = 30;
public ShipSharingService(int picWidth, int picHeight,
ICollectionGenObj<DrawningBase> collection)
: base(picWidth, picHeight, collection)
{
MaxInRow = (picWidth - fromBorder - fromCeiling)
/ (_placeSizeWidth + between);
MaxInColon = (picHeight - fromBorder - fromCeiling)
/ _placeSizeHeight;
}
protected override void DrawBackground(Graphics g)
{
Pen pen = new(Color.Black, 2);
int currentH = 10, currentW = 10;
for (int i = 0; i < MaxInRow; i++)
{
currentH = 10;
for (int j = 0; j < MaxInColon; j++)
{
g.DrawLine(pen, currentW + _placeSizeWidth, currentH - 1,
currentW - 1, currentH - 1);
g.DrawLine(pen, currentW - 1, currentH - 1, currentW - 1,
currentH + _placeSizeHeight);
currentH += _placeSizeHeight + 1;
}
currentW += _placeSizeWidth + between;
}
}
protected override void SetObjectsPosition()
{
int index_collection = 0;
int newX = fromBorder, newY = fromCeiling;
if (_collection != null)
{
for (int i = 0; i < MaxInColon; ++i)
{
newX = fromBorder;
for (int j = 0; j < MaxInRow; ++j)
{
if (_collection.GetItem(index_collection) != null)
{
_collection.GetItem(index_collection).SetPictureSize(_pictureWidth, _pictureHeight);
_collection.GetItem(index_collection).SetPosition(newX, newY);
newX += _placeSizeWidth + between;
index_collection++;
}
}
newY += _placeSizeHeight + 2;
}
}
}
}