ISEbd-21_Melnikov_I.O._Loco.../Locomotives/Locomotives/AbstractMap.cs

245 lines
8.8 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.

namespace Locomotives
{
internal abstract class AbstractMap
{
/// <summary>
/// Поле от интерфейса прорисовки
/// </summary>
private IDrawningObject _drawningObject = null;
/// <summary>
/// Массив карты
/// </summary>
protected int[,] _map = null;
/// <summary>
/// Ширина карты (графической панели)
/// </summary>
protected int _width;
/// <summary>
/// Высота карты (графической панели)
/// </summary>
protected int _height;
/// <summary>
/// Ширина ячейки
/// </summary>
protected float _size_x;
/// <summary>
/// Высота ячейки
/// </summary>
protected float _size_y;
protected readonly Random _random = new();
/// <summary>
/// Доступная для движения ячейка
/// </summary>
protected readonly int _freeRoad = 0;
/// <summary>
/// Недоступная для движения ячейка
/// </summary>
protected readonly int _barrier = 1;
/// <summary>
/// Наполнение графической панели
/// </summary>
/// <param name="width">Ширина</param>
/// <param name="height">Высота</param>
/// <param name="drawningObject"></param>
/// <returns></returns>
public Bitmap CreateMap(int width, int height, IDrawningObject drawningObject)
{
_width = width;
_height = height;
_drawningObject = drawningObject;
GenerateMap();
while (!SetObjectOnMap())
{
GenerateMap();
}
return DrawMapWithObject();
}
/// <summary>
/// Получение координат отрисовываемого объекта в массиве
/// </summary>
/// <returns></returns>
public (int Top, int Bottom, int Left, int Right) GetObjectCoordinates()
{
return
(
(int)(_drawningObject.GetCurrentPosition().Top / _size_y),
(int)(_drawningObject.GetCurrentPosition().Bottom / _size_y),
(int)(_drawningObject.GetCurrentPosition().Left / _size_x),
(int)(_drawningObject.GetCurrentPosition().Right / _size_x)
);
}
/// <summary>
/// Проверка возможности движения в данном направлении
/// </summary>
/// <param name="direction">Направление</param>
/// <returns></returns>
private bool AbleToMove(Direction direction)
{
switch (direction)
{
case Direction.Up:
if (GetObjectCoordinates().Top - 1 < 0)
{
return false;
}
break;
case Direction.Down:
if (GetObjectCoordinates().Bottom + 1 > _map.GetLength(0))
{
return false;
}
break;
case Direction.Left:
if (GetObjectCoordinates().Left - 1 < 0)
{
return false;
}
break;
case Direction.Right:
if (GetObjectCoordinates().Right + 1 > _map.GetLength(1))
{
return false;
}
break;
}
for (int i = GetObjectCoordinates().Left; i <= GetObjectCoordinates().Right; i++)
{
for (int j = GetObjectCoordinates().Top; j <= GetObjectCoordinates().Bottom; j++)
{
if (i - 1 < 0 || j - 1 < 0 || i + 1 > _map.GetLength(0) || j + 1 > _map.GetLength(1))
{
return false;
}
switch (direction)
{
case Direction.Up:
if (_map[i, j - 1] == _barrier)
{
return false;
}
break;
case Direction.Down:
if (_map[i, j + 1] == _barrier)
{
return false;
}
break;
case Direction.Left:
if (_map[i - 1, j] == _barrier)
{
return false;
}
break;
case Direction.Right:
if (_map[i + 1, j] == _barrier)
{
return false;
}
break;
}
}
}
return true;
}
/// <summary>
/// Проверка возможности установить объект на карте
/// </summary>
/// <returns></returns>
private bool AbleToSetObject()
{
for (int i = GetObjectCoordinates().Left; i <= GetObjectCoordinates().Right; i++)
{
for (int j = GetObjectCoordinates().Top; j <= GetObjectCoordinates().Bottom; j++)
{
if (_map[i, j] == _barrier || i < 0 || j < 0)
{
return false;
}
}
}
return true;
}
/// <summary>
/// Передвижение объекта по карте
/// </summary>
/// <param name="direction">Направление</param>
/// <returns></returns>
public Bitmap MoveObject(Direction direction)
{
if (!AbleToMove(direction))
{
return DrawMapWithObject();
}
_drawningObject.MoveObject(direction);
return DrawMapWithObject();
}
/// <summary>
/// Создание объекта на карте
/// </summary>
/// <returns>Возможность создать объект</returns>
private bool SetObjectOnMap()
{
if (_drawningObject == null || _map == null)
{
return false;
}
int x = _random.Next(10, 100);
int y = _random.Next(10, 100);
_drawningObject.SetObject(x, y, _width, _height);
// TODO првоерка, что объект не "накладывается" на закрытые участки
if (!AbleToSetObject())
{
return false;
}
return true;
}
/// <summary>
/// Отрисовка карты
/// </summary>
/// <returns></returns>
private Bitmap DrawMapWithObject()
{
Bitmap bmp = new(_width, _height);
if (_drawningObject == null || _map == null)
{
return bmp;
}
Graphics gr = Graphics.FromImage(bmp);
for (int i = 0; i < _map.GetLength(0); ++i)
{
for (int j = 0; j < _map.GetLength(1); ++j)
{
if (_map[i, j] == _freeRoad)
{
DrawRoadPart(gr, i, j);
}
else if (_map[i, j] == _barrier)
{
DrawBarrierPart(gr, i, j);
}
}
}
_drawningObject.DrawningObject(gr);
return bmp;
}
/// <summary>
/// Генерация массива карты
/// </summary>
protected abstract void GenerateMap();
/// <summary>
/// Отрисовка ячейки со свободным пространством (дорогой)
/// </summary>
/// <param name="g"></param>
/// <param name="i"></param>
/// <param name="j"></param>
protected abstract void DrawRoadPart(Graphics g, int i, int j);
/// <summary>
/// Отрисовка ячейки с барьером
/// </summary>
/// <param name="g"></param>
/// <param name="i"></param>
/// <param name="j"></param>
protected abstract void DrawBarrierPart(Graphics g, int i, int j);
}
}