Морской бой. Проверка убитых кораблей - C#
Формулировка задачи:
Всем привет. Задача такова: дана матрица, в ней надо подсчитать сколько кораблей каждого типа было убито. Для обозначения 0 - ячейка пуста, 1 - нетронутый корабль и -1 - подбитый кораблей.
Пытаюсь как это решить, но что-то не выходит
Пока что проверяет только корабли, которые располагаются горизонтально и то, не очень-то и работает. Может кто-то подскажет как лучше это реализовать?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static bool[,] newPoint; //Копия матриы field. True - если уже был в этой клетке
static int count = 0; //Какой тип корабля. Соотвествено 1 - однопалубный
static int[] palub = { 0, 0, 0, 0 }; //Количество кораблей каждого типа(1 палоубного, 2-х и тд)
//Рекурсивно проверяю следеющию клетку от заданной
static bool CheckRight(int[,] field, int i, int j)
{
if (field[i, j] == 0)
return true;
if (field[i, j] == 1)
return false;
if (j == field.GetLength(1))
return true;
newPoint[i, j] = true;
count++;
return CheckRight(field, i, j + 1);
}
static void Main(string[] args)
{
int[,] field = {
{-1, 1, 0, 0,-1, 0, 0, 1, 0, 0, },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, },
{ 0, 0,-1, 0, 0, 0, 1,-1,-1, 1, },
{ 0, 0,-1, 0, 0, 0, 0, 0, 0, 0, },
{-1, 0, 0, 0,-1, 0, 0, 0, 0, 0, },
{ 0, 0, 0, 0,-1, 0, 0, 0, 0, 0, },
{ 0, 0, 0, 0,-1, 0, 0,-1, 0, 0, },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
};
newPoint = new bool[field.GetLength(0), field.GetLength(1)];
for(int i = 0; i < field.GetLength(0) - 1; i++)
for (int j = 0; j < field.GetLength(1) - 1; j++)
{
//Если попалась ячейка с подбитым кораблем
//Проверяем не было ли до нее ячейки с 1
//Проверяем, что снизу и сверху 0
if (field[i, j] == -1)
{
if (j != 0 && i != 0 && i != field.GetLength(1))
if (field[i, j - 1] != 1 && field[i + 1, j] == 0 && field[i - 1, j] == 0)
if (CheckRight(field, i, j))
{
palub[count - 1] += 1;
count = 0;
}
if (i == 0 && j == 0)
if (field[i + 1, j] == 0)
if (CheckRight(field, i, j))
{
palub[count - 1] += 1;
count = 0;
}
if (i == field.GetLength(0) && j == 0)
if (field[i - 1, j] == 0)
if (CheckRight(field, i, j))
{
palub[count - 1] += 1;
count = 0;
}
if (i != 0 && j == 0)
if (field[i - 1, j] == 0 && field[i + 1, j] == 0 && field[i - 1, j] == 0)
if (CheckRight(field, i, j))
{
palub[count - 1] += 1;
count = 0;
}
if(i == 0 && j != 0)
if (field[i, j - 1] != 1 && field[i + 1, j] == 0)
if (CheckRight(field, i, j))
{
palub[count - 1] += 1;
count = 0;
}
}
}
Console.ReadKey();
}
}
}Решение задачи: «Морской бой. Проверка убитых кораблей»
textual
Листинг программы
class Program
{
static void Main()
{
int[,] Field = {
{-1, 1, 0, 0,-1, 0, 0, 1, 0, 0, },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, },
{ 0, 0,-1, 0, 0, 0, 1,-1,-1, 1, },
{ 0, 0,-1, 0, 0, 0, 0, 0, 0, 0, },
{-1, 0, 0, 0,-1, 0, 0, 0, 0, 0, },
{ 0, 0, 0, 0,-1, 0, 0, 0, 0, 0, },
{ 0, 0, 0, 0,-1, 0, 0,-1, 0, 0, },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
};
var Ships = Ship.TakeAll(Field).ToList();
Console.WriteLine("Число кораблей: " + Ships.Count);
foreach (var g in Ships.GroupBy(s => s.Length).OrderBy(g => g.Key))
Console.WriteLine("палубы: {0}, всего: {1}, убитых: {2}, подбитых: {3}",
g.Key, g.Count(), g.Count(s => s.IsDead), g.Count(s => s.IsBitten));
Console.ReadLine();
}
}
class Ship
{
public int Length; // Длина корабля
public int Hits; // Число выстрелов
public bool IsDead => Hits == Length; // Если полностью убит
public bool IsBitten => Hits > 0 && Hits < Length; // Если ранен
// Получает один корабль из заданной позиции
public static Ship TakeFrom(int[,] Fields, int Row, int Column)
{
int Rows = Fields.GetLength(0), Columns = Fields.GetLength(1);
// вычисляем направление - или вправо или вниз
int dx = Column + 1 < Columns && Fields[Row, Column + 1] != 0 ? 1 : 0;
int dy = Row + 1 < Rows && Fields[Row + 1, Column] != 0 ? 1 : 0;
// считаем число 1 и -1 вдоль направления (см выше)
int len = 0, hits = 0;
while (Row < Rows && Column < Columns && Fields[Row, Column] !=0)
{
if (Fields[Row, Column] == -1) hits++;
Fields[Row, Column] = 0;
len++; Row += dy; Column += dx;
}
return new Ship()
{
Length = len,
Hits = hits
};
}
// Получает все корабли
public static IEnumerable<Ship> TakeAll(int[,] Fields)
{
/* матрицу можно скопировать Array.Copy если нужна */
int Rows = Fields.GetLength(0), Columns = Fields.GetLength(1);
for (int r = 0; r < Rows; r++)
for (int c = 0; c < Columns; c++)
if (Fields[r, c] != 0)
yield return TakeFrom(Fields, r, c);
}
}