Compare commits

...

24 Commits

Author SHA1 Message Date
34abba54cc 8 лабораторная работа 2024-06-10 07:35:07 +04:00
996797c794 Добавили сортировку 2024-06-10 06:37:56 +04:00
5c7b6d8bf2 Добавили DrawningLinerCompareByType 2024-06-10 05:54:10 +04:00
859a9ffff6 изменили Insert d massive и list, также добавили новый класс ошибки 2024-06-10 05:44:42 +04:00
50755f3d53 Добавлен DrawningLinerEqutables 2024-06-10 05:33:55 +04:00
392189d5b2 Лабораторная работа сдана 2024-05-16 08:27:33 +04:00
7ac785ccfd Доработан Logger, а также исправлена ошибка с удалением лайнера 2024-05-15 09:37:25 +04:00
ba8685e9dc 7 лабораторная работа 2024-04-20 07:48:17 +04:00
3d5e3f3cdc Заменил SetMaxCount на MaxCount 2024-04-20 06:59:05 +04:00
572648c859 создание 6 лабораторной 2024-04-20 00:28:10 +04:00
0e0b374521 Исправил AllowDrop 2024-04-17 15:24:49 +04:00
2ab72ce5de Лабораторная работа 5 2024-04-17 10:15:59 +04:00
d1e6850818 Merge pull request 'labWork_04' (#5) from labWork_04 into labWork_05
Reviewed-on: #5
2024-04-17 08:11:21 +04:00
10ce368f63 Добавление новый способ хранения объектов в "Сервисе" 2024-04-03 08:28:54 +04:00
9aec819091 Финальное закрепление ветки 2024-03-24 16:26:53 +04:00
dac8a3ec17 Исправлены ошибки с отрисовкой sharing 2024-03-20 08:23:41 +04:00
359c50745b Добавление компании 2024-03-19 10:26:26 +04:00
fb4cc240a1 Adding abstract class 2024-03-15 09:36:48 +04:00
f1f6698e1f Добавление комментария в DrawningCommonLiner 2024-03-06 09:45:25 +04:00
ecfe3f3131 Добавлена стратегия на перемещение к центру и к краю 2024-03-06 09:38:21 +04:00
6c4691699b Создание родительского класса для entity liner 2024-03-06 07:52:17 +04:00
bd746e9288 С дополнительным первым заданием 2024-02-21 16:54:00 +04:00
997c87a792 Доработал SetPosition и SetPictureSize 2024-02-21 16:33:40 +04:00
kassslll
d50a0855a0 Лабораторная работа 1 2024-02-18 08:02:04 +04:00
50 changed files with 4440 additions and 75 deletions

View File

@ -0,0 +1,140 @@
using ProjectLiner.Drawnings;
using ProjectLiner.Exceptions;
using ProjectLiner.CollectionGenericObjects;
using ProjectLiner.Exceptions;
namespace ProjectLiner.CollectionGenericObjects
{
/// <summary>
/// Абстракция компании, хранящий коллекцию автомобилей
/// </summary>
public abstract class AbstractCompany
{
/// <summary>
/// Размер места (ширина)
/// </summary>
protected readonly int _placeSizeWidth = 210;
/// <summary>
/// Размер места (высота)
/// </summary>
protected readonly int _placeSizeHeight = 150;
/// <summary>
/// Ширина окна
/// </summary>
protected readonly int _pictureWidth;
/// <summary>
/// Высота окна
/// </summary>
protected readonly int _pictureHeight;
/// <summary>
/// Коллекция автомобилей
/// </summary>
protected ICollectionGenericObjects<DrawningCommonLiner>? _collection = null;
/// <summary>
/// Вычисление максимального количества элементов, который можно разместить в окне
/// </summary>
private int GetMaxCount => _pictureWidth / _placeSizeWidth * (_pictureHeight / _placeSizeHeight);
/// <summary>
/// Конструктор
/// </summary>
/// <param name="picWidth">Ширина окна</param>
/// <param name="picHeight">Высота окна</param>
/// <param name="collection">Коллекция автомобилей</param>
public AbstractCompany(int picWidth, int picHeight, ICollectionGenericObjects<DrawningCommonLiner> collection)
{
_pictureWidth = picWidth;
_pictureHeight = picHeight;
_collection = collection;
_collection.MaxCount = GetMaxCount;
}
/// <summary>
/// Перегрузка оператора сложения для класса
/// </summary>
/// <param name="company">Компания</param>
/// <param name="airplane">Добавляемый объект</param>
/// <returns></returns>
public static int operator +(AbstractCompany company, DrawningCommonLiner liner)
{
return company._collection.Insert(liner, new DrawningLinerEqutables() );
}
/// <summary>
/// Перегрузка оператора удаления для класса
/// </summary>
/// <param name="company">Компания</param>
/// <param name="position">Номер удаляемого объекта</param>
/// <returns></returns>
public static DrawningCommonLiner operator -(AbstractCompany company, int position)
{
return company._collection.Remove(position);
}
/// <summary>
/// Получение случайного объекта из коллекции
/// </summary>
/// <returns></returns>
public DrawningCommonLiner? GetRandomObject()
{
Random rnd = new();
try
{
return _collection?.Get(rnd.Next(GetMaxCount));
}
catch (ObjectNotFoundException)
{
return null;
}
}
/// <summary>
/// Вывод всей коллекции
/// </summary>
/// <returns></returns>
public Bitmap? Show()
{
Bitmap bitmap = new(_pictureWidth, _pictureHeight);
Graphics graphics = Graphics.FromImage(bitmap);
DrawBackgound(graphics);
SetObjectsPosition();
for (int i = 0; i < (_collection?.Count ?? 0); ++i)
{
try
{
DrawningCommonLiner? obj = _collection?.Get(i);
obj?.DrawTransport(graphics);
}
catch (ObjectNotFoundException)
{
continue;
}
}
return bitmap;
}
/// <summary>
/// Вывод заднего фона
/// </summary>
/// <param name="g"></param>
protected abstract void DrawBackgound(Graphics g);
/// <summary>
/// Расстановка объектов
/// </summary>
protected abstract void SetObjectsPosition();
/// <summary>
/// Сортировка коллекции
/// </summary>
/// <param name="comparer">Сравнитель объектов</param>
public void Sort(IComparer<DrawningCommonLiner?> comparer) => _collection?.CollectionSort(comparer);
}
}

View File

@ -0,0 +1,74 @@
using ProjectLiner.CollectionGenericObjects;
namespace ProjectLiner.CollectionGenericObjects;
/// <summary>
/// Класс, хранящиий информацию по коллекции
/// </summary>
public class CollectionInfo : IEquatable<CollectionInfo>
{
/// <summary>
/// Название
/// </summary>
public string Name { get; private set; }
/// <summary>
/// Тип
/// </summary>
public CollectionType CollectionType { get; private set; }
/// <summary>
/// Описание
/// </summary>
public string Description { get; private set; }
/// <summary>
/// Разделитель для записи информации по объекту в файл
/// </summary>
private static readonly string _separator = "-";
/// <summary>
/// Конструктор
/// </summary>
/// <param name="name">Название</param>
/// <param name="collectionType">Тип</param>
/// <param name="description">Описание</param>
public CollectionInfo(string name, CollectionType collectionType, string description)
{
Name = name;
CollectionType = collectionType;
Description = description;
}
/// <summary>
/// Создание объекта из строки
/// </summary>
/// <param name="data">Строка</param>
/// <returns>Объект или null</returns>
public static CollectionInfo? GetCollectionInfo(string data)
{
string[] strs = data.Split(_separator, StringSplitOptions.RemoveEmptyEntries);
if (strs.Length < 1 || strs.Length > 3)
{
return null;
}
return new CollectionInfo(strs[0],
(CollectionType)Enum.Parse(typeof(CollectionType), strs[1]), strs.Length > 2 ? strs[2] : string.Empty);
}
public override string ToString()
{
return Name + _separator + CollectionType + _separator + Description;
}
public bool Equals(CollectionInfo? other)
{
return Name == other?.Name;
}
public override bool Equals(object? obj)
{
return Equals(obj as CollectionInfo);
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}

View File

@ -0,0 +1,24 @@

namespace ProjectLiner.CollectionGenericObjects;
/// <summary>
/// Тип коллекции
/// </summary>
public enum CollectionType
{
/// <summary>
/// Неопределено
/// </summary>
None = 0,
/// <summary>
/// Массив
/// </summary>
Massive = 1,
/// <summary>
/// Список
/// </summary>
List = 2,
}

View File

@ -0,0 +1,68 @@
namespace ProjectLiner.CollectionGenericObjects
{
/// <summary>
/// Интерфейс описания действий для набора хранимых объектов
/// </summary>
/// <typeparam name="T">Параметр: ограничение - ссылочный тип</typeparam>
public interface ICollectionGenericObjects<T>
where T : class
{
/// <summary>
/// Количество объектов в коллекции
/// </summary>
int Count { get; }
/// <summary>
/// Установка максимального количества элементов
/// </summary>
int MaxCount { get; set; }
/// <summary>
/// Добавление объекта в коллекцию
/// </summary>
/// <param name="obj">Добавляемый объект</param>
/// /// <param name="comparer">Сравнение двух объектов</param>
/// <returns>true - вставка прошла удачно, false - вставка не удалась</returns>
int Insert(T obj, IEqualityComparer<T?>? comparer = null);
/// <summary>
/// Добавление объекта в коллекцию на конкретную позицию
/// </summary>
/// <param name="obj">Добавляемый объект</param>
/// <param name="position">Позиция</param>
/// /// <param name="comparer">Сравнение двух объектов</param>
/// <returns>true - вставка прошла удачно, false - вставка не удалась</returns>
int Insert(T obj, int position, IEqualityComparer<T?>? comparer = null);
/// <summary>
/// Удаление объекта из коллекции с конкретной позиции
/// </summary>
/// <param name="position">Позиция</param>
/// <returns>true - удаление прошло удачно, false - удаление не удалось</returns>
T? Remove(int position);
/// <summary>
/// Получение объекта по позиции
/// </summary>
/// <param name="position">Позиция</param>
/// <returns>Объект</returns>
T? Get(int position);
/// <summary>
/// Получение типа коллекции
/// </summary>
CollectionType GetCollectionType { get; }
/// <summary>
/// Получение объектов коллекции по одному
/// </summary>
/// <returns>Поэлементый вывод элементов коллекции</returns>
IEnumerable<T?> GetItems();
/// <summary>
/// Сортировка коллекции
/// </summary>
/// <param name="comparer"></param>
void CollectionSort(IComparer<T?> comparer);
}
}

View File

@ -0,0 +1,67 @@
using ProjectLiner.Drawnings;
using ProjectLiner.Exceptions;
using ProjectLiner.CollectionGenericObjects;
using ProjectLiner.Exceptions;
namespace ProjectLiner.CollectionGenericObjects
{
public class LinerSharingService : AbstractCompany
{
public LinerSharingService(int picWidth, int picHeight, ICollectionGenericObjects<DrawningCommonLiner> collection) : base(picWidth, picHeight, collection)
{
}
protected override void DrawBackgound(Graphics g)
{
Pen pen = new(Color.Black, 4);
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 - 40, j * _placeSizeHeight);
}
g.DrawLine(pen, i * _placeSizeWidth, 0, i * _placeSizeWidth, _pictureHeight / _placeSizeHeight * _placeSizeHeight);
}
}
protected override void SetObjectsPosition()
{
int width = _pictureWidth / _placeSizeWidth;
int height = _pictureHeight / _placeSizeHeight;
int curWidth = width - 1;
int curHeight = 0;
for (int i = 0; i < (_collection?.Count ?? 0); i++)
{
try
{
if (_collection.Get(i) != null)
{
_collection.Get(i).SetPictureSize(_pictureWidth, _pictureHeight);
_collection.Get(i).SetPosition(_placeSizeWidth * curWidth + 10, curHeight * _placeSizeHeight + 5);
}
if (curWidth > 0)
curWidth--;
else
{
curWidth = width - 1;
curHeight++;
}
if (curHeight > height)
{
return;
}
}
catch (ObjectNotFoundException)
{
break;
}
}
}
}
}

View File

@ -0,0 +1,113 @@

using ProjectLiner.Exceptions;
using ProjectLiner.CollectionGenericObjects;
using ProjectLiner.Exceptions;
namespace ProjectLiner.CollectionGenericObjects
{
/// <summary>
/// Параметризованный набор объектов
/// </summary>
/// <typeparam name="T">Параметр: ограничение - ссылочный тип</typeparam>
public class ListGenericObjects<T> : ICollectionGenericObjects<T>
where T : class
{
/// <summary>
/// Список объектов, которые храним
/// </summary>
private readonly List<T?> _collection;
/// <summary>
/// Максимально допустимое число объектов в списке
/// </summary>
private int _maxCount;
public int Count => _collection.Count;
public int MaxCount
{
get
{
return _maxCount;
}
set
{
if (value > 0)
{
_maxCount = value;
}
}
}
public CollectionType GetCollectionType => CollectionType.List;
/// <summary>
/// Конструктор
/// </summary>
public ListGenericObjects()
{
_collection = new();
}
public T? Get(int position)
{
if (position >= Count || position < 0)
throw new PositionOutOfCollectionException(position);
return _collection[position];
}
public int Insert(T obj, IEqualityComparer<T?>? comparer = null)
{
if (Count == _maxCount) throw new CollectionOverflowException();
if (comparer != null)
{
if (_collection.Contains(obj, comparer))
{
throw new ObjectAlreadyExistsException(obj);
}
}
_collection.Add(obj);
return Count;
}
public int Insert(T obj, int position, IEqualityComparer<T?>? comparer = null)
{
if (Count == _maxCount) throw new CollectionOverflowException();
if (position >= Count || position < 0) throw new PositionOutOfCollectionException();
if (comparer != null)
{
if (_collection.Contains(obj, comparer))
{
throw new ObjectAlreadyExistsException(obj);
}
}
_collection.Insert(position, obj);
return position;
}
public T? Remove(int position)
{
if (position < 0 || position > Count)
throw new PositionOutOfCollectionException(position);
T? temp = _collection[position];
_collection.RemoveAt(position);
return temp;
}
public IEnumerable<T?> GetItems()
{
for (int i = 0; i < _collection.Count; ++i)
{
yield return _collection[i];
}
}
public void CollectionSort(IComparer<T?> comparer)
{
_collection.Sort(comparer);
}
}
}

View File

@ -0,0 +1,155 @@

using ProjectLiner.Exceptions;
using ProjectLiner.CollectionGenericObjects;
using ProjectLiner.Exceptions;
namespace ProjectLiner.CollectionGenericObjects
{
/// <summary>
/// Параметризованный набор объектов
/// </summary>
/// <typeparam name="T">Параметр: ограничение - ссылочный тип</typeparam>
public class MassiveGenericObjects<T> : ICollectionGenericObjects<T>
where T : class
{
/// <summary>
/// Массив объектов, которые храним
/// </summary>
private T?[] _collection;
public int Count => _collection.Length;
public int MaxCount
{
get
{
return _collection.Length;
}
set
{
if (value > 0)
{
if (_collection.Length > 0)
{
Array.Resize(ref _collection, value);
}
else
{
_collection = new T?[value];
}
}
}
}
public CollectionType GetCollectionType => CollectionType.Massive;
/// <summary>
/// Конструктор
/// </summary>
public MassiveGenericObjects()
{
_collection = Array.Empty<T?>();
}
public T? Get(int position)
{
if (position < 0 || position >= Count)
throw new PositionOutOfCollectionException(position);
if (_collection[position] == null)
throw new ObjectNotFoundException(position);
return _collection[position];
}
public int Insert(T obj, IEqualityComparer<T?>? comparer = null)
{
if (comparer != null)
{
foreach (T? i in _collection)
{
if (comparer.Equals(i, obj))
{
throw new ObjectAlreadyExistsException(1);
}
}
}
for (int i = 0; i < Count; i++)
{
if (_collection[i] == null)
{
_collection[i] = obj;
return i;
}
}
throw new CollectionOverflowException();
}
public int Insert(T obj, int position, IEqualityComparer<T?>? comparer = null)
{
if (position >= Count || position < 0) throw new PositionOutOfCollectionException();
if (comparer != null)
{
foreach (T? i in _collection)
{
if (comparer.Equals(i, obj))
{
throw new ObjectAlreadyExistsException(position);
}
}
}
if (_collection[position] == null)
{
_collection[position] = obj;
return position;
}
int temp = position + 1;
while (temp < Count)
{
if (_collection[temp] == null)
{
_collection[temp] = obj;
return temp;
}
++temp;
}
temp = position - 1;
while (temp >= 0)
{
if (_collection[temp] == null)
{
_collection[temp] = obj;
return temp;
}
--temp;
}
throw new CollectionOverflowException();
}
public T? Remove(int position)
{
if (position < 0 || position >= Count)
throw new PositionOutOfCollectionException(position);
if (_collection[position] == null)
throw new ObjectNotFoundException(position);
T? temp = _collection[position];
_collection[position] = null;
return temp;
}
public IEnumerable<T?> GetItems()
{
for (int i = 0; i < _collection.Length; ++i)
{
yield return _collection[i];
}
}
public void CollectionSort(IComparer<T?> comparer)
{
Array.Sort(_collection, comparer);
}
}
}

View File

@ -0,0 +1,223 @@

using ProjectLiner.CollectionGenericObjects;
using ProjectLiner.Drawnings;
using ProjectLiner.Exceptions;
using System.Data;
using System.Text;
using System.Xml.Linq;
namespace ProjectLiner.CollectionGenericObjects;
/// <summary>
/// Класс-хранилище коллекций
/// </summary>
/// <typeparam name="T"></typeparam>
public class StorageCollection<T>
where T : DrawningCommonLiner
{
/// <summary>
/// Словарь (хранилище) с коллекциями
/// </summary>
readonly Dictionary<CollectionInfo, ICollectionGenericObjects<T>> _storages;
/// <summary>
/// Ключевое слово, с которого должен начинаться файл
/// </summary>
private readonly string _collectionKey = "CollectionsStorage";
/// <summary>
/// Разделитель для записей коллекции данных в файл
/// </summary>
private readonly string _separatorItems = ";";
/// <summary>
/// Разделитель для записи ключа и значения элемента словаря
/// </summary>
private readonly string _separatorForKeyValue = "|";
/// <summary>
/// Возвращение списка названий коллекций
/// </summary>
public List<CollectionInfo> Keys => _storages.Keys.ToList();
/// <summary>
/// Конструктор
/// </summary>
public StorageCollection()
{
_storages = new Dictionary<CollectionInfo, ICollectionGenericObjects<T>>();
}
/// <summary>
/// Добавление коллекции в хранилище
/// </summary>
/// <param name="name">Название коллекции</param>
/// <param name="collectionType">тип коллекции</param>
public void AddCollection(string name, CollectionType collectionType)
{
CollectionInfo collectionInfo = new(name, collectionType, string.Empty);
if (name == null || _storages.ContainsKey(collectionInfo))
return;
switch (collectionType)
{
case CollectionType.None:
return;
case CollectionType.Massive:
_storages[collectionInfo] = new MassiveGenericObjects<T>();
return;
case CollectionType.List:
_storages[collectionInfo] = new ListGenericObjects<T>();
return;
default: break;
}
}
/// <summary>
/// Удаление коллекции
/// </summary>
/// <param name="name">Название коллекции</param>
public void DelCollection(string name)
{
CollectionInfo collectionInfo = new(name, CollectionType.None, string.Empty);
if (_storages.ContainsKey(collectionInfo))
_storages.Remove(collectionInfo);
}
/// <summary>
/// Доступ к коллекции
/// </summary>
/// <param name="name">Название коллекции</param>
/// <returns></returns>
public ICollectionGenericObjects<T>? this[string name]
{
get
{
CollectionInfo collectionInfo = new(name, CollectionType.None, string.Empty);
if (_storages.ContainsKey(collectionInfo))
return _storages[collectionInfo];
return null;
}
}
/// <summary>
/// Сохранение информации по автомобилям в хранилище в файл
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public void SaveData(string filename)
{
if (_storages.Count == 0)
{
throw new InvalidDataException("В хранилище отсутствуют коллекции для сохранения");
}
if (File.Exists(filename))
{
File.Delete(filename);
}
using (StreamWriter writer = new(filename))
{
writer.Write(_collectionKey);
foreach (KeyValuePair<CollectionInfo, ICollectionGenericObjects<T>> value in _storages)
{
writer.Write(Environment.NewLine);
// не сохраняем пустые коллекции
if (value.Value.Count == 0)
{
continue;
}
writer.Write(value.Key);
writer.Write(_separatorForKeyValue);
writer.Write(value.Value.MaxCount);
writer.Write(_separatorForKeyValue);
foreach (T? item in value.Value.GetItems())
{
string data = item?.GetDataForSave() ?? string.Empty;
if (string.IsNullOrEmpty(data))
{
continue;
}
writer.Write(data);
writer.Write(_separatorItems);
}
}
}
}
/// <summary>
/// Загрузка информации по автомобилям в хранилище из файла
/// </summary>
/// <param name="filename">>Путь и имя файла</param>
/// <returns>true - загрузка прошла успешно, false - ошибка при загрузке данных</returns>
public void LoadData(string filename)
{
if (!File.Exists(filename))
{
throw new FileNotFoundException($"{filename} не существует");
}
using (StreamReader reader = new(filename))
{
string line = reader.ReadLine();
if (line == null || line.Length == 0)
{
throw new FileFormatException("Файл не подходит");
}
if (!line.Equals(_collectionKey))
{
throw new IOException("В файле неверные данные");
}
_storages.Clear();
while ((line = reader.ReadLine()) != null)
{
string[] record = line.Split(_separatorForKeyValue, StringSplitOptions.RemoveEmptyEntries);
if (record.Length != 3)
{
continue;
}
CollectionInfo? collectionInfo = CollectionInfo.GetCollectionInfo(record[0]) ?? throw new Exception("Не удалось определить информацию коллекции" + record[0]);
ICollectionGenericObjects<T>? collection = StorageCollection<T>.CreateCollection(collectionInfo.CollectionType);
if (collection == null)
{
throw new InvalidOperationException("Не удалось создать коллекцию");
}
collection.MaxCount = Convert.ToInt32(record[1]);
string[] set = record[2].Split(_separatorItems, StringSplitOptions.RemoveEmptyEntries);
foreach (string elem in set)
{
if (elem?.CreateDrawningCommonLiner() is T truck)
{
try
{
if (collection.Insert(truck) == -1)
{
throw new ConstraintException("Объект не удалось добавить в коллекцию: " + record[3]);
}
}
catch (CollectionOverflowException ex)
{
throw new DataException("Коллекция переполнена", ex);
}
}
}
_storages.Add(collectionInfo, collection);
}
}
}
/// <summary>
/// Создание коллекции по типу
/// </summary>
/// <param name="collectionType"></param>
/// <returns></returns>
private static ICollectionGenericObjects<T>? CreateCollection(CollectionType collectionType)
{
return collectionType switch
{
CollectionType.Massive => new MassiveGenericObjects<T>(),
CollectionType.List => new ListGenericObjects<T>(),
_ => null,
};
}
}

View File

@ -0,0 +1,13 @@
using ProjectLiner.Drawnings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLiner;
/// <summary>
/// Делегат передачи объекта класса-прорисовки
/// </summary>
/// <param name="liner"></param>
public delegate void CommonLinerDelegate(DrawningCommonLiner liner);

View File

@ -0,0 +1,32 @@
namespace ProjectLiner.Drawnings;
/// <summary>
/// Направление перемещения
/// </summary>
public enum DirectionType
{
/// <summary>
/// Неизвестное направление
/// </summary>
Unknow = -1,
/// <summary>
/// Вверх
/// </summary>
Up = 1,
/// <summary>
/// Вниз
/// </summary>
Down = 2,
/// <summary>
/// Влево
/// </summary>
Left = 3,
/// <summary>
/// Вправо
/// </summary>
Right = 4
}

View File

@ -0,0 +1,255 @@
using ProjectLiner.Entities;
namespace ProjectLiner.Drawnings;
/// <summary>
/// Класс, отвечающий за прорисовку и перемещение обычного объекта-сущности
/// </summary>
public class DrawningCommonLiner
{
/// <summary>
/// Класс-сущность
/// </summary>
public EntityCommonLiner? EntityCommonLiner { get; protected set; }
/// <summary>
/// Ширина окна
/// </summary>
private int? _pictureWidth;
/// <summary>
/// Высота окна
/// </summary>
private int? _pictureHeight;
/// <summary>
/// Левая координата прорисовки лайнера
/// </summary>
protected int? _startPosX;
/// <summary>
/// Верхняя кооридната прорисовки лайнера
/// </summary>
protected int? _startPosY;
/// <summary>
/// Ширина прорисовки лайнера
/// </summary>
private readonly int _drawningLinerWidth = 155;
/// <summary>
/// Высота прорисовки лайнера
/// </summary>
private readonly int _drawningLinerHeight = 90;
/// <summary>
/// Координата X объекта
/// </summary>
public int? GetPosX => _startPosX;
/// <summary>
/// Координата Y объекта
/// </summary>
public int? GetPosY => _startPosY;
/// <summary>
/// Ширина объекта
/// </summary>
public int GetWidth => _drawningLinerWidth;
/// <summary>
/// Высота объекта
/// </summary>
public int GetHeight => _drawningLinerHeight;
/// <summary>
/// Пустой конструктор
/// </summary>
public DrawningCommonLiner()
{
_pictureWidth = null;
_pictureHeight = null;
_startPosX = null;
_startPosY = null;
}
/// <summary>
/// конструктор
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodyColor">Основной цвет</param>
public DrawningCommonLiner(int speed, double weight, Color bodycolor) : this()
{
EntityCommonLiner = new EntityCommonLiner(speed, weight, bodycolor);
}
/// <summary>
/// конструктор для наследников
/// </summary>
/// <param name="drawningLinerHeight">Высота</param>
/// <param name="drawningLinerWight">Длина</param>
protected DrawningCommonLiner(int drawningLinerWight, int drawningLinerHeight) : this()
{
_drawningLinerHeight = drawningLinerHeight;
_drawningLinerWidth = drawningLinerWight;
}
/// <summary>
/// Конструктор для метода создания объекта из строки (ExtentionDrawningCommonLiner)
/// </summary>
/// <param name="CommonLiner"></param>
public DrawningCommonLiner(EntityCommonLiner? CommonLiner) : this()
{
EntityCommonLiner = CommonLiner;
}
/// <summary>
/// Установка границ поля
/// </summary>
/// <param name="width">Ширина поля</param>
/// <param name="height">Высота поля</param>
/// <returns>true - границы заданы, false - проверка не пройдена, нельзя разместить объект в этих размерах</returns>
public bool SetPictureSize(int width, int height)
{
if (width > _drawningLinerWidth && height > _drawningLinerHeight)
{
_pictureWidth = width;
_pictureHeight = height;
if (_startPosX != null && _startPosY != null)
{
if (_startPosX.Value < 0)
_startPosX = 0;
if (_startPosY.Value < 0)
_startPosY = 0;
if (_startPosX.Value + _drawningLinerWidth > _pictureWidth)
{
_startPosX = _pictureWidth - _drawningLinerWidth;
}
if (_startPosY.Value + _drawningLinerHeight > _pictureHeight)
{
_startPosY = _pictureHeight - _drawningLinerHeight;
}
}
return true;
}
return false;
}
/// <summary>
/// Установка позиции
/// </summary>
/// <param name="x">Координата X</param>
/// <param name="y">Координата Y</param>
public void SetPosition(int x, int y)
{
if (!_pictureHeight.HasValue || !_pictureWidth.HasValue)
{
return;
}
else
{
_startPosX = x;
_startPosY = y;
if (_startPosX.Value < 0)
_startPosX = 0;
if (_startPosY.Value < 0)
_startPosY = 0;
if (_startPosX.Value + _drawningLinerWidth > _pictureWidth)
{
_startPosX = _pictureWidth - _drawningLinerWidth;
}
if (_startPosY.Value + _drawningLinerHeight > _pictureHeight)
{
_startPosY = _pictureHeight - _drawningLinerHeight;
}
}
}
/// <summary>
/// Изменение направления перемещения
/// </summary>
/// <param name="direction">Направление</param>
/// <returns>true - перемещене выполнено, false - перемещение невозможно</returns>
public bool MoveTransport(DirectionType direction)
{
if (EntityCommonLiner == null || !_startPosX.HasValue || !_startPosY.HasValue)
{
return false;
}
switch (direction)
{
//влево
case DirectionType.Left:
if (_startPosX.Value - EntityCommonLiner.Step > 0)
{
_startPosX -= (int)EntityCommonLiner.Step;
}
return true;
//вверх
case DirectionType.Up:
if (_startPosY.Value - EntityCommonLiner.Step > 0)
{
_startPosY -= (int)EntityCommonLiner.Step;
}
return true;
// вправо
case DirectionType.Right:
if (_startPosX.Value + EntityCommonLiner.Step < _pictureWidth - _drawningLinerWidth)
{
_startPosX += (int)EntityCommonLiner.Step;
}
return true;
//вниз
case DirectionType.Down:
if (_startPosY.Value + EntityCommonLiner.Step < _pictureHeight - _drawningLinerHeight)
{
_startPosY += (int)EntityCommonLiner.Step;
}
return true;
default:
return false;
}
}
/// <summary>
/// Прорисовка объекта
/// </summary>
/// <param name="g"></param>
public virtual void DrawTransport(Graphics g)
{
if (EntityCommonLiner == null || !_startPosX.HasValue || !_startPosY.HasValue)
{
return;
}
Pen pen = new(Color.Black);
Brush br = new SolidBrush(EntityCommonLiner.BodyColor);
// кузов лайнера
Point point1 = new Point(_startPosX.Value, _startPosY.Value + 40);
Point point2 = new Point(_startPosX.Value + 50, _startPosY.Value + 90);
Point point3 = new Point(_startPosX.Value + 135, _startPosY.Value + 90);
Point point4 = new Point(_startPosX.Value + 155, _startPosY.Value + 40);
Point[] curvePoints = { point1, point2, point3, point4 };
g.FillPolygon(br, curvePoints);
// борт лайнера
Point point5 = new Point(_startPosX.Value + 40, _startPosY.Value);
Point point6 = new Point(_startPosX.Value + 140, _startPosY.Value);
Point point7 = new Point(_startPosX.Value + 140, _startPosY.Value + 40);
Point point8 = new Point(_startPosX.Value + 40, _startPosY.Value + 40);
Point[] curvePoints2 = { point5, point6, point7, point8 };
g.FillPolygon(br, curvePoints2);
}
}

View File

@ -0,0 +1,82 @@
using ProjectLiner.Entities;
namespace ProjectLiner.Drawnings;
/// <summary>
/// Класс, отвечающий за прорисовку и перемещение объекта-сущности
/// </summary>
public class DrawningLiner : DrawningCommonLiner
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodycolor">Основной цвет</param>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="anchor">Признак наличия якоря</param>
/// <param name="boats">Признак наличия шлюпок</param>
/// <param name="pipe">Признак наличия трубы</param>
public DrawningLiner(int speed, double weight, Color bodycolor, Color additionalColor, bool anchor, bool boats, bool pipe) : base(150, 125)
{
EntityCommonLiner = new EntityLiner(speed, weight, bodycolor, additionalColor, anchor, boats, pipe);
}
/// <summary>
/// Конструктор для метода создания объекта из строки (ExtentionDrawningAirplane)
/// </summary>
/// <param name="airplane"></param>
public DrawningLiner(EntityCommonLiner? liner) : base(liner)
{
if (liner != null)
EntityCommonLiner = liner;
}
public override void DrawTransport(Graphics g)
{
if (EntityCommonLiner == null || EntityCommonLiner is not EntityLiner liner || !_startPosX.HasValue || !_startPosY.HasValue)
{
return;
}
Pen pen = new(Color.Black);
Brush additionalBrush = new SolidBrush(liner.AdditionalColor);
Brush br = new SolidBrush(liner.BodyColor);
_startPosY += 40;
base.DrawTransport(g);
_startPosY -= 40;
// якорь
if (liner.Anchor)
{
g.DrawLine(pen, _startPosX.Value + 45, _startPosY.Value + 85, _startPosX.Value + 45, _startPosY.Value + 115);
g.DrawLine(pen, _startPosX.Value + 30, _startPosY.Value + 95, _startPosX.Value + 60, _startPosY.Value + 95);
g.DrawLine(pen, _startPosX.Value + 25, _startPosY.Value + 100, _startPosX.Value + 45, _startPosY.Value + 115);
g.DrawLine(pen, _startPosX.Value + 45, _startPosY.Value + 115, _startPosX.Value + 65, _startPosY.Value + 100);
}
// шлюпки
if (liner.Boats)
{
g.FillEllipse(additionalBrush, _startPosX.Value + 40, _startPosY.Value + 85, 30, 15);
g.FillEllipse(additionalBrush, _startPosX.Value + 75, _startPosY.Value + 85, 30, 15);
g.FillEllipse(additionalBrush, _startPosX.Value + 110, _startPosY.Value + 85, 30, 15);
}
// труба
if (liner.Pipe)
{
Point point9 = new Point(_startPosX.Value + 90, _startPosY.Value + 10);
Point point10 = new Point(_startPosX.Value + 90, _startPosY.Value + 40);
Point point11 = new Point(_startPosX.Value + 115, _startPosY.Value + 40);
Point point12 = new Point(_startPosX.Value + 115, _startPosY.Value + 10);
Point[] curvePoints3 = { point9, point10, point11, point12 };
g.FillPolygon(additionalBrush, curvePoints3);
}
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLiner.Drawnings;
/// <summary>
/// Сравнение по цвету, скорости, весу
/// </summary>
public class DrawningLinerCompareByColor : IComparer<DrawningCommonLiner?>
{
public int Compare(DrawningCommonLiner? x, DrawningCommonLiner? y)
{
if (x == null || x.EntityCommonLiner == null)
{
return 1;
}
if (y == null || y.EntityCommonLiner == null)
{
return -1;
}
var bodycolorCompare = x.EntityCommonLiner.BodyColor.Name.CompareTo(y.EntityCommonLiner.BodyColor.Name);
if (bodycolorCompare != 0)
{
return bodycolorCompare;
}
var speedCompare = x.EntityCommonLiner.Speed.CompareTo(y.EntityCommonLiner.Speed);
if (speedCompare != 0)
{
return speedCompare;
}
return x.EntityCommonLiner.Weight.CompareTo(y.EntityCommonLiner.Weight);
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLiner.Drawnings;
/// <summary>
/// Сравнение по типу, скорости, весу
/// </summary>
public class DrawningLinerCompareByType : IComparer<DrawningCommonLiner?>
{
public int Compare(DrawningCommonLiner? x, DrawningCommonLiner? y)
{
if (x == null && y == null) return 0;
if (x == null || x.EntityCommonLiner == null)
{
return 1;
}
if (y == null || y.EntityCommonLiner == null)
{
return -1;
}
if (x.GetType().Name != y.GetType().Name)
{
return x.GetType().Name.CompareTo(y.GetType().Name);
}
var speedCompare = x.EntityCommonLiner.Speed.CompareTo(y.EntityCommonLiner.Speed);
if (speedCompare != 0)
{
return speedCompare;
}
return x.EntityCommonLiner.Weight.CompareTo(y.EntityCommonLiner.Weight);
}
}

View File

@ -0,0 +1,71 @@
using ProjectLiner.Drawnings;
using ProjectLiner.Entities;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// Реализация сравнения двух объектов класса-прорисовки
/// </summary>
public class DrawningLinerEqutables : IEqualityComparer<DrawningCommonLiner?>
{
public bool Equals(DrawningCommonLiner x, DrawningCommonLiner? y)
{
if (x == null || x.EntityCommonLiner == null)
{
return false;
}
if (y == null || y.EntityCommonLiner == null)
{
return false;
}
if (x.GetType().Name != y.GetType().Name)
{
return false;
}
if (x.EntityCommonLiner.Speed != y.EntityCommonLiner.Speed)
{
return false;
}
if (x.EntityCommonLiner.Weight != y.EntityCommonLiner.Weight)
{
return false;
}
if (x.EntityCommonLiner.BodyColor != y.EntityCommonLiner.BodyColor)
{
return false;
}
if (x is DrawningLiner && y is DrawningLiner)
{
if (((EntityLiner)x.EntityCommonLiner).AdditionalColor !=
((EntityLiner)y.EntityCommonLiner).AdditionalColor)
{
return false;
}
if (((EntityLiner)x.EntityCommonLiner).Boats !=
((EntityLiner)y.EntityCommonLiner).Boats)
{
return false;
}
if (((EntityLiner)x.EntityCommonLiner).Anchor !=
((EntityLiner)y.EntityCommonLiner).Anchor)
{
return false;
}
if (((EntityLiner)x.EntityCommonLiner).Pipe !=
((EntityLiner)y.EntityCommonLiner).Pipe)
{
return false;
}
}
return true;
}
public int GetHashCode([DisallowNull] DrawningCommonLiner obj)
{
return obj.GetHashCode();
}
}

View File

@ -0,0 +1,53 @@
using ProjectLiner.Entities;
namespace ProjectLiner.Drawnings;
public static class ExtentionDrawningLiner
{
/// <summary>
/// Разделитель для записи информации по объекту в файл
/// </summary>
private static readonly string _separatorForObject = ":";
/// <summary>
/// Создание объекта из строки
/// </summary>
/// <param name="info">Строка с данными для создания объекта</param>
/// <returns>Объект</returns>
public static DrawningCommonLiner? CreateDrawningCommonLiner(this string info)
{
string[] strs = info.Split(_separatorForObject);
EntityCommonLiner? CommonLiner = EntityLiner.CreateEntityLiner(strs);
if (CommonLiner != null)
{
return new DrawningLiner(CommonLiner);
}
CommonLiner = EntityCommonLiner.CreateEntityCommonLiner(strs);
if (CommonLiner != null)
{
return new DrawningCommonLiner(CommonLiner);
}
return null;
}
/// <summary>
/// Получение данных для сохранения в файл
/// </summary>
/// <param name="drawningCommonLiner">Сохраняемый объект</param>
/// <returns>Строка с данными по объекту</returns>
public static string GetDataForSave(this DrawningCommonLiner drawningCommonLiner)
{
string[]? array = drawningCommonLiner?.EntityCommonLiner?.GetStringRepresentation();
if (array == null)
{
return string.Empty;
}
return string.Join(_separatorForObject, array);
}
}

View File

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// Класс-сущность обычного "Лайнера"
/// </summary>
namespace ProjectLiner.Entities
{
public class EntityCommonLiner
{
/// <summary>
/// Скорость
/// </summary>
public int Speed { get; private set; }
/// <summary>
/// Вес
/// </summary>
public double Weight { get; private set; }
/// <summary>
/// Основной цвет
/// </summary>
public Color BodyColor { get; private set; }
/// <summary>
/// Шаг перемещения автомобиля
/// </summary>
public double Step => Speed * 100 / Weight;
/// <summary>
/// Конструктор лайнера
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес автомобиля</param>
/// <param name="bodyColor">Основной цвет</param>
public EntityCommonLiner(int speed, double weight, Color bodyColor)
{
Speed = speed;
Weight = weight;
BodyColor = bodyColor;
}
/// <summary>
/// Метод передачи основного цвета
/// </summary>
/// <param name="bodyColor"></param>
public void SetBodyColor(Color bodyColor)
{
BodyColor = bodyColor;
}
/// <summary>
/// Получение строк со значениями свойств объекта класса-сущности
/// </summary>
/// <returns></returns>
public virtual string[] GetStringRepresentation()
{
return new[] { nameof(EntityCommonLiner), Speed.ToString(), Weight.ToString(), BodyColor.Name };
}
/// <summary>
/// Создание объекта из массива строк
/// </summary>
/// <param name="strs"></param>
/// <returns></returns>
public static EntityCommonLiner? CreateEntityCommonLiner(string[] strs)
{
if (strs.Length != 4 || strs[0] != nameof(EntityCommonLiner))
return null;
return new EntityCommonLiner(Convert.ToInt32(strs[1]), Convert.ToDouble(strs[2]), Color.FromName(strs[3]));
}
}
}

View File

@ -0,0 +1,80 @@
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace ProjectLiner.Entities;
/// <summary>
/// Класс-сущность "Лайнер"
/// </summary>
public class EntityLiner: EntityCommonLiner
{
/// <summary>
/// Дополнительный цвет (для опциональных элементов)
/// </summary>
public Color AdditionalColor { get; private set; }
/// <summary>
/// Признак (опция) наличия якоря
/// </summary>
public bool Anchor { get; private set; }
/// <summary>
/// Признак (опция) наличия шлюпок
/// </summary>
public bool Boats { get; private set; }
/// <summary>
/// Признак (опция) наличия трубы
/// </summary>
public bool Pipe { get; private set; }
/// <summary>
/// Инициализация полей объекта-класса спортивного автомобиля
/// </summary>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="anchor">Признак наличия якоря</param>
/// <param name="boats">Признак наличия шлюпок</param>
/// <param name="pipe">Признак наличия трубы</param>
public EntityLiner(int speed, double weight, Color bodyColor, Color additionalColor, bool anchor, bool boats, bool pipe) : base(speed, weight, bodyColor)
{
new EntityCommonLiner(speed, weight, bodyColor);
AdditionalColor = additionalColor;
Anchor = anchor;
Boats = boats;
Pipe = pipe;
}
/// <summary>
/// Метод передачи дополнительного цвета
/// </summary>
/// <param name="additionalColor"></param>
public void SetAdditionalColor(Color additionalColor)
{
AdditionalColor = additionalColor;
}
/// <summary>
/// Переопределение метода создания объекта из массива строк
/// </summary>
/// <returns></returns>
public override string[] GetStringRepresentation()
{
return new[] { nameof(EntityLiner), Speed.ToString(), Weight.ToString(), BodyColor.Name, AdditionalColor.Name, Anchor.ToString(), Boats.ToString(), Pipe.ToString() };
}
/// <summary>
/// Создание объекта из массива строк
/// </summary>
/// <param name="strs"></param>
/// <returns></returns>
public static EntityLiner? CreateEntityLiner(string[] strs)
{
if (strs.Length != 8 || strs[0] != nameof(EntityLiner))
return null;
return new EntityLiner(Convert.ToInt32(strs[1]), Convert.ToDouble(strs[2]),
Color.FromName(strs[3]), Color.FromName(strs[4]),
Convert.ToBoolean(strs[5]), Convert.ToBoolean(strs[6]), Convert.ToBoolean(strs[7]));
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLiner.Exceptions;
/// <summary>
/// Класс, описывающий ошибку переполнения коллекции
/// </summary>
public class CollectionOverflowException : ApplicationException
{
public CollectionOverflowException(int count) : base("В коллекции превышено допустимое колличество: " + count) { }
public CollectionOverflowException() : base() { }
public CollectionOverflowException(string message) : base(message) { }
public CollectionOverflowException(string message, Exception exception) : base(message, exception) { }
protected CollectionOverflowException(SerializationInfo info, StreamingContext contex) : base(info, contex) { }
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLiner.Exceptions;
/// <summary>
/// Класс, описывающий ошибку, что в коллекции уже есть такой элемент
/// </summary>
[Serializable]
public class ObjectAlreadyExistsException : ApplicationException
{
public ObjectAlreadyExistsException(object i) : base("В коллекции уже есть такой элемент " + i) { }
public ObjectAlreadyExistsException() : base() { }
public ObjectAlreadyExistsException(string message) : base(message) { }
public ObjectAlreadyExistsException(string message, Exception exception) : base(message, exception)
{ }
protected ObjectAlreadyExistsException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLiner.Exceptions;
/// <summary>
/// Класс, описывающий ошибку, что по указанной позиции нет элемента
/// </summary>
public class ObjectNotFoundException : ApplicationException
{
public ObjectNotFoundException(int i) : base("Не найден объект по позиции " + i) { }
public ObjectNotFoundException() : base() { }
public ObjectNotFoundException(string message) : base(message) { }
public ObjectNotFoundException(string message, Exception exception) : base(message, exception)
{ }
protected ObjectNotFoundException(SerializationInfo info, StreamingContext contex) : base(info, contex) { }
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLiner.Exceptions;
/// <summary>
/// Класс, описывающий ошибку выхода за границы коллекции
/// </summary>
[Serializable]
public class PositionOutOfCollectionException: ApplicationException
{
public PositionOutOfCollectionException(int i) : base("Выход за границы коллекции.Позиция " + i) { }
public PositionOutOfCollectionException() : base() { }
public PositionOutOfCollectionException(string message) : base(message) { }
public PositionOutOfCollectionException(string message, Exception exception) : base(message, exception) { }
protected PositionOutOfCollectionException(SerializationInfo info, StreamingContext contex) : base(info, contex) { }
}

View File

@ -1,39 +0,0 @@
namespace ProjectLiner
{
partial class Form1
{
/// <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()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -1,10 +0,0 @@
namespace ProjectLiner
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,155 @@
namespace ProjectLiner
{
partial class FormLiner
{
/// <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()
{
pictureBoxLiner = new PictureBox();
buttonDown = new Button();
buttonUp = new Button();
buttonLeft = new Button();
buttonRight = new Button();
comboBoxStrategy = new ComboBox();
buttonStrategyStep = new Button();
((System.ComponentModel.ISupportInitialize)pictureBoxLiner).BeginInit();
SuspendLayout();
//
// pictureBoxLiner
//
pictureBoxLiner.BackColor = SystemColors.Control;
pictureBoxLiner.Dock = DockStyle.Fill;
pictureBoxLiner.Location = new Point(0, 0);
pictureBoxLiner.Margin = new Padding(5);
pictureBoxLiner.Name = "pictureBoxLiner";
pictureBoxLiner.Size = new Size(1465, 1007);
pictureBoxLiner.TabIndex = 0;
pictureBoxLiner.TabStop = false;
//
// buttonDown
//
buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonDown.BackgroundImage = Properties.Resources.bottom;
buttonDown.BackgroundImageLayout = ImageLayout.Stretch;
buttonDown.Location = new Point(1283, 905);
buttonDown.Margin = new Padding(5);
buttonDown.Name = "buttonDown";
buttonDown.Size = new Size(77, 82);
buttonDown.TabIndex = 2;
buttonDown.UseVisualStyleBackColor = true;
buttonDown.Click += ButtonMove_Click;
//
// buttonUp
//
buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonUp.BackgroundImage = Properties.Resources.top;
buttonUp.BackgroundImageLayout = ImageLayout.Stretch;
buttonUp.Location = new Point(1283, 813);
buttonUp.Margin = new Padding(5);
buttonUp.Name = "buttonUp";
buttonUp.Size = new Size(77, 82);
buttonUp.TabIndex = 3;
buttonUp.UseVisualStyleBackColor = true;
buttonUp.Click += ButtonMove_Click;
//
// buttonLeft
//
buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonLeft.BackgroundImage = Properties.Resources.left;
buttonLeft.BackgroundImageLayout = ImageLayout.Stretch;
buttonLeft.Location = new Point(1196, 905);
buttonLeft.Margin = new Padding(5);
buttonLeft.Name = "buttonLeft";
buttonLeft.Size = new Size(77, 82);
buttonLeft.TabIndex = 4;
buttonLeft.UseVisualStyleBackColor = true;
buttonLeft.Click += ButtonMove_Click;
//
// buttonRight
//
buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonRight.BackgroundImage = Properties.Resources.right;
buttonRight.BackgroundImageLayout = ImageLayout.Stretch;
buttonRight.Location = new Point(1369, 905);
buttonRight.Margin = new Padding(5);
buttonRight.Name = "buttonRight";
buttonRight.Size = new Size(77, 82);
buttonRight.TabIndex = 5;
buttonRight.UseVisualStyleBackColor = true;
buttonRight.Click += ButtonMove_Click;
//
// comboBoxStrategy
//
comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxStrategy.FormattingEnabled = true;
comboBoxStrategy.Items.AddRange(new object[] { "К центру", "К краю" });
comboBoxStrategy.Location = new Point(1147, 20);
comboBoxStrategy.Margin = new Padding(5);
comboBoxStrategy.Name = "comboBoxStrategy";
comboBoxStrategy.Size = new Size(298, 49);
comboBoxStrategy.TabIndex = 11;
//
// buttonStrategyStep
//
buttonStrategyStep.Location = new Point(1261, 84);
buttonStrategyStep.Margin = new Padding(5);
buttonStrategyStep.Name = "buttonStrategyStep";
buttonStrategyStep.Size = new Size(185, 61);
buttonStrategyStep.TabIndex = 12;
buttonStrategyStep.Text = "Шаг";
buttonStrategyStep.UseVisualStyleBackColor = true;
buttonStrategyStep.Click += buttonStrategyStep_Click;
//
// FormLiner
//
AutoScaleDimensions = new SizeF(17F, 41F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1465, 1007);
Controls.Add(buttonStrategyStep);
Controls.Add(comboBoxStrategy);
Controls.Add(buttonRight);
Controls.Add(buttonLeft);
Controls.Add(buttonUp);
Controls.Add(buttonDown);
Controls.Add(pictureBoxLiner);
Margin = new Padding(5);
Name = "FormLiner";
Text = "Лайнер";
((System.ComponentModel.ISupportInitialize)pictureBoxLiner).EndInit();
ResumeLayout(false);
}
#endregion
private PictureBox pictureBoxLiner;
private Button buttonDown;
private Button buttonUp;
private Button buttonLeft;
private Button buttonRight;
private ComboBox comboBoxStrategy;
private Button buttonStrategyStep;
}
}

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 ProjectLiner.Drawnings;
using ProjectLiner.MovementStrategy;
namespace ProjectLiner
{
public partial class FormLiner : Form
{
private DrawningCommonLiner? _drawningCommonLiner;
private AbstractStrategy? _strategy;
public FormLiner()
{
InitializeComponent();
_strategy = null;
}
/// <summary>
/// Стратегия перемещения
/// </summary>
public DrawningCommonLiner SetLiner
{
set
{
_drawningCommonLiner = value;
_drawningCommonLiner.SetPictureSize(pictureBoxLiner.Width, pictureBoxLiner.Height);
comboBoxStrategy.Enabled = true;
_strategy = null;
Draw();
}
}
/// <summary>
/// Метод прорисовки лайнера
/// </summary>
private void Draw()
{
if (_drawningCommonLiner == null)
{
return;
}
Bitmap bmp = new(pictureBoxLiner.Width, pictureBoxLiner.Height);
Graphics gr = Graphics.FromImage(bmp);
_drawningCommonLiner.DrawTransport(gr);
pictureBoxLiner.Image = bmp;
}
/// <summary>
/// Перемещение объекта по форме (нажатие кнопок навигации)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonMove_Click(object sender, EventArgs e)
{
if (_drawningCommonLiner == null)
{
return;
}
string name = ((Button)sender)?.Name ?? string.Empty;
bool result = false;
switch (name)
{
case "buttonUp":
result = _drawningCommonLiner.MoveTransport(DirectionType.Up);
break;
case "buttonDown":
result = _drawningCommonLiner.MoveTransport(DirectionType.Down);
break;
case "buttonLeft":
result = _drawningCommonLiner.MoveTransport(DirectionType.Left);
break;
case "buttonRight":
result = _drawningCommonLiner.MoveTransport(DirectionType.Right);
break;
}
if (result)
{
Draw();
}
}
/// <summary>
/// Обработка нажатия кнопки "Шаг"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonStrategyStep_Click(object sender, EventArgs e)
{
if (_drawningCommonLiner == null)
{
return;
}
if (comboBoxStrategy.Enabled)
{
_strategy = comboBoxStrategy.SelectedIndex switch
{
0 => new MoveToCenter(),
1 => new MoveToBorder(),
_ => null,
};
if (_strategy == null)
{
return;
}
_strategy.SetData(new MoveableLiner(_drawningCommonLiner), pictureBoxLiner.Width, pictureBoxLiner.Height);
}
if (_strategy == null)
{
return;
}
comboBoxStrategy.Enabled = false;
_strategy.MakeStep();
Draw();
if (_strategy.GetStatus() == StrategyStatus.Finish)
{
comboBoxStrategy.Enabled = true;
_strategy = null;
}
}
}
}

View File

@ -1,17 +1,17 @@
<?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
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>
@ -26,36 +26,36 @@
<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
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
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
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
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
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
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
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->

View File

@ -0,0 +1,392 @@
namespace ProjectLiner
{
partial class FormLinerCollection
{
/// <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()
{
groupBoxTools = new GroupBox();
buttonCreateCompany = new Button();
panelStorage = new Panel();
buttonCollectionDel = new Button();
listBoxCollection = new ListBox();
buttonCollectionAdd = new Button();
radioButtonList = new RadioButton();
radioButtonMassive = new RadioButton();
textBoxCollectionName = new TextBox();
labelCollectionName = new Label();
comboBoxSelectorCompany = new ComboBox();
pictureBox = new PictureBox();
panelCompanyTools = new Panel();
buttonAddLiner = new Button();
maskedTextBox1 = new MaskedTextBox();
button5 = new Button();
button3 = new Button();
button4 = 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();
groupBoxTools.SuspendLayout();
panelStorage.SuspendLayout();
((System.ComponentModel.ISupportInitialize)pictureBox).BeginInit();
panelCompanyTools.SuspendLayout();
menuStrip.SuspendLayout();
SuspendLayout();
//
// groupBoxTools
//
groupBoxTools.Controls.Add(buttonCreateCompany);
groupBoxTools.Controls.Add(panelStorage);
groupBoxTools.Controls.Add(comboBoxSelectorCompany);
groupBoxTools.Dock = DockStyle.Right;
groupBoxTools.Location = new Point(1052, 49);
groupBoxTools.Name = "groupBoxTools";
groupBoxTools.Size = new Size(272, 1140);
groupBoxTools.TabIndex = 0;
groupBoxTools.TabStop = false;
groupBoxTools.Text = "Инструменты";
//
// buttonCreateCompany
//
buttonCreateCompany.Font = new Font("Segoe UI", 9.75F, FontStyle.Regular, GraphicsUnit.Point);
buttonCreateCompany.Location = new Point(7, 495);
buttonCreateCompany.Margin = new Padding(5);
buttonCreateCompany.Name = "buttonCreateCompany";
buttonCreateCompany.Size = new Size(257, 38);
buttonCreateCompany.TabIndex = 8;
buttonCreateCompany.Text = "Создать компанию";
buttonCreateCompany.UseVisualStyleBackColor = true;
buttonCreateCompany.Click += ButtonCreateCompany_Click;
//
// panelStorage
//
panelStorage.Controls.Add(buttonCollectionDel);
panelStorage.Controls.Add(listBoxCollection);
panelStorage.Controls.Add(buttonCollectionAdd);
panelStorage.Controls.Add(radioButtonList);
panelStorage.Controls.Add(radioButtonMassive);
panelStorage.Controls.Add(textBoxCollectionName);
panelStorage.Controls.Add(labelCollectionName);
panelStorage.Dock = DockStyle.Top;
panelStorage.Location = new Point(3, 43);
panelStorage.Name = "panelStorage";
panelStorage.Size = new Size(266, 370);
panelStorage.TabIndex = 7;
//
// buttonCollectionDel
//
buttonCollectionDel.Font = new Font("Segoe UI", 9.75F, FontStyle.Regular, GraphicsUnit.Point);
buttonCollectionDel.Location = new Point(3, 314);
buttonCollectionDel.Margin = new Padding(5);
buttonCollectionDel.Name = "buttonCollectionDel";
buttonCollectionDel.Size = new Size(257, 38);
buttonCollectionDel.TabIndex = 6;
buttonCollectionDel.Text = "Удалить Коллекцию";
buttonCollectionDel.UseVisualStyleBackColor = true;
buttonCollectionDel.Click += ButtonCollectionDel_Click;
//
// listBoxCollection
//
listBoxCollection.Font = new Font("Segoe UI", 9.75F, FontStyle.Regular, GraphicsUnit.Point);
listBoxCollection.FormattingEnabled = true;
listBoxCollection.ItemHeight = 30;
listBoxCollection.Location = new Point(5, 180);
listBoxCollection.Margin = new Padding(5);
listBoxCollection.Name = "listBoxCollection";
listBoxCollection.Size = new Size(254, 124);
listBoxCollection.TabIndex = 5;
//
// buttonCollectionAdd
//
buttonCollectionAdd.Font = new Font("Segoe UI", 7.948052F, FontStyle.Regular, GraphicsUnit.Point);
buttonCollectionAdd.Location = new Point(3, 134);
buttonCollectionAdd.Name = "buttonCollectionAdd";
buttonCollectionAdd.Size = new Size(263, 38);
buttonCollectionAdd.TabIndex = 4;
buttonCollectionAdd.Text = "Добавить коллекцию";
buttonCollectionAdd.UseVisualStyleBackColor = true;
buttonCollectionAdd.Click += ButtonCollectionAdd_Click;
//
// radioButtonList
//
radioButtonList.AutoSize = true;
radioButtonList.Font = new Font("Segoe UI", 9.818182F, FontStyle.Regular, GraphicsUnit.Point);
radioButtonList.Location = new Point(138, 95);
radioButtonList.Name = "radioButtonList";
radioButtonList.Size = new Size(107, 34);
radioButtonList.TabIndex = 3;
radioButtonList.TabStop = true;
radioButtonList.Text = "Список";
radioButtonList.UseVisualStyleBackColor = true;
//
// radioButtonMassive
//
radioButtonMassive.AutoSize = true;
radioButtonMassive.Font = new Font("Segoe UI", 9.818182F, FontStyle.Regular, GraphicsUnit.Point);
radioButtonMassive.Location = new Point(3, 95);
radioButtonMassive.Name = "radioButtonMassive";
radioButtonMassive.Size = new Size(107, 34);
radioButtonMassive.TabIndex = 2;
radioButtonMassive.TabStop = true;
radioButtonMassive.Text = "массив";
radioButtonMassive.UseVisualStyleBackColor = true;
//
// textBoxCollectionName
//
textBoxCollectionName.Location = new Point(0, 43);
textBoxCollectionName.Name = "textBoxCollectionName";
textBoxCollectionName.Size = new Size(264, 47);
textBoxCollectionName.TabIndex = 1;
//
// labelCollectionName
//
labelCollectionName.AutoSize = true;
labelCollectionName.Font = new Font("Segoe UI", 9.818182F, FontStyle.Regular, GraphicsUnit.Point);
labelCollectionName.Location = new Point(22, 8);
labelCollectionName.Name = "labelCollectionName";
labelCollectionName.Size = new Size(213, 30);
labelCollectionName.TabIndex = 0;
labelCollectionName.Text = "Название коллекции";
//
// comboBoxSelectorCompany
//
comboBoxSelectorCompany.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
comboBoxSelectorCompany.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxSelectorCompany.FormattingEnabled = true;
comboBoxSelectorCompany.Items.AddRange(new object[] { "Хранилище" });
comboBoxSelectorCompany.Location = new Point(23, 419);
comboBoxSelectorCompany.Name = "comboBoxSelectorCompany";
comboBoxSelectorCompany.Size = new Size(242, 49);
comboBoxSelectorCompany.TabIndex = 0;
comboBoxSelectorCompany.SelectedIndexChanged += ComboBoxSelectorCompany_SelectedIndexChanged;
//
// pictureBox
//
pictureBox.Dock = DockStyle.Bottom;
pictureBox.Enabled = false;
pictureBox.Location = new Point(0, 177);
pictureBox.Name = "pictureBox";
pictureBox.Size = new Size(1052, 1012);
pictureBox.TabIndex = 1;
pictureBox.TabStop = false;
//
// panelCompanyTools
//
panelCompanyTools.BackColor = SystemColors.Window;
panelCompanyTools.Controls.Add(buttonSortByColor);
panelCompanyTools.Controls.Add(buttonSortByType);
panelCompanyTools.Controls.Add(buttonAddLiner);
panelCompanyTools.Controls.Add(maskedTextBox1);
panelCompanyTools.Controls.Add(button5);
panelCompanyTools.Controls.Add(button3);
panelCompanyTools.Controls.Add(button4);
panelCompanyTools.Location = new Point(1052, 592);
panelCompanyTools.Margin = new Padding(5);
panelCompanyTools.Name = "panelCompanyTools";
panelCompanyTools.Size = new Size(272, 589);
panelCompanyTools.TabIndex = 9;
//
// buttonAddLiner
//
buttonAddLiner.Location = new Point(6, 54);
buttonAddLiner.Name = "buttonAddLiner";
buttonAddLiner.Size = new Size(242, 75);
buttonAddLiner.TabIndex = 7;
buttonAddLiner.Text = "Добавить";
buttonAddLiner.UseVisualStyleBackColor = true;
buttonAddLiner.Click += ButtonAddCommonLiner_Click;
//
// maskedTextBox1
//
maskedTextBox1.Location = new Point(3, 167);
maskedTextBox1.Mask = "00";
maskedTextBox1.Name = "maskedTextBox1";
maskedTextBox1.Size = new Size(245, 47);
maskedTextBox1.TabIndex = 3;
maskedTextBox1.ValidatingType = typeof(int);
//
// button5
//
button5.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
button5.Location = new Point(3, 384);
button5.Name = "button5";
button5.Size = new Size(245, 75);
button5.TabIndex = 6;
button5.Text = "Обновить";
button5.UseVisualStyleBackColor = true;
button5.Click += ButtonRefresh_Click;
//
// button3
//
button3.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
button3.Location = new Point(3, 220);
button3.Name = "button3";
button3.Size = new Size(245, 75);
button3.TabIndex = 4;
button3.Text = "Удаление Лайнера";
button3.UseVisualStyleBackColor = true;
button3.Click += ButtonRemoveCommonLiner_Click;
//
// button4
//
button4.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
button4.Location = new Point(3, 302);
button4.Name = "button4";
button4.Size = new Size(245, 75);
button4.TabIndex = 5;
button4.Text = "Передать на тесты";
button4.UseVisualStyleBackColor = true;
button4.Click += ButtonGoToCheck_Click;
//
// menuStrip
//
menuStrip.ImageScalingSize = new Size(26, 26);
menuStrip.Items.AddRange(new ToolStripItem[] { файлToolStripMenuItem });
menuStrip.Location = new Point(0, 0);
menuStrip.Name = "menuStrip";
menuStrip.Size = new Size(1324, 49);
menuStrip.TabIndex = 10;
menuStrip.Text = "menuStrip1";
//
// файлToolStripMenuItem
//
файлToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { saveToolStripMenuItem, loadToolStripMenuItem });
файлToolStripMenuItem.Name = айлToolStripMenuItem";
файлToolStripMenuItem.Size = new Size(104, 45);
файлToolStripMenuItem.Text = "Файл";
//
// saveToolStripMenuItem
//
saveToolStripMenuItem.Name = "saveToolStripMenuItem";
saveToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.S;
saveToolStripMenuItem.Size = new Size(399, 50);
saveToolStripMenuItem.Text = "Сохранение";
saveToolStripMenuItem.Click += saveToolStripMenuItem_Click;
//
// loadToolStripMenuItem
//
loadToolStripMenuItem.Name = "loadToolStripMenuItem";
loadToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.L;
loadToolStripMenuItem.Size = new Size(399, 50);
loadToolStripMenuItem.Text = "Загрузка";
loadToolStripMenuItem.Click += loadToolStripMenuItem_Click;
//
// openFileDialog
//
openFileDialog.FileName = "openFileDialog1";
openFileDialog.Filter = "txt file | *.txt";
//
// saveFileDialog
//
saveFileDialog.Filter = "txt file | *.txt";
//
// buttonSortByColor
//
buttonSortByColor.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonSortByColor.Font = new Font("Segoe UI", 9.818182F, FontStyle.Regular, GraphicsUnit.Point);
buttonSortByColor.Location = new Point(3, 526);
buttonSortByColor.Name = "buttonSortByColor";
buttonSortByColor.Size = new Size(245, 44);
buttonSortByColor.TabIndex = 9;
buttonSortByColor.Text = "Сортировка по цвету";
buttonSortByColor.UseVisualStyleBackColor = true;
buttonSortByColor.Click += buttonSortByColor_Click;
//
// buttonSortByType
//
buttonSortByType.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonSortByType.Font = new Font("Segoe UI", 9.818182F, FontStyle.Regular, GraphicsUnit.Point);
buttonSortByType.Location = new Point(4, 476);
buttonSortByType.Name = "buttonSortByType";
buttonSortByType.Size = new Size(244, 44);
buttonSortByType.TabIndex = 8;
buttonSortByType.Text = "Сортировка по типу";
buttonSortByType.UseVisualStyleBackColor = true;
buttonSortByType.Click += buttonSortByType_Click;
//
// FormLinerCollection
//
AutoScaleDimensions = new SizeF(17F, 41F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1324, 1189);
Controls.Add(panelCompanyTools);
Controls.Add(pictureBox);
Controls.Add(groupBoxTools);
Controls.Add(menuStrip);
MainMenuStrip = menuStrip;
Name = "FormLinerCollection";
Text = "Коллекция автомобилей";
groupBoxTools.ResumeLayout(false);
panelStorage.ResumeLayout(false);
panelStorage.PerformLayout();
((System.ComponentModel.ISupportInitialize)pictureBox).EndInit();
panelCompanyTools.ResumeLayout(false);
panelCompanyTools.PerformLayout();
menuStrip.ResumeLayout(false);
menuStrip.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private GroupBox groupBoxTools;
private ComboBox comboBoxSelectorCompany;
private PictureBox pictureBox;
private Button buttonGoToCheck;
private Button buttonRemoveLiner;
private MaskedTextBox maskedTextBoxPosition;
private Button buttonRefresh;
private Panel panelStorage;
private Label labelCollectionName;
private RadioButton radioButtonMassive;
private TextBox textBoxCollectionName;
private Button buttonCollectionAdd;
private RadioButton radioButtonList;
private Button buttonCollectionDel;
private ListBox listBoxCollection;
private Button buttonCreateCompany;
private Panel panelCompanyTools;
private MaskedTextBox maskedTextBox1;
private Button button5;
private Button button3;
private Button button4;
private Button buttonAddLiner;
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,361 @@
using Microsoft.Extensions.Logging;
using ProjectLiner.CollectionGenericObjects;
using ProjectLiner.Drawnings;
using ProjectLiner.Exceptions;
using ProjectLiner.CollectionGenericObjects;
using ProjectLiner.Exceptions;
using System.Windows.Forms;
namespace ProjectLiner
{
/// <summary>
/// Форма работы с компанией и ее коллекцией
/// </summary>
public partial class FormLinerCollection : Form
{
/// <summary>
/// Хранилише коллекций
/// </summary>
private readonly StorageCollection<DrawningCommonLiner> _storageCollection;
/// <summary>
/// Компания
/// </summary>
private AbstractCompany? _company = null;
/// <summary>
/// Логер
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Конструктор
/// </summary>
public FormLinerCollection(ILogger<FormLinerCollection> logger)
{
InitializeComponent();
_storageCollection = new();
_logger = logger;
_logger.LogInformation("Форма загрузилась");
}
/// <summary>
/// Выбор компании
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ComboBoxSelectorCompany_SelectedIndexChanged(object sender, EventArgs e)
{
panelCompanyTools.Enabled = false;
}
/// <summary>
/// Добавление самолета
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonAddCommonLiner_Click(object sender, EventArgs e)
{
FormLinerConfig form = new();
form.Show();
form.AddEvent(SetLiner);
}
/// <summary>
/// Добавление самолета в коллекцию
/// </summary>
/// <param name="CommonLiner"></param>
private void SetLiner(DrawningCommonLiner CommonLiner)
{
try
{
if (_company == null || CommonLiner == null)
{
return;
}
if (_company + CommonLiner != -1)
{
MessageBox.Show("Объект добавлен");
pictureBox.Image = _company.Show();
_logger.LogInformation("Добавлен объект: {0}", CommonLiner.GetDataForSave());
}
}
catch (CollectionOverflowException ex)
{
MessageBox.Show(ex.Message);
_logger.LogError("Ошибка: {Message}", ex.Message);
}
catch (ObjectAlreadyExistsException ex)
{
MessageBox.Show("Такой объект есть в коллекции");
_logger.LogWarning($"Добавление существующего объекта: {ex.Message}");
}
}
/// <summary>
/// Удаление объекта
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonRemoveCommonLiner_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(maskedTextBox1.Text) || _company == null)
{
return;
}
if (MessageBox.Show("Удалить объект?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
try
{
int pos = Convert.ToInt32(maskedTextBox1.Text);
if (_company - pos != null)
{
MessageBox.Show("Объект удален");
pictureBox.Image = _company.Show();
_logger.LogInformation("Удалён объект по позиции {0}", pos);
}
}
catch (PositionOutOfCollectionException ex)
{
MessageBox.Show(ex.Message);
_logger.LogError("Ошибка: {Message}", ex.Message);
}
catch (ObjectNotFoundException ex)
{
MessageBox.Show(ex.Message);
_logger.LogError("Ошибка: {Message}", ex.Message);
}
}
/// <summary>
/// Передача объекта в другую форму
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonGoToCheck_Click(object sender, EventArgs e)
{
if (_company == null)
{
return;
}
try
{
DrawningCommonLiner? plane = null;
int counter = 100;
while (plane == null)
{
plane = _company.GetRandomObject();
counter--;
if (counter <= 0)
{
break;
}
}
if (plane == null)
{
return;
}
FormLiner form = new()
{
SetLiner = plane
};
form.ShowDialog();
}
catch (ObjectNotFoundException)
{
_logger.LogError("Ошибка при передаче объекта на FormLiner");
}
}
/// <summary>
/// Перерисовка коллекции
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonRefresh_Click(object sender, EventArgs e)
{
if (_company == null)
{
return;
}
pictureBox.Image = _company.Show();
}
/// <summary>
/// Добавление коллекции
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCollectionAdd_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxCollectionName.Text) || (!radioButtonList.Checked && !radioButtonMassive.Checked))
{
MessageBox.Show("Не все данные заполнены", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
_logger.LogError("Ошибка: Заполнены не все данные для добавления коллекции");
return;
}
CollectionType collectionType = CollectionType.None;
if (radioButtonMassive.Checked)
collectionType = CollectionType.Massive;
else if (radioButtonList.Checked)
collectionType = CollectionType.List;
_storageCollection.AddCollection(textBoxCollectionName.Text, collectionType);
RefreshListBoxItems();
_logger.LogInformation("Добавлена коллекция: {Collection} типа: {Type}", textBoxCollectionName.Text, collectionType);
}
/// <summary>
/// Удаление коллекции
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCollectionDel_Click(object sender, EventArgs e)
{
if (listBoxCollection.SelectedItems == null || listBoxCollection.SelectedIndex < 0)
{
MessageBox.Show("Коллекция не выбрана");
return;
}
if (MessageBox.Show("Удалить коллекцию?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
return;
}
_storageCollection.DelCollection(listBoxCollection.SelectedItem.ToString());
RefreshListBoxItems();
_logger.LogInformation("Коллекция удалена: {0}", textBoxCollectionName.Text);
}
/// <summary>
/// Обновление списка в listBoxCollection
/// </summary>
private void RefreshListBoxItems()
{
listBoxCollection.Items.Clear();
for (int i = 0; i < _storageCollection.Keys?.Count; ++i)
{
string? colName = _storageCollection.Keys?[i].Name;
if (!string.IsNullOrEmpty(colName))
listBoxCollection.Items.Add(colName);
}
}
/// <summary>
/// Создание компании
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCreateCompany_Click(object sender, EventArgs e)
{
if (listBoxCollection.SelectedIndex < 0 || listBoxCollection.SelectedItem == null)
{
MessageBox.Show("Коллекция не выбрана");
return;
}
ICollectionGenericObjects<DrawningCommonLiner>? collection = _storageCollection[listBoxCollection.SelectedItem.ToString() ?? string.Empty];
if (collection == null)
{
MessageBox.Show("Коллекция не проинициализирована");
return;
}
switch (comboBoxSelectorCompany.Text)
{
case "Хранилище":
_company = new LinerSharingService(pictureBox.Width, pictureBox.Height, collection);
_logger.LogInformation("Создна компания типа {Company}, коллекция: {Collection}", comboBoxSelectorCompany.Text, textBoxCollectionName.Text);
_logger.LogInformation("Создана компания на коллекции: {Collection}", textBoxCollectionName.Text);
break;
}
panelCompanyTools.Enabled = true;
RefreshListBoxItems();
}
/// <summary>
/// Обработка нажатия "Сохранение"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
_storageCollection.SaveData(saveFileDialog.FileName);
MessageBox.Show("Сохранение прошло успешно", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
_logger.LogInformation("Сохранение в файл: {filename}", saveFileDialog.FileName);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error);
_logger.LogError("Ошибка: {Message}", ex.Message);
}
}
}
/// <summary>
/// Обработка нажатия "Загрузка"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void loadToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
_storageCollection.LoadData(openFileDialog.FileName);
MessageBox.Show("Загрузка прошла успешно", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Information);
RefreshListBoxItems();
_logger.LogInformation("Загрузка из файла: {filename}", saveFileDialog.FileName);
}
catch (Exception ex)
{
MessageBox.Show($"Не загрузилось: {ex.Message}", "Результат", MessageBoxButtons.OK, MessageBoxIcon.Error);
_logger.LogError("Ошибка: {Message}", ex.Message);
}
}
}
/// <summary>
/// Сортировка по типу
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSortByType_Click(object sender, EventArgs e) => CompareTrucks(new DrawningLinerCompareByType());
/// <summary>
/// Сортировка по цвету
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonSortByColor_Click(object sender, EventArgs e) => CompareTrucks(new DrawningLinerCompareByColor());
/// <summary>
/// Сортировка по сравнителю
/// </summary>
private void CompareTrucks(IComparer<DrawningCommonLiner?> comparer)
{
if (_company == null)
{
return;
}
_company.Sort(comparer);
pictureBox.Image = _company.Show();
}
}
}

View File

@ -0,0 +1,132 @@
<?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>17, 17</value>
</metadata>
<metadata name="openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>228, 17</value>
</metadata>
<metadata name="saveFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>519, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>25</value>
</metadata>
</root>

View File

@ -0,0 +1,382 @@
namespace ProjectLiner
{
partial class FormLinerConfig
{
/// <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()
{
Label labelSimpleObject;
Label labelModifiedObject;
Label labelBodyColor;
Label labelAdditionslColor;
groupBoxConfig = new GroupBox();
groupBoxColors = new GroupBox();
panelDarkOliveGreen = new Panel();
panelAqua = new Panel();
panelSeaGreen = new Panel();
panelPaleGreen = new Panel();
panelCrimson = new Panel();
panelMediumBlue = new Panel();
panelDeepPink = new Panel();
panelBlueViolet = new Panel();
checkBoxPipe = new CheckBox();
checkBoxBoats = new CheckBox();
checkBoxAnchor = new CheckBox();
numericUpDownWeight = new NumericUpDown();
labelWeight = new Label();
numericUpDownSpeed = new NumericUpDown();
labelSpeed = new Label();
pictureBoxObject = new PictureBox();
buttonAdd = new Button();
buttonCancel = new Button();
panelObject = new Panel();
labelSimpleObject = new Label();
labelModifiedObject = new Label();
labelBodyColor = new Label();
labelAdditionslColor = new Label();
groupBoxConfig.SuspendLayout();
groupBoxColors.SuspendLayout();
((System.ComponentModel.ISupportInitialize)numericUpDownWeight).BeginInit();
((System.ComponentModel.ISupportInitialize)numericUpDownSpeed).BeginInit();
((System.ComponentModel.ISupportInitialize)pictureBoxObject).BeginInit();
panelObject.SuspendLayout();
SuspendLayout();
//
// labelSimpleObject
//
labelSimpleObject.BorderStyle = BorderStyle.FixedSingle;
labelSimpleObject.Location = new Point(537, 292);
labelSimpleObject.Name = "labelSimpleObject";
labelSimpleObject.Size = new Size(224, 93);
labelSimpleObject.TabIndex = 0;
labelSimpleObject.Text = "Простой";
labelSimpleObject.TextAlign = ContentAlignment.MiddleCenter;
labelSimpleObject.MouseDown += labelObject_MouseDown;
//
// labelModifiedObject
//
labelModifiedObject.BorderStyle = BorderStyle.FixedSingle;
labelModifiedObject.Location = new Point(779, 292);
labelModifiedObject.Name = "labelModifiedObject";
labelModifiedObject.Size = new Size(224, 93);
labelModifiedObject.TabIndex = 1;
labelModifiedObject.Text = "Продвинутый";
labelModifiedObject.TextAlign = ContentAlignment.MiddleCenter;
labelModifiedObject.MouseDown += labelObject_MouseDown;
//
// labelBodyColor
//
labelBodyColor.AllowDrop = true;
labelBodyColor.BorderStyle = BorderStyle.FixedSingle;
labelBodyColor.Font = new Font("Segoe UI", 9.818182F, FontStyle.Regular, GraphicsUnit.Point);
labelBodyColor.Location = new Point(20, 14);
labelBodyColor.Name = "labelBodyColor";
labelBodyColor.Size = new Size(120, 56);
labelBodyColor.TabIndex = 10;
labelBodyColor.Text = "Цвет";
labelBodyColor.TextAlign = ContentAlignment.MiddleCenter;
labelBodyColor.DragDrop += labelBodyColor_DragDrop;
labelBodyColor.DragEnter += labelBodyColor_DragEnter;
//
// labelAdditionslColor
//
labelAdditionslColor.AllowDrop = true;
labelAdditionslColor.BorderStyle = BorderStyle.FixedSingle;
labelAdditionslColor.Location = new Point(146, 14);
labelAdditionslColor.Name = "labelAdditionslColor";
labelAdditionslColor.Size = new Size(120, 56);
labelAdditionslColor.TabIndex = 11;
labelAdditionslColor.Text = "Доп. цвет";
labelAdditionslColor.TextAlign = ContentAlignment.MiddleCenter;
labelAdditionslColor.DragDrop += labelAdditionalColor_DragDrop;
labelAdditionslColor.DragEnter += labelAdditionalColor_DragEnter;
//
// groupBoxConfig
//
groupBoxConfig.Controls.Add(groupBoxColors);
groupBoxConfig.Controls.Add(checkBoxPipe);
groupBoxConfig.Controls.Add(checkBoxBoats);
groupBoxConfig.Controls.Add(checkBoxAnchor);
groupBoxConfig.Controls.Add(numericUpDownWeight);
groupBoxConfig.Controls.Add(labelWeight);
groupBoxConfig.Controls.Add(numericUpDownSpeed);
groupBoxConfig.Controls.Add(labelSpeed);
groupBoxConfig.Controls.Add(labelModifiedObject);
groupBoxConfig.Controls.Add(labelSimpleObject);
groupBoxConfig.Dock = DockStyle.Left;
groupBoxConfig.Location = new Point(0, 0);
groupBoxConfig.Name = "groupBoxConfig";
groupBoxConfig.Size = new Size(1079, 406);
groupBoxConfig.TabIndex = 0;
groupBoxConfig.TabStop = false;
groupBoxConfig.Text = "Параметры";
//
// groupBoxColors
//
groupBoxColors.Controls.Add(panelDarkOliveGreen);
groupBoxColors.Controls.Add(panelAqua);
groupBoxColors.Controls.Add(panelSeaGreen);
groupBoxColors.Controls.Add(panelPaleGreen);
groupBoxColors.Controls.Add(panelCrimson);
groupBoxColors.Controls.Add(panelMediumBlue);
groupBoxColors.Controls.Add(panelDeepPink);
groupBoxColors.Controls.Add(panelBlueViolet);
groupBoxColors.Location = new Point(537, 46);
groupBoxColors.Name = "groupBoxColors";
groupBoxColors.Size = new Size(466, 215);
groupBoxColors.TabIndex = 9;
groupBoxColors.TabStop = false;
groupBoxColors.Text = "Цвета";
//
// panelDarkOliveGreen
//
panelDarkOliveGreen.BackColor = Color.DarkOliveGreen;
panelDarkOliveGreen.BackgroundImageLayout = ImageLayout.None;
panelDarkOliveGreen.Location = new Point(287, 137);
panelDarkOliveGreen.Name = "panelDarkOliveGreen";
panelDarkOliveGreen.Size = new Size(56, 54);
panelDarkOliveGreen.TabIndex = 4;
panelDarkOliveGreen.MouseDown += Panel_MouseDown;
//
// panelAqua
//
panelAqua.BackColor = Color.Aqua;
panelAqua.Location = new Point(125, 137);
panelAqua.Name = "panelAqua";
panelAqua.Size = new Size(56, 54);
panelAqua.TabIndex = 6;
panelAqua.MouseDown += Panel_MouseDown;
//
// panelSeaGreen
//
panelSeaGreen.BackColor = Color.SeaGreen;
panelSeaGreen.Location = new Point(207, 137);
panelSeaGreen.Name = "panelSeaGreen";
panelSeaGreen.Size = new Size(56, 54);
panelSeaGreen.TabIndex = 5;
panelSeaGreen.MouseDown += Panel_MouseDown;
//
// panelPaleGreen
//
panelPaleGreen.BackColor = Color.PaleGreen;
panelPaleGreen.Location = new Point(38, 137);
panelPaleGreen.Name = "panelPaleGreen";
panelPaleGreen.Size = new Size(56, 54);
panelPaleGreen.TabIndex = 3;
panelPaleGreen.MouseDown += Panel_MouseDown;
//
// panelCrimson
//
panelCrimson.BackColor = Color.Crimson;
panelCrimson.Location = new Point(287, 62);
panelCrimson.Name = "panelCrimson";
panelCrimson.Size = new Size(56, 54);
panelCrimson.TabIndex = 1;
panelCrimson.MouseDown += Panel_MouseDown;
//
// panelMediumBlue
//
panelMediumBlue.BackColor = Color.MediumBlue;
panelMediumBlue.Location = new Point(125, 62);
panelMediumBlue.Name = "panelMediumBlue";
panelMediumBlue.Size = new Size(56, 54);
panelMediumBlue.TabIndex = 2;
panelMediumBlue.MouseDown += Panel_MouseDown;
//
// panelDeepPink
//
panelDeepPink.BackColor = Color.DeepPink;
panelDeepPink.Location = new Point(207, 62);
panelDeepPink.Name = "panelDeepPink";
panelDeepPink.Size = new Size(56, 54);
panelDeepPink.TabIndex = 1;
panelDeepPink.MouseDown += Panel_MouseDown;
//
// panelBlueViolet
//
panelBlueViolet.BackColor = Color.BlueViolet;
panelBlueViolet.Location = new Point(38, 62);
panelBlueViolet.Name = "panelBlueViolet";
panelBlueViolet.Size = new Size(56, 54);
panelBlueViolet.TabIndex = 0;
panelBlueViolet.MouseDown += Panel_MouseDown;
//
// checkBoxPipe
//
checkBoxPipe.AutoSize = true;
checkBoxPipe.Location = new Point(35, 340);
checkBoxPipe.Name = "checkBoxPipe";
checkBoxPipe.Size = new Size(373, 45);
checkBoxPipe.TabIndex = 8;
checkBoxPipe.Text = "Признак наличия трубы";
checkBoxPipe.UseVisualStyleBackColor = true;
//
// checkBoxBoats
//
checkBoxBoats.AutoSize = true;
checkBoxBoats.Location = new Point(35, 256);
checkBoxBoats.Name = "checkBoxBoats";
checkBoxBoats.Size = new Size(404, 45);
checkBoxBoats.TabIndex = 7;
checkBoxBoats.Text = "Признак наличия шлюпок";
checkBoxBoats.UseVisualStyleBackColor = true;
//
// checkBoxAnchor
//
checkBoxAnchor.AutoSize = true;
checkBoxAnchor.Location = new Point(35, 183);
checkBoxAnchor.Name = "checkBoxAnchor";
checkBoxAnchor.Size = new Size(371, 45);
checkBoxAnchor.TabIndex = 6;
checkBoxAnchor.Text = "Признак наличия якоря";
checkBoxAnchor.UseVisualStyleBackColor = true;
//
// numericUpDownWeight
//
numericUpDownWeight.Location = new Point(195, 112);
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(192, 47);
numericUpDownWeight.TabIndex = 5;
numericUpDownWeight.Value = new decimal(new int[] { 100, 0, 0, 0 });
//
// labelWeight
//
labelWeight.AutoSize = true;
labelWeight.Location = new Point(35, 118);
labelWeight.Name = "labelWeight";
labelWeight.Size = new Size(72, 41);
labelWeight.TabIndex = 4;
labelWeight.Text = "Вес:";
//
// numericUpDownSpeed
//
numericUpDownSpeed.Location = new Point(195, 59);
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(192, 47);
numericUpDownSpeed.TabIndex = 3;
numericUpDownSpeed.Value = new decimal(new int[] { 100, 0, 0, 0 });
//
// labelSpeed
//
labelSpeed.AutoSize = true;
labelSpeed.Location = new Point(35, 59);
labelSpeed.Name = "labelSpeed";
labelSpeed.Size = new Size(154, 41);
labelSpeed.TabIndex = 2;
labelSpeed.Text = "Скорость:";
//
// pictureBoxObject
//
pictureBoxObject.Location = new Point(20, 96);
pictureBoxObject.Name = "pictureBoxObject";
pictureBoxObject.Size = new Size(246, 172);
pictureBoxObject.TabIndex = 1;
pictureBoxObject.TabStop = false;
//
// buttonAdd
//
buttonAdd.Font = new Font("Segoe UI", 8.883117F, FontStyle.Regular, GraphicsUnit.Point);
buttonAdd.Location = new Point(1105, 320);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(120, 53);
buttonAdd.TabIndex = 2;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// buttonCancel
//
buttonCancel.Font = new Font("Segoe UI", 8.883117F, FontStyle.Regular, GraphicsUnit.Point);
buttonCancel.Location = new Point(1256, 320);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(120, 53);
buttonCancel.TabIndex = 3;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
//
// panelObject
//
panelObject.AllowDrop = true;
panelObject.Controls.Add(labelAdditionslColor);
panelObject.Controls.Add(labelBodyColor);
panelObject.Controls.Add(pictureBoxObject);
panelObject.Location = new Point(1085, 12);
panelObject.Name = "panelObject";
panelObject.Size = new Size(291, 289);
panelObject.TabIndex = 4;
panelObject.DragDrop += PanelObject_DragDrop;
panelObject.DragEnter += PanelObject_DragEnter;
//
// FormLinerConfig
//
AutoScaleDimensions = new SizeF(17F, 41F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1388, 406);
Controls.Add(panelObject);
Controls.Add(buttonCancel);
Controls.Add(buttonAdd);
Controls.Add(groupBoxConfig);
Name = "FormLinerConfig";
Text = "Создание объекта";
groupBoxConfig.ResumeLayout(false);
groupBoxConfig.PerformLayout();
groupBoxColors.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)numericUpDownWeight).EndInit();
((System.ComponentModel.ISupportInitialize)numericUpDownSpeed).EndInit();
((System.ComponentModel.ISupportInitialize)pictureBoxObject).EndInit();
panelObject.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private GroupBox groupBoxConfig;
private NumericUpDown numericUpDownWeight;
private Label labelWeight;
private NumericUpDown numericUpDownSpeed;
private Label labelSpeed;
private CheckBox checkBoxPipe;
private CheckBox checkBoxBoats;
private CheckBox checkBoxAnchor;
private GroupBox groupBoxColors;
private Panel panelDarkOliveGreen;
private Panel panelAqua;
private Panel panelSeaGreen;
private Panel panelPaleGreen;
private Panel panelCrimson;
private Panel panelMediumBlue;
private Panel panelDeepPink;
private Panel panelBlueViolet;
private PictureBox pictureBoxObject;
private Button buttonAdd;
private Button buttonCancel;
private Panel panelObject;
}
}

View File

@ -0,0 +1,190 @@

using ProjectLiner.Drawnings;
using ProjectLiner.Entities;
using static System.Runtime.InteropServices.JavaScript.JSType;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrackBar;
namespace ProjectLiner;
/// <summary>
/// Форма конфигурации объекта
/// </summary>
public partial class FormLinerConfig : Form
{
/// <summary>
/// Объект - прорисовка самолета
/// </summary>
private DrawningCommonLiner? _commonLiner;
/// <summary>
/// Событие для передачи объекта
/// </summary>
private event Action<DrawningCommonLiner>? linerDelegate;
public FormLinerConfig()
{
InitializeComponent();
panelBlueViolet.MouseDown += Panel_MouseDown;
panelMediumBlue.MouseDown += Panel_MouseDown;
panelAqua.MouseDown += Panel_MouseDown;
panelCrimson.MouseDown += Panel_MouseDown;
panelDarkOliveGreen.MouseDown += Panel_MouseDown;
panelPaleGreen.MouseDown += Panel_MouseDown;
panelSeaGreen.MouseDown += Panel_MouseDown;
panelDeepPink.MouseDown += Panel_MouseDown;
buttonCancel.Click += (sender, e) => Close();
}
/// <summary>
/// Привязка внешнего метода к событию
/// </summary>
/// <param name="commonlinerDelegate"></param>
public void AddEvent(Action<DrawningCommonLiner> commonlinerDelegate)
{
linerDelegate += commonlinerDelegate;
}
/// <summary>
/// Прорисовка объекта
/// </summary>
private void DrawObject()
{
Bitmap bmp = new(pictureBoxObject.Width, pictureBoxObject.Height);
Graphics gr = Graphics.FromImage(bmp);
_commonLiner?.SetPictureSize(pictureBoxObject.Width, pictureBoxObject.Height);
_commonLiner?.SetPosition(5, 5);
_commonLiner?.DrawTransport(gr);
pictureBoxObject.Image = bmp;
}
/// <summary>
/// Передаем информацию при нажатии на Label
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void labelObject_MouseDown(object sender, MouseEventArgs e)
{
(sender as Label)?.DoDragDrop((sender as Label)?.Name ?? string.Empty, DragDropEffects.Move | DragDropEffects.Copy);
}
/// <summary>
/// Проверка получаемой информации (ее типа на соответствие требуемому)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PanelObject_DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.Data?.GetDataPresent(DataFormats.Text) ?? false ? DragDropEffects.Copy : DragDropEffects.None;
}
/// <summary>
/// Действия при приеме перетаскиваемой информации
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PanelObject_DragDrop(object sender, DragEventArgs e)
{
switch (e.Data?.GetData(DataFormats.Text)?.ToString())
{
case "labelSimpleObject":
_commonLiner = new DrawningCommonLiner((int)numericUpDownSpeed.Value, (double)numericUpDownWeight.Value, Color.White);
break;
case "labelModifiedObject":
_commonLiner = new DrawningLiner((int)numericUpDownSpeed.Value, (double)numericUpDownWeight.Value, Color.White,
Color.Black, checkBoxAnchor.Checked, checkBoxBoats.Checked, checkBoxPipe.Checked);
break;
}
DrawObject();
}
/// <summary>
/// Передаем информацию при нажатии на Panel
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Panel_MouseDown(object? sender, MouseEventArgs e)
{
(sender as Control)?.DoDragDrop((sender as Control)?.BackColor!, DragDropEffects.Move | DragDropEffects.Copy);
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
if (_commonLiner != null)
{
linerDelegate?.Invoke(_commonLiner);
Close();
}
}
/// <summary>
/// Передача основного цвета
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void labelBodyColor_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(Color)))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
/// <summary>
/// Прорисовка основным цветом
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void labelBodyColor_DragDrop(object sender, DragEventArgs e)
{
if (_commonLiner != null)
{
_commonLiner.EntityCommonLiner?.SetBodyColor((Color)e.Data.GetData(typeof(Color)));
DrawObject();
}
}
/// <summary>
/// Прорисовка дополнительным цветом
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void labelAdditionalColor_DragDrop(object sender, DragEventArgs e)
{
if (_commonLiner?.EntityCommonLiner is EntityLiner _liner)
{
_liner.SetAdditionalColor((Color)e.Data.GetData(typeof(Color)));
}
DrawObject();
}
/// <summary>
/// Передача дополнительного цвета
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void labelAdditionalColor_DragEnter(object sender, DragEventArgs e)
{
if (_commonLiner is DrawningLiner)
{
if (e.Data.GetDataPresent(typeof(Color)))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
}
}

View File

@ -0,0 +1,132 @@
<?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="labelSimpleObject.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="labelModifiedObject.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="labelBodyColor.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="labelAdditionslColor.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

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

View File

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

View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLiner.MovementStrategy;
/// <summary>
/// Стратегия перемещения объекта к правой нижней границы
/// </summary>
public class MoveToBorder : AbstractStrategy
{
protected override bool IsTargetDestination()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null)
{
return false;
}
return objParams.RightBorder <= FieldWidth && objParams.RightBorder + GetStep() >= FieldWidth &&
objParams.DownBorder <= FieldHeight && objParams.DownBorder + GetStep() >= FieldHeight;
}
protected override void MoveToTarget()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null)
{
return;
}
int diffX = objParams.RightBorder - FieldWidth;
if (Math.Abs(diffX) > GetStep())
{
if (diffX > 0)
{
MoveLeft();
}
else
{
MoveRight();
}
}
int diffY = objParams.DownBorder - FieldHeight;
if (Math.Abs(diffY) > GetStep())
{
if (diffY > 0)
{
MoveUp();
}
else
{
MoveDown();
}
}
}
}

View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLiner.MovementStrategy;
/// <summary>
/// Стратегия перемещения объекта в центр экрана
/// </summary>
public class MoveToCenter : AbstractStrategy
{
protected override bool IsTargetDestination()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null)
{
return false;
}
return objParams.ObjectMiddleHorizontal - GetStep() <= FieldWidth / 2 && objParams.ObjectMiddleHorizontal + GetStep() >= FieldWidth / 2 &&
objParams.ObjectMiddleVertical - GetStep() <= FieldHeight / 2 && objParams.ObjectMiddleVertical + GetStep() >= FieldHeight / 2;
}
protected override void MoveToTarget()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null)
{
return;
}
int diffX = objParams.ObjectMiddleHorizontal - FieldWidth / 2;
if (Math.Abs(diffX) > GetStep())
{
if (diffX > 0)
{
MoveLeft();
}
else
{
MoveRight();
}
}
int diffY = objParams.ObjectMiddleVertical - FieldHeight / 2;
if (Math.Abs(diffY) > GetStep())
{
if (diffY > 0)
{
MoveUp();
}
else
{
MoveDown();
}
}
}
}

View File

@ -0,0 +1,82 @@
using ProjectLiner.Drawnings;
using ProjectLiner.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectLiner.MovementStrategy;
/// <summary>
/// Класс-реализация IMoveableObject с использованием DrawningCommonLiner
/// </summary>
public class MoveableLiner : IMoveableObject
{
/// <summary>
/// Поле-объект класса DrawningCommonLiner или его наследника
/// </summary>
private readonly DrawningCommonLiner? _CommonLiner = null;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="CommonLiner">Объект класса DrawningCommonLiner</param>
public MoveableLiner(DrawningCommonLiner CommonLiner)
{
_CommonLiner = CommonLiner;
}
public ObjectParameters? GetObjectPosition
{
get
{
if (_CommonLiner == null || _CommonLiner.EntityCommonLiner == null || !_CommonLiner.GetPosX.HasValue || !_CommonLiner.GetPosY.HasValue)
{
return null;
}
return new ObjectParameters(_CommonLiner.GetPosX.Value, _CommonLiner.GetPosY.Value, _CommonLiner.GetWidth, _CommonLiner.GetHeight);
}
}
public int GetStep => (int)(_CommonLiner?.EntityCommonLiner?.Step ?? 0);
public int AnotherStep
{
set
{
AnotherStep = value;
}
}
public bool TryMoveObject(MovementDirection direction)
{
if (_CommonLiner == null || _CommonLiner.EntityCommonLiner == null)
{
return false;
}
return _CommonLiner.MoveTransport(GetDirectionType(direction));
}
/// <summary>
/// Конвертация из MovementDirection в DirectionType
/// </summary>
/// <param name="direction">MovementDirection</param>
/// <returns>DirectionType</returns>
private static DirectionType GetDirectionType(MovementDirection direction)
{
return direction switch
{
MovementDirection.Left => DirectionType.Left,
MovementDirection.Right => DirectionType.Right,
MovementDirection.Up => DirectionType.Up,
MovementDirection.Down => DirectionType.Down,
_ => DirectionType.Unknow,
};
}
public void MegaTurboStep(int value)
{
AnotherStep = value;
}
}

View File

@ -0,0 +1,30 @@
namespace ProjectLiner.MovementStrategy;
/// <summary>
/// Направление перемещения
/// </summary>
public enum MovementDirection
{
/// <summary>
/// Вверх
/// </summary>
Up = 1,
/// <summary>
/// Вниз
/// </summary>
Down = 2,
/// <summary>
/// Влево
/// </summary>
Left = 3,
/// <summary>
/// Вправо
/// </summary>
Right = 4
}

View File

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

View File

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

View File

@ -1,3 +1,8 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
namespace ProjectLiner
{
internal static class Program
@ -10,8 +15,36 @@ namespace ProjectLiner
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
ServiceCollection services = new();
ConfigureServices(services);
using ServiceProvider serviceProvider = services.BuildServiceProvider();
Application.Run(serviceProvider.GetRequiredService<FormLinerCollection>());
}
/// <summary>
/// Êîíôèãóðàöèÿ ñåðâèñà DI
/// </summary>
/// <param name="services"></param>
private static void ConfigureServices(ServiceCollection services)
{
string[] path = Directory.GetCurrentDirectory().Split('\\');
string pathNeed = "";
for (int i = 0; i < path.Length - 3; i++)
{
pathNeed += path[i] + "\\";
}
services.AddSingleton<FormLinerCollection>()
.AddLogging(option =>
{
option.SetMinimumLevel(LogLevel.Information);
option.AddSerilog(new LoggerConfiguration()
.ReadFrom.Configuration(new ConfigurationBuilder()
.AddJsonFile($"{pathNeed}serilog.json")
.Build())
.CreateLogger());
});
}
}
}

View File

@ -8,4 +8,34 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.8" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
<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>
<ItemGroup>
<None Update="serilog.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,103 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ProjectLiner.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("ProjectLiner.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;
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap bottom {
get {
object obj = ResourceManager.GetObject("bottom", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap left {
get {
object obj = ResourceManager.GetObject("left", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap right {
get {
object obj = ResourceManager.GetObject("right", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap top {
get {
object obj = ResourceManager.GetObject("top", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}

View File

@ -0,0 +1,133 @@
<?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.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="bottom" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\bottom.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="left" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\left.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="right" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\right.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="top" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\top.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,19 @@
{
"Serilog": {
"Using": [
"Serilog.Sinks.File"
],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "log.log"
}
}
],
"Properties": {
"Application": "Sample"
}
}
}