PIbd-21_Potapov_N.S._Catama.../Boats/Boats/MapWithSetBoatsGeneric.cs
2022-11-26 20:57:51 +04:00

269 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Boats
{
/// <summary>
/// Карта с набром объектов
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
internal class MapWithSetBoatsGeneric<T, U>
where T : class, IDrawingObject
where U : AbstractMap
{
/// <summary>
/// Ширина окна отрисовки
/// </summary>
private readonly int _pictureWidth;
/// <summary>
/// Высота окна отрисовки
/// </summary>
private readonly int _pictureHeight;
/// <summary>
/// Размер занимаемого объектом места (ширина)
/// </summary>
private readonly int _placeSizeWidth = 130;
/// <summary>
/// Размер занимаемого объектом места (высота)
/// </summary>
private readonly int _placeSizeHeight = 80;
/// <summary>
/// Набор объектов
/// </summary>
private readonly SetBoatsGeneric<T> _setBoats;
/// <summary>
/// Карта
/// </summary>
private readonly U _map;
/// <summary>
/// Массив точек установки лодок в гавани
/// </summary>
private Point[]? _placesPoints;
private readonly int _placesCount = 18;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="picWidth"></param>
/// <param name="picHeight"></param>
/// <param name="map"></param>
public MapWithSetBoatsGeneric(int picWidth, int picHeight, U map)
{
int width = picWidth / _placeSizeWidth;
int height = picHeight / _placeSizeHeight;
_setBoats = new SetBoatsGeneric<T>(_placesCount);
_pictureWidth = picWidth;
_pictureHeight = picHeight;
_map = map;
_placesPoints = null;
}
/// <summary>
/// Перегрузка оператора сложения
/// </summary>
/// <param name="map"></param>
/// <param name="boat"></param>
/// <returns>Возвращает позицию объекта в массиве или
/// -1, если установить объект не удплось</returns>
public static int operator +(MapWithSetBoatsGeneric<T, U> map, T boat)
{
return map._setBoats.Insert(boat);
}
/// <summary>
/// Перегрузка оператора вычитания
/// </summary>
/// <param name="map"></param>
/// <param name="position"></param>
/// <returns>Возвращает удаляемый объект или
/// null, если удалить не удалось</returns>
public static T operator -(MapWithSetBoatsGeneric<T, U> map, int position)
{
return map._setBoats.Remove(position);
}
/// <summary>
/// Вывод всего набора объектов
/// </summary>
/// <returns>Возвращает Bitmap с гаванью и лодками</returns>
public Bitmap ShowSet()
{
Bitmap bmp = new(_pictureWidth, _pictureHeight);
Graphics g = Graphics.FromImage(bmp);
DrawBackground(g);
DrawBoats(g);
return bmp;
}
/// <summary>
/// Просмотр объекта на карте
/// </summary>
/// <returns>Возвращает Bitmap с картой и объектом на ней</returns>
public Bitmap ShowOnMap()
{
Shaking();
foreach (var boat in _setBoats.GetBoats())
{
return _map.CreateMap(_pictureWidth, _pictureHeight, boat);
}
return new(_pictureWidth, _pictureHeight);
}
/// <summary>
/// Перемещение объекта по карте
/// </summary>
/// <param name="direction"></param>
/// <returns>Возвращает Bitmap с картой и перемещенным объектом на ней</returns>
public Bitmap MoveObject(Direction direction)
{
if (_map != null)
{
return _map.MoveObject(direction);
}
return new(_pictureWidth, _pictureHeight);
}
/// <summary>
/// "Взбалтываем" набор, чтобы все элементы оказались в начале
/// </summary>
private void Shaking()
{
int j = _setBoats.Count - 1;
for (int i = 0; i < _setBoats.Count; i++)
{
if (_setBoats[i] == null)
{
for (; j > i; j--)
{
var boat = _setBoats[j];
if (boat != null)
{
_setBoats.Insert(boat, i);
_setBoats.Remove(j);
break;
}
}
if (j <= i)
{
return;
}
}
}
}
/// <summary>
/// Метод отрисовки фона
/// </summary>
/// <param name="g"></param>
private void DrawBackground(Graphics g)
{
bool pointsInit = false;
// если массив точек null, то рисуем фон первый раз
// инициализируем массив для его заполнения
if (_placesPoints == null)
{
_placesPoints = new Point[_placesCount];
pointsInit = true;
}
// рисуем фон
g.FillRectangle(Brushes.Aqua, 0, 0, _pictureWidth * _placeSizeWidth,
_pictureHeight * _placeSizeHeight);
// рисуем основной пирс
g.FillRectangle(Brushes.Gray, 0, 0, _placeSizeWidth * 5 / 4, _placeSizeHeight * 3 / 2);
g.FillRectangle(Brushes.Gray, _pictureWidth - _placeSizeWidth * 5 / 4, 0,
_placeSizeWidth * 5 / 4, _placeSizeHeight * 3 / 2);
g.FillRectangle(Brushes.Gray, 0, _placeSizeHeight * 3 / 2,
_placeSizeWidth * 1 / 4, _pictureHeight - _placeSizeHeight * 3 / 2);
g.FillRectangle(Brushes.Gray, _pictureWidth - _placeSizeWidth * 1 / 4, _placeSizeHeight * 3 / 2,
_placeSizeWidth * 1 / 4, _pictureHeight - _placeSizeHeight * 3 / 2);
g.FillRectangle(Brushes.Gray, 0, 0, _pictureWidth, _placeSizeHeight * 1 / 2);
// рисуем плавучие пирсы
// горизонтальные
int w = _placeSizeWidth;
int h = _placeSizeHeight;
int x = w * 1 / 4;
int y = h * 5 / 2;
int pirsSize = h * 1 / 6;
int i = 0;
while (y + h + pirsSize < _pictureHeight)
{
g.FillRectangle(Brushes.Brown, x, y, w, pirsSize);
g.FillRectangle(Brushes.Brown, _pictureWidth - x - w, y, w, pirsSize);
if (pointsInit)
{
_placesPoints[11 + i] = new Point(x + 5, y - _placeSizeHeight + 5);
_placesPoints[6 - i] = new Point(_pictureWidth - x - w + 5, y - _placeSizeHeight + 5);
}
y += h + pirsSize;
i++;
}
if (pointsInit)
{
_placesPoints[11 + i] = new Point(x + 5, y - _placeSizeHeight + 5);
_placesPoints[6 - i] = new Point(_pictureWidth - x - w + 5, y - _placeSizeHeight + 5);
}
// вертикальные
x = _placeSizeWidth * 5 / 4 + w;
y = _placeSizeHeight * 1 / 2;
h = _placeSizeHeight;
i = 0;
while (x + w + pirsSize < _pictureWidth - _placeSizeWidth * 5 / 4)
{
g.FillRectangle(Brushes.Brown, x, y, pirsSize, h);
if (pointsInit)
{
_placesPoints[10 - i] = new Point(x - w + 5, y + 5);
}
x += w + pirsSize;
i++;
}
if (pointsInit)
{
_placesPoints[10 - i] = new Point(x - w + 5, y + 5);
}
}
/// <summary>
/// Метод отрисовки лодок
/// </summary>
/// <param name="g"></param>
private void DrawBoats(Graphics g)
{
int i = 0;
foreach (var boat in _setBoats.GetBoats())
{
// Установка позиции
boat.SetObject(_placesPoints[i].X, _placesPoints[i].Y,
_pictureWidth, _pictureHeight);
boat.DrawingObject(g);
i++;
}
}
/// <summary>
/// Получение данных в виде строки
/// </summary>
/// <param name="sep"></param>
/// <returns></returns>
public string GetData(char separatorType, char separatorData)
{
string data = $"{_map.GetType().Name}{separatorType}";
foreach (var car in _setBoats.GetBoats())
{
data += $"{car.GetInfo()}{separatorData}";
}
return data;
}
/// <summary>
/// Загрузка списка из массива строк
/// </summary>
/// <param name="records"></param>
public void LoadData(string[] records)
{
foreach (var rec in records)
{
_setBoats.Insert(DrawingObjectBoat.Create(rec) as T);
}
}
}
}