Морской бой. Проверка убитых кораблей - 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);
    }
}

Оцени полезность:

8   голосов , оценка 3.75 из 5