Compare commits

..

9 Commits
main ... Lab03

32 changed files with 1926 additions and 75 deletions

View File

@ -0,0 +1,119 @@
using Battleship.Drawnings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.CollectionGenericObjects;
/// <summary>
/// Абстракция компании, хранящий коллекцию кораблей
/// </summary>
public abstract class AbstractCompany
{
/// <summary>
/// Размер места (ширина)
/// </summary>
protected readonly int _placeSizeWidth = 210;
/// <summary>
/// Размер места (высота)
/// </summary>
protected readonly int _placeSizeHeight = 100;
/// <summary>
/// Ширина окна
/// </summary>
protected readonly int _pictureWidth;
/// <summary>
/// Высота окна
/// </summary>
protected readonly int _pictureHeight;
/// <summary>
/// Коллекция кораблей
/// </summary>
protected ICollectionGenericObjects<DrawningShip>? _collection = null;
/// <summary>
/// Вычисление максимального количества элементов, который можно разместить в окне
/// </summary>
private int GetMaxCount => _pictureWidth * _pictureHeight / (_placeSizeWidth * _placeSizeHeight);
/// <summary>
/// Конструктор
/// </summary>
/// <param name="picWidth">Ширина окна</param>
/// <param name="picHeight">Высота окна</param>
/// <param name="collection">Коллекция кораблей</param>
public AbstractCompany(int picWidth, int picHeight, ICollectionGenericObjects<DrawningShip> collection)
{
_pictureWidth = picWidth;
_pictureHeight = picHeight;
_collection = collection;
_collection.SetMaxCount = GetMaxCount;
}
/// <summary>
/// Перегрузка оператора сложения для класса
/// </summary>
/// <param name="company">Компания</param>
/// <param name="car">Добавляемый объект</param>
/// <returns></returns>
public static int operator +(AbstractCompany company, DrawningShip ship)
{
return company._collection.Insert(ship);
}
/// <summary>
/// Перегрузка оператора удаления для класса
/// </summary>
/// <param name="company">Компания</param>
/// <param name="position">Номер удаляемого объекта</param>
/// <returns></returns>
public static DrawningShip operator -(AbstractCompany company, int position)
{
return company._collection?.Remove(position);
}
/// <summary>
/// Получение случайного объекта из коллекции
/// </summary>
/// <returns></returns>
public DrawningShip? GetRandomObject()
{
Random rnd = new();
return _collection?.Get(rnd.Next(GetMaxCount));
}
/// <summary>
/// Вывод всей коллекции
/// </summary>
/// <returns></returns>
public Bitmap? Show()
{
Bitmap bitmap = new(_pictureWidth, _pictureHeight);
Graphics graphics = Graphics.FromImage(bitmap);
DrawBackground(graphics);
SetObjectsPosition();
for (int i = 0; i < (_collection?.Count ?? 0); ++i)
{
DrawningShip? obj = _collection?.Get(i);
obj?.DrawTransport(graphics);
}
return bitmap;
}
/// <summary>
/// Вывод заднего фона
/// </summary>
/// <param name="g"></param>
protected abstract void DrawBackground(Graphics g);
/// <summary>
/// Расстановка объектов
/// </summary>
protected abstract void SetObjectsPosition();
}

View File

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.CollectionGenericObjects;
/// <summary>
/// Интерфейс описания действий для набора хранимых объектов
/// </summary>
/// <typeparam name="T">Параметр: ограничение - ссылочный тип</typeparam>
public interface ICollectionGenericObjects<T>
where T : class
{
/// <summary>
/// Количество объектов в коллекции
/// </summary>
int Count { get; }
/// <summary>
/// Установка максимального количества элементов
/// </summary>
int SetMaxCount { set; }
/// <summary>
/// Добавление объекта в коллекцию
/// </summary>
/// <param name="obj">Добавляемый объект</param>
/// <returns>true - удачно, false - вставка не удалась</returns>
int Insert(T obj);
/// <summary>
/// Добавление объекта в коллекцию на конкретную позицию
/// </summary>
/// <param name="obj">Добавляемый объект</param>
/// <param name="position">Позиция</param>
/// <returns>true - удачно, false - вставка не удалась</returns>
bool Insert(T obj, int position);
/// <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);
}

View File

@ -0,0 +1,110 @@
using Battleship.Drawnings;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.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;
/// <summary>
/// Установка максимального кол-ва объектов
/// </summary>
public int SetMaxCount
{
set
{
if (value > 0)
{
if (_collection.Length > 0)
{
Array.Resize(ref _collection, value);
}
else
{
_collection = new T?[value];
}
}
}
}
/// <summary>
/// Конструктор
/// </summary>
public MassiveGenericObjects()
{
_collection = Array.Empty<T?>();
}
/// <summary>
/// Получение объекта по позиции
/// </summary>
/// <param name="position">Позиция (индекс)</param>
/// <returns></returns>
public T? Get(int position)
{
if (position < 0 || position >= _collection.Length)
return null;
return _collection[position];
}
public int Insert(T obj)
{
for (int i = 0; i < _collection.Length; i++)
{
if (_collection[i] == null)
{
_collection[i] = obj;
return i;
}
}
return -1;
}
public bool Insert(T obj, int position)
{
if (position < 0 || position >= _collection.Length) // проверка позиции
return false;
if (_collection[position] == null) // Попытка вставить на указанную позицию
{
_collection[position] = obj;
return true;
}
for (int i = position; i < _collection.Length; i++) // попытка вставить объект на позицию после указанной
{
if (_collection[i] == null)
{
_collection[i] = obj;
return true;
}
}
for (int i = 0; i < position; i++) // попытка вставить объект на позицию до указанной
{
if (_collection[i] == null)
{
_collection[i] = obj;
return true;
}
}
return false;
}
public T? Remove(int position)
{
if (position < 0 || position >= _collection.Length || _collection[position]==null) // проверка позиции и наличия объекта
return null;
T? temp = _collection[position];
_collection[position] = null;
return temp;
}
}

View File

@ -0,0 +1,57 @@
using Battleship.Drawnings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.CollectionGenericObjects;
/// <summary>
/// Реализация абстрактной компании - доки с кораблями
/// </summary>
public class ShipDocks : AbstractCompany
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="picWidth"></param>
/// <param name="picHeight"></param>
/// <param name="collection"></param>
public ShipDocks(int picWidth, int picHeight, ICollectionGenericObjects<DrawningShip> collection) : base(picWidth, picHeight, collection)
{
}
protected override void DrawBackground(Graphics g)
{
Pen pen = new Pen(Color.Brown, 4);
int x = 0, y = 0;
while (y + _placeSizeHeight < _pictureHeight)
{
while (x + _placeSizeWidth < _pictureWidth)
{
g.DrawLine(pen, x, y, x + _placeSizeWidth, y);
g.DrawLine(pen, x, y, x, y + _placeSizeHeight);
g.DrawLine(pen, x, y + _placeSizeHeight, x+_placeSizeWidth, y + _placeSizeHeight);
x += _placeSizeWidth + 50;
}
y += _placeSizeHeight;
x = 0;
}
}
protected override void SetObjectsPosition()
{
int count = 0;
for (int iy = _placeSizeHeight * 11 + 5; iy >= 0; iy -= _placeSizeHeight)
{
for(int ix = 5; ix + _placeSizeWidth+50 < _pictureWidth; ix += _placeSizeWidth + 50)
{
_collection?.Get(count)?.SetPictureSize(_pictureWidth, _pictureHeight);
_collection?.Get(count)?.SetPosition(ix, iy);
count++;
}
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.Drawnings;
public enum DirectionType
{
Unknown = -1, //Неизвестное направление
Up = 1, //Вверх
Down = 2,//Вниз
Right = 3,//Вправо
Left = 4 //Влево
}

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Battleship.Entities;
namespace Battleship.Drawnings;
// класс прорисовки и пермещения
public class DrawningBattleship : DrawningShip
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodyColor">Основной цвет</param>
/// <param name="additionalColor">Дополнительный цвет</param>
/// <param name="bodyKit">Признак наличия обвеса</param>
/// <param name="wing">Признак наличия антикрыла</param>
/// <param name="sportLine">Признак наличия гоночной полосы</param>
public DrawningBattleship(int speed, double weight, Color bodycolor, Color additionalcolor, bool weapon, bool rockets) : base(143, 75)
{
EntityShip = new EntityBattleship(speed, weight, bodycolor, additionalcolor, weapon, rockets);
}
public override void DrawTransport(Graphics g)
{
if (EntityShip == null || EntityShip is not EntityBattleship entityBattleship || !_startX.HasValue || !_startY.HasValue) //проверка наличия корабля и инициализации начальной позиции
return;
_startY += 15;
base.DrawTransport(g);
_startY -= 15;
#region Прорисовка доп. элеменетов
Pen pen = new(Color.Black, 3); //!!! ЗАДАТЬ ВОПРОС ПРО PEN
Brush addBr = new SolidBrush(entityBattleship.AdditionalColor);
// Орудийная башня
if (entityBattleship.Weapon)
{
g.FillPie(addBr, _startX.Value + 8, _startY.Value + 15, 30, 25, 180, 180);
g.FillRectangle(addBr, _startX.Value + 18, _startY.Value, 10, 20);
}
//Ракеты
if (entityBattleship.Rockets)
{
g.FillRectangle(addBr, _startX.Value + 8, _startY.Value + 15 + 20, 30, 35);
g.DrawRectangle(pen, _startX.Value + 8, _startY.Value + 15 + 20, 30, 35);
g.DrawEllipse(pen, _startX.Value + 13, _startY.Value + 15 + 25, 10, 10);
g.DrawEllipse(pen, _startX.Value + 23, _startY.Value + 15 + 25, 10, 10);
g.DrawEllipse(pen, _startX.Value + 23, _startY.Value + 15 + 40, 10, 10);
g.DrawEllipse(pen, _startX.Value + 13, _startY.Value + 15 + 40, 10, 10);
}
#endregion
}
}

View File

@ -0,0 +1,149 @@
using Battleship.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.Drawnings;
public class DrawningShip
{
#region [Инициализация переменных]
public EntityShip? EntityShip { get; protected set; } //класс сущность
private int? _pictureWidth; //ширина окна
private int? _pictureHeight; //высота окна
protected int? _startX; // Х начальной позиции
protected int? _startY; // Y начальной позиции
private readonly int _drawningShipWidth = 143; // длина корабля
private readonly int _drawningShipHeight = 60; // высота корабля
#endregion
#region [Инициализация геттеров переменных]
/// <summary>
/// Getter координаты Х
/// </summary>
public int? GetPosX => _startX;
/// <summary>
/// Getter координаты Y
/// </summary>
public int? GetPosY => _startY;
/// <summary>
/// Getter ширины объекта
/// </summary>
public int GetWidth => _drawningShipWidth;
/// <summary>
/// Getter высоты объекта
/// </summary>
public int GetHeight => _drawningShipHeight;
#endregion
/// <summary>
/// Пустой конструктор
/// </summary>
public DrawningShip()
{
_pictureWidth = null;
_pictureHeight = null;
_startX = null;
_startY = null;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodyColor">Основной цвет</param>
public DrawningShip(int speed, double weight, Color bodyColor) : this()
{
EntityShip = new EntityShip(speed, weight, bodyColor);
}
/// <summary>
/// Конструктор для наследников
/// </summary>
/// <param name="drawningShipWidth"></param>
/// <param name="drawningShipHeight"></param>
protected DrawningShip(int drawningShipWidth, int drawningShipHeight) : this()
{
_drawningShipHeight = drawningShipHeight;
_drawningShipWidth = drawningShipWidth;
}
public bool SetPictureSize(int width, int height) // установка размеров окна
{
if (width > _drawningShipWidth && height > _drawningShipHeight) //если размеры окна позволяют вместить корабль, то присваиваем
{
if (_startX.HasValue && _startY.HasValue)
{
if (_drawningShipHeight + _startY.Value > height)
{
_startY = height - _drawningShipHeight;
}
if (_drawningShipWidth + _startX.Value > width)
{
_startX = width - _drawningShipWidth;
}
}
_pictureWidth = width;
_pictureHeight = height;
return true;
}
return false;
}
public void SetPosition(int x, int y) // установка позиции корабля
{
if (!_pictureHeight.HasValue || !_pictureWidth.HasValue) // проверка инициализации размеров окна
return;
if (x < 0 || x + _drawningShipWidth > _pictureWidth) // если корабль не вмещается по Х - присваиваем 0
x = 0;
if (y < 0 || y + _drawningShipHeight > _pictureHeight) // если корабль не вмещается по Y - присваиваем 0
y = 0;
_startX = x;
_startY = y;
}
public bool MoveTransport(DirectionType direction) //метод движения корабля
{
if (EntityShip == null || !_startX.HasValue || !_startY.HasValue) //проверка наличия корабля и инициализации начальной позиции
return false;
switch (direction)
{
case DirectionType.Left: // Влево
if (_startX.Value - EntityShip.Step > 0) // Проверяем, есть ли место для шага (аналогично далее)
_startX -= (int)EntityShip.Step;
return true;
case DirectionType.Right: // Вправо
if (_startX.Value + EntityShip.Step + _drawningShipWidth < _pictureWidth)
_startX += (int)EntityShip.Step;
return true;
case DirectionType.Up: // Вверх
if (_startY.Value - EntityShip.Step > 0)
_startY -= (int)EntityShip.Step;
return true;
case DirectionType.Down: // Вниз
if (_startY.Value + _drawningShipHeight + EntityShip.Step < _pictureHeight)
_startY += (int)EntityShip.Step;
return true;
default: return false;
}
}
public virtual void DrawTransport(Graphics g) //метод рисования корабля
{
if (EntityShip == null || !_startX.HasValue || !_startY.HasValue) //проверка наличия корабля и инициализации начальной позиции
return;
Pen pen = new(Color.Black, 3);
Brush br = new SolidBrush(EntityShip.BodyColor);
#region [Drawing]
// Гриницы Линкора
g.DrawLine(pen, _startX.Value + 3, _startY.Value, _startX.Value + 93, _startY.Value);
g.DrawLine(pen, _startX.Value + 93, _startY.Value, _startX.Value + 143, _startY.Value + 30);
g.DrawLine(pen, _startX.Value + 143, _startY.Value + 30, _startX.Value + 93, _startY.Value + 60);
g.DrawLine(pen, _startX.Value + 93, _startY.Value + 60, _startX.Value + 3, _startY.Value + 60);
g.DrawLine(pen, _startX.Value + 3, _startY.Value + 60, _startX.Value + 3, _startY.Value);
//Заливка
g.FillRectangle(br, _startX.Value + 3, _startY.Value, 90, 60);
g.FillPolygon(br, new PointF[] { new PointF(_startX.Value + 93, _startY.Value), new PointF(_startX.Value + 143, _startY.Value + 30), new PointF(_startX.Value + 93, _startY.Value + 60) });
//Элементы палубы
g.DrawEllipse(pen, _startX.Value + 83, _startY.Value + 20, 20, 20);
g.DrawRectangle(pen, _startX.Value + 63, _startY.Value + 15, 15, 30);
g.DrawRectangle(pen, _startX.Value + 43, _startY.Value + 25, 20, 10);
Brush brBlack = new SolidBrush(Color.Black);
g.FillRectangle(brBlack, _startX.Value, _startY.Value + 10, 3, 15);
g.FillRectangle(brBlack, _startX.Value, _startY.Value + 35, 3, 15);
#endregion
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.Entities;
// класс-сущность "Боевой корабль"
public class EntityBattleship : EntityShip
{
public Color AdditionalColor; // дополнительный цвет
public bool Weapon { get; private set; } // оружие
public bool Rockets { get; set; } // рокеты
/// <summary>
/// Конструктор сущности
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodycolor">Основной цвет</param>
/// <param name="additionalcolor">Дополнительный цвет</param>
/// <param name="weapon">Наличие оружейной башни</param>
/// <param name="rockets">Наличие рокет</param>
public EntityBattleship(int speed, double weight, Color bodycolor, Color additionalcolor, bool weapon, bool rockets) : base(speed, weight, bodycolor) // инициализация полей объекта-класса военного корабля
{
AdditionalColor = additionalcolor;
Weapon = weapon;
Rockets = rockets;
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.Entities;
/// <summary>
/// Класс-сущность "Корабль"
/// </summary>
public class EntityShip
{
public int Speed; // скорость
public double Weight; //вес
public Color BodyColor; /*основной цвет*/
public double Step => Speed * 100 / Weight; // шаг перемещения корабля
/// <summary>
/// Конструктор сущности
/// </summary>
/// <param name="speed">Скорость</param>
/// <param name="weight">Вес</param>
/// <param name="bodycolor">Цвет</param>
public EntityShip(int speed, double weight, Color bodycolor) {
Speed = speed;
Weight = weight;
BodyColor = bodycolor;
}
}

View File

@ -1,39 +0,0 @@
namespace Battleship
{
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 Battleship
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,145 @@
namespace Battleship
{
partial class FormBattleship
{
/// <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()
{
pictureBoxBattleship = new PictureBox();
buttonUp = new Button();
buttonDown = new Button();
buttonLeft = new Button();
buttonRight = new Button();
comboBoxStrategy = new ComboBox();
buttonStrategyStep = new Button();
((System.ComponentModel.ISupportInitialize)pictureBoxBattleship).BeginInit();
SuspendLayout();
//
// pictureBoxBattleship
//
pictureBoxBattleship.Dock = DockStyle.Fill;
pictureBoxBattleship.Location = new Point(0, 0);
pictureBoxBattleship.Name = "pictureBoxBattleship";
pictureBoxBattleship.Size = new Size(1496, 902);
pictureBoxBattleship.TabIndex = 0;
pictureBoxBattleship.TabStop = false;
//
// buttonUp
//
buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonUp.BackgroundImage = Properties.Resources.right_arrow;
buttonUp.BackgroundImageLayout = ImageLayout.Stretch;
buttonUp.Location = new Point(1389, 798);
buttonUp.Name = "buttonUp";
buttonUp.Size = new Size(40, 40);
buttonUp.TabIndex = 2;
buttonUp.UseVisualStyleBackColor = true;
buttonUp.Click += ButtonMove_Click;
//
// buttonDown
//
buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonDown.BackgroundImage = Properties.Resources.right_arrow_2;
buttonDown.BackgroundImageLayout = ImageLayout.Stretch;
buttonDown.Location = new Point(1389, 844);
buttonDown.Name = "buttonDown";
buttonDown.Size = new Size(40, 40);
buttonDown.TabIndex = 3;
buttonDown.UseVisualStyleBackColor = true;
buttonDown.Click += ButtonMove_Click;
//
// buttonLeft
//
buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonLeft.BackgroundImage = Properties.Resources.right_arrow_4;
buttonLeft.BackgroundImageLayout = ImageLayout.Stretch;
buttonLeft.Location = new Point(1343, 844);
buttonLeft.Name = "buttonLeft";
buttonLeft.Size = new Size(40, 40);
buttonLeft.TabIndex = 4;
buttonLeft.UseVisualStyleBackColor = true;
buttonLeft.Click += ButtonMove_Click;
//
// buttonRight
//
buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
buttonRight.BackgroundImage = Properties.Resources.right_arrow_3;
buttonRight.BackgroundImageLayout = ImageLayout.Stretch;
buttonRight.Location = new Point(1435, 844);
buttonRight.Name = "buttonRight";
buttonRight.Size = new Size(40, 40);
buttonRight.TabIndex = 5;
buttonRight.UseVisualStyleBackColor = true;
buttonRight.Click += ButtonMove_Click;
//
// comboBoxStrategy
//
comboBoxStrategy.Anchor = AnchorStyles.Top | AnchorStyles.Right;
comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxStrategy.FormattingEnabled = true;
comboBoxStrategy.Items.AddRange(new object[] { "К центру", "К краю" });
comboBoxStrategy.Location = new Point(1232, 12);
comboBoxStrategy.Name = "comboBoxStrategy";
comboBoxStrategy.Size = new Size(243, 40);
comboBoxStrategy.TabIndex = 7;
//
// buttonStrategyStep
//
buttonStrategyStep.Anchor = AnchorStyles.Top | AnchorStyles.Right;
buttonStrategyStep.Location = new Point(1325, 70);
buttonStrategyStep.Name = "buttonStrategyStep";
buttonStrategyStep.Size = new Size(150, 46);
buttonStrategyStep.TabIndex = 8;
buttonStrategyStep.Text = "Шаг";
buttonStrategyStep.UseVisualStyleBackColor = true;
buttonStrategyStep.Click += buttonStrategyStep_Click;
//
// FormBattleship
//
AutoScaleDimensions = new SizeF(13F, 32F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1496, 902);
Controls.Add(buttonStrategyStep);
Controls.Add(comboBoxStrategy);
Controls.Add(buttonRight);
Controls.Add(buttonLeft);
Controls.Add(buttonDown);
Controls.Add(buttonUp);
Controls.Add(pictureBoxBattleship);
Name = "FormBattleship";
Text = "Линкор";
((System.ComponentModel.ISupportInitialize)pictureBoxBattleship).EndInit();
ResumeLayout(false);
}
#endregion
private PictureBox pictureBoxBattleship;
private Button buttonUp;
private Button buttonDown;
private Button buttonLeft;
private Button buttonRight;
private ComboBox comboBoxStrategy;
private Button buttonStrategyStep;
}
}

View File

@ -0,0 +1,100 @@
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 Battleship.Drawnings;
using Battleship.Entities;
using Battleship.MovementStrategy;
namespace Battleship
{
public partial class FormBattleship : Form
{
private DrawningShip? _drawningShip;
private AbstractStrategy? _strategy;
/// <summary>
/// Получение объекта
/// </summary>
public DrawningShip SetShip
{
set
{
_drawningShip = value; //??? value в сеттерах - стандартная переменная?
_drawningShip.SetPictureSize(pictureBoxBattleship.Width, pictureBoxBattleship.Height);
comboBoxStrategy.Enabled = true;
_strategy = null;
Draw();
}
}
public FormBattleship()
{
InitializeComponent();
_strategy = null;
}
private void Draw() // метод рисования корабля
{
if (_drawningShip == null)
return;
Bitmap bmp = new(pictureBoxBattleship.Width, pictureBoxBattleship.Height);
Graphics gr = Graphics.FromImage(bmp);
_drawningShip.DrawTransport(gr);
pictureBoxBattleship.Image = bmp;
}
private void ButtonMove_Click(object sender, EventArgs e) // обработка кнопок движения
{
if (_drawningShip == null)
return;
string name = ((Button)sender)?.Name ?? string.Empty;
bool result = false;
switch (name)
{
case "buttonUp":
result = _drawningShip.MoveTransport(DirectionType.Up);
break;
case "buttonDown":
result = _drawningShip.MoveTransport(DirectionType.Down);
break;
case "buttonRight":
result = _drawningShip.MoveTransport(DirectionType.Right);
break;
case "buttonLeft":
result = _drawningShip.MoveTransport(DirectionType.Left);
break;
}
if (result)
Draw();
}
private void buttonStrategyStep_Click(object sender, EventArgs e)
{
if (_drawningShip == null)
return;
if (comboBoxStrategy.Enabled)
{
_strategy = comboBoxStrategy.SelectedIndex switch
{
0 => new MoveToCenter(),
1 => new MoveToBorder(),
_ => null,
};
if (_strategy == null)
return;
_strategy.SetData(new MoveableShip(_drawningShip), pictureBoxBattleship.Width, pictureBoxBattleship.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,174 @@
namespace Battleship
{
partial class FormShipCollection
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
Tools = new GroupBox();
buttonRefresh = new Button();
buttonGoToTest = new Button();
buttonDelShip = new Button();
maskedTextBox = new MaskedTextBox();
buttonAddBettleship = new Button();
buttonAddShip = new Button();
comboBoxSelectorCompany = new ComboBox();
pictureBox = new PictureBox();
Tools.SuspendLayout();
((System.ComponentModel.ISupportInitialize)pictureBox).BeginInit();
SuspendLayout();
//
// Tools
//
Tools.Controls.Add(buttonRefresh);
Tools.Controls.Add(buttonGoToTest);
Tools.Controls.Add(buttonDelShip);
Tools.Controls.Add(maskedTextBox);
Tools.Controls.Add(buttonAddBettleship);
Tools.Controls.Add(buttonAddShip);
Tools.Controls.Add(comboBoxSelectorCompany);
Tools.Dock = DockStyle.Right;
Tools.Location = new Point(1605, 0);
Tools.Name = "Tools";
Tools.Size = new Size(488, 1236);
Tools.TabIndex = 0;
Tools.TabStop = false;
Tools.Text = "Инструменты";
//
// buttonRefresh
//
buttonRefresh.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonRefresh.Location = new Point(14, 1134);
buttonRefresh.Name = "buttonRefresh";
buttonRefresh.Size = new Size(468, 90);
buttonRefresh.TabIndex = 6;
buttonRefresh.Text = "Обновить";
buttonRefresh.UseVisualStyleBackColor = true;
buttonRefresh.Click += ButtonRefresh_Click;
//
// buttonGoToTest
//
buttonGoToTest.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonGoToTest.Location = new Point(6, 768);
buttonGoToTest.Name = "buttonGoToTest";
buttonGoToTest.Size = new Size(476, 90);
buttonGoToTest.TabIndex = 5;
buttonGoToTest.Text = "Передать на тест";
buttonGoToTest.UseVisualStyleBackColor = true;
buttonGoToTest.Click += ButtonGoToTest_Click;
//
// buttonDelShip
//
buttonDelShip.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonDelShip.Location = new Point(6, 573);
buttonDelShip.Name = "buttonDelShip";
buttonDelShip.Size = new Size(476, 90);
buttonDelShip.TabIndex = 4;
buttonDelShip.Text = "Удалить корабль";
buttonDelShip.UseVisualStyleBackColor = true;
buttonDelShip.Click += ButtonDelShip_Click;
//
// maskedTextBox
//
maskedTextBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
maskedTextBox.Location = new Point(6, 520);
maskedTextBox.Mask = "00";
maskedTextBox.Name = "maskedTextBox";
maskedTextBox.Size = new Size(476, 39);
maskedTextBox.TabIndex = 3;
maskedTextBox.ValidatingType = typeof(int);
//
// buttonAddBettleship
//
buttonAddBettleship.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonAddBettleship.Location = new Point(6, 283);
buttonAddBettleship.Name = "buttonAddBettleship";
buttonAddBettleship.Size = new Size(476, 90);
buttonAddBettleship.TabIndex = 2;
buttonAddBettleship.Text = "Добавить боевой корабль";
buttonAddBettleship.UseVisualStyleBackColor = true;
buttonAddBettleship.Click += ButtonAddBattleship_Click;
//
// buttonAddShip
//
buttonAddShip.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
buttonAddShip.Location = new Point(6, 172);
buttonAddShip.Name = "buttonAddShip";
buttonAddShip.Size = new Size(476, 90);
buttonAddShip.TabIndex = 1;
buttonAddShip.Text = "Добавить корабль";
buttonAddShip.UseVisualStyleBackColor = true;
buttonAddShip.Click += buttonAddShip_Click_1;
//
// 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(6, 38);
comboBoxSelectorCompany.Name = "comboBoxSelectorCompany";
comboBoxSelectorCompany.Size = new Size(476, 40);
comboBoxSelectorCompany.TabIndex = 0;
comboBoxSelectorCompany.SelectedIndexChanged += ComboBoxSelectorCompany_SelectedIndexChanged;
//
// pictureBox
//
pictureBox.Dock = DockStyle.Fill;
pictureBox.Location = new Point(0, 0);
pictureBox.Name = "pictureBox";
pictureBox.Size = new Size(1605, 1236);
pictureBox.TabIndex = 1;
pictureBox.TabStop = false;
//
// FormShipCollection
//
AutoScaleDimensions = new SizeF(13F, 32F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(2093, 1236);
Controls.Add(pictureBox);
Controls.Add(Tools);
Name = "FormShipCollection";
Text = "Коллекция кораблей";
Tools.ResumeLayout(false);
Tools.PerformLayout();
((System.ComponentModel.ISupportInitialize)pictureBox).EndInit();
ResumeLayout(false);
}
#endregion
private GroupBox Tools;
private Button buttonAddBettleship;
private Button buttonAddShip;
private ComboBox comboBoxSelectorCompany;
private Button buttonDelShip;
private MaskedTextBox maskedTextBox;
private PictureBox pictureBox;
private Button buttonRefresh;
private Button buttonGoToTest;
}
}

View File

@ -0,0 +1,166 @@
using Battleship.CollectionGenericObjects;
using Battleship.Drawnings;
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;
namespace Battleship;
public partial class FormShipCollection : Form
{
/// <summary>
/// Компания
/// </summary>
private AbstractCompany? _company = null;
/// <summary>
/// Конструктор
/// </summary>
public FormShipCollection()
{
InitializeComponent();
}
/// <summary>
/// Выбор компании
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ComboBoxSelectorCompany_SelectedIndexChanged(object sender, EventArgs e)
{
switch (comboBoxSelectorCompany.Text)
{
case "Доки":
_company = new ShipDocks(pictureBox.Width, pictureBox.Height, new MassiveGenericObjects<DrawningShip>());
break;
}
}
/// <summary>
/// Создание объекта класса-перемещения
/// </summary>
/// <param name="type">Тип создаваемого объекта</param>
private void CreateObject(string type)
{
if (_company == null)
{
return;
}
Random random = new();
DrawningShip drawningShip;
switch (type)
{
case nameof(DrawningShip):
drawningShip = new DrawningShip(random.Next(100, 300), random.Next(1000, 3000), GetColor(random));
break;
case nameof(DrawningBattleship):
drawningShip = new DrawningBattleship(random.Next(100, 300), random.Next(1000, 3000),
GetColor(random), GetColor(random),
Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2)));
break;
default:
return;
}
if (_company + drawningShip != -1)
{
MessageBox.Show("Объект добавлен");
pictureBox.Image = _company.Show();
}
else
{
MessageBox.Show("Не удалось добавить объект");
}
}
/// <summary>
/// Получение цвета
/// </summary>
/// <param name="random">Генератор случайных чисел</param>
/// <returns></returns>
private static Color GetColor(Random random)
{
Color color = Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255));
ColorDialog dialog = new();
if (dialog.ShowDialog() == DialogResult.OK)
{
color = dialog.Color;
}
return color;
}
private void ButtonDelShip_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(maskedTextBox.Text) || _company == null)
{
return;
}
if (MessageBox.Show("Удалить объект?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
return;
}
int pos = Convert.ToInt32(maskedTextBox.Text);
if (_company - pos != null)
{
MessageBox.Show("Объект удален");
pictureBox.Image = _company.Show();
}
else
{
MessageBox.Show("Не удалось удалить объект");
}
}
private void ButtonGoToTest_Click(object sender, EventArgs e)
{
if (_company == null)
{
return;
}
DrawningShip? ship = null;
int counter = 100;
while (ship == null)
{
ship = _company.GetRandomObject();
counter--;
if (counter <= 0)
{
break;
}
}
if (ship == null)
{
return;
}
FormBattleship form = new()
{
SetShip = ship
};
form.ShowDialog();
}
private void ButtonRefresh_Click(object sender, EventArgs e)
{
if (_company == null)
{
return;
}
pictureBox.Image = _company.Show();
}
private void ButtonAddBattleship_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningBattleship));
private void buttonAddShip_Click_1(object sender, EventArgs e) => CreateObject(nameof(DrawningShip));
}

View File

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

View File

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.MovementStrategy;
/// <summary>
/// Класс-стратегия перемещения объекта
/// </summary>
public abstract class AbstractStrategy
{
private IMoveableObject? _moveableObject;
private StrategyStatus _state = StrategyStatus.NotInit;
protected int FieldWidth { get; private set;}
protected int FieldHeight { get; private set;}
public StrategyStatus GetStatus() => _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>true - достигнута, false - не достигнута</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,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.MovementStrategy;
/// <summary>
/// Интерфейс для работы с перемещаемым объектом
/// </summary>
public interface IMoveableObject
{
/// <summary>
/// Получение координаты объекта
/// </summary>
ObjectParameters? GetObjectPosition { get; }
/// <summary>
/// Шаг объекта
/// </summary>
int GetStep { get; }
/// <summary>
/// Попытка переместить объект в указанном направлении
/// </summary>
/// <param name="direction">Направление</param>
/// <returns>true - успех перемещения, false - неудача перемещения</returns>
bool TryMoveObject(MovementDirection direction);
}

View File

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.MovementStrategy;
public class MoveToBorder : AbstractStrategy
{
protected override bool IsTargetDestination()
{
ObjectParameters? objParameters = GetObjectParameters;
if (objParameters == null)
{
return false;
}
return (objParameters.RightBorder - GetStep() <= FieldWidth && objParameters.RightBorder + GetStep() >= FieldWidth &&
objParameters.BottomBorder - GetStep() <= FieldHeight && objParameters.BottomBorder + GetStep() >= FieldHeight);
}
protected override void MoveToTarget()
{
ObjectParameters? objParameters = GetObjectParameters;
if (objParameters == null)
{
return;
}
int diffx = FieldWidth - objParameters.RightBorder;
if (diffx > GetStep())
{
MoveRight();
}
int diffy = FieldHeight - objParameters.BottomBorder;
if (diffy > GetStep())
{
MoveDown();
}
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.MovementStrategy;
public class MoveToCenter : AbstractStrategy
{
protected override bool IsTargetDestination()
{
ObjectParameters? objParameters = GetObjectParameters;
if (objParameters == null){
return false;
}
return (objParameters.ObjectMiddleHorizontal - GetStep() <= FieldWidth / 2 && objParameters.ObjectMiddleHorizontal + GetStep() >= FieldWidth / 2 &&
objParameters.ObjectMiddleVertical - GetStep() <= FieldHeight / 2 && objParameters.ObjectMiddleVertical + GetStep() >= FieldHeight / 2);
}
protected override void MoveToTarget()
{
ObjectParameters? objParameters = GetObjectParameters;
if (objParameters == null) {
return;
}
int diffx = objParameters.ObjectMiddleHorizontal - FieldWidth / 2;
if (Math.Abs(diffx) > GetStep()){
if (diffx > 0)
MoveLeft();
else
MoveRight();
}
int diffy = objParameters.ObjectMiddleVertical - FieldHeight / 2;
if (Math.Abs(diffy) > GetStep())
{
if (diffy > 0)
MoveUp();
else
MoveDown();
}
}
}

View File

@ -0,0 +1,54 @@
using Battleship.Drawnings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.MovementStrategy;
/// <summary>
/// Класс-реализация IMoveableObject с помощью DrawningShip
/// </summary>
public class MoveableShip : IMoveableObject
{
private readonly DrawningShip? _ship = null;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="drawningShip">Объект класса DrawningShip</param>
public MoveableShip(DrawningShip drawningShip)
{
_ship = drawningShip;
}
public ObjectParameters? GetObjectPosition
{
get
{
if (_ship == null || !_ship.GetPosX.HasValue || !_ship.GetPosY.HasValue)
return null;
return new ObjectParameters(_ship.GetPosX.Value, _ship.GetPosY.Value, _ship.GetWidth, _ship.GetHeight);
}
}
public int GetStep => (int)(_ship?.EntityShip?.Step ?? 0);
public bool TryMoveObject(MovementDirection direction)
{
if (_ship == null || _ship.EntityShip == null)
return false;
return _ship.MoveTransport(GetDirectionType(direction));
}
/// <summary>
/// Преобразование из DrawningShip
/// </summary>
/// <param name="direction"></param>
/// <returns></returns>
public 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.Unknown,
};
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.MovementStrategy;
/// <summary>
/// Направление перемещения
/// </summary>
public enum MovementDirection
{
/// <summary>
/// Вверх
/// </summary>
Up = 1,
/// <summary>
/// Вниз
/// </summary>
Down = 2,
/// <summary>
/// Вправо
/// </summary>
Right = 3,
/// <summary>
/// Влево
/// </summary>
Left = 4
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.MovementStrategy;
/// <summary>
/// Параметры-координаты объекта
/// </summary>
public class ObjectParameters
{
private readonly int _x;
private readonly int _y;
private readonly int _width;
private readonly int _height;
public int LeftBorder => _x;
public int TopBorder => _y;
public int RightBorder => _x + _width;
public int BottomBorder => _y + _height;
public int ObjectMiddleHorizontal => _x + _width / 2;
public int ObjectMiddleVertical => _y + _height / 2;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="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,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Battleship.MovementStrategy;
/// <summary>
/// Статус выполнения операции пермещения
/// </summary>
public enum StrategyStatus
{
/// <summary>
/// Готов к началу
/// </summary>
NotInit,
/// <summary>
/// В процессе
/// </summary>
InProgress,
/// <summary>
/// Выполнено
/// </summary>
Finish
}

View File

@ -11,7 +11,7 @@ namespace Battleship
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
Application.Run(new FormShipCollection());
}
}
}

View File

@ -0,0 +1,103 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Этот код создан программой.
// Исполняемая версия:4.0.30319.42000
//
// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае
// повторной генерации кода.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Battleship.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("Battleship.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 right_arrow {
get {
object obj = ResourceManager.GetObject("right-arrow", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap right_arrow_2 {
get {
object obj = ResourceManager.GetObject("right-arrow-2", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap right_arrow_3 {
get {
object obj = ResourceManager.GetObject("right-arrow-3", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Поиск локализованного ресурса типа System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap right_arrow_4 {
get {
object obj = ResourceManager.GetObject("right-arrow-4", 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="right-arrow-4" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\right-arrow-4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="right-arrow-2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\right-arrow-2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="right-arrow-3" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\right-arrow-3.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="right-arrow" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\right-arrow.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: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB