private static IEnumerable <OffsetCoords> AddNextOpenNodes(
            OffsetCoords currentCell,
            Func <OffsetCoords, bool> availabilityDelegate)
        {
            var cubeCoords       = HexHelper.ConvertToCube(currentCell);
            var clockwiseOffsets = HexHelper.GetOffsetClockwise();

            foreach (var offset in clockwiseOffsets)
            {
                var neighbourCubeCoords = cubeCoords + offset;

                var neighbourCoords = HexHelper.ConvertToOffset(neighbourCubeCoords);

                var isAvailable = availabilityDelegate(neighbourCoords);
                if (isAvailable)
                {
                    yield return(neighbourCoords);
                }
            }
        }
        private static bool CheckAvailableFor7(OffsetCoords testCoords, Matrix <bool> matrix)
        {
            if (!matrix[testCoords.X, testCoords.Y])
            {
                return(false);
            }

            var neighbours = HexHelper.GetNeighbors(testCoords.X, testCoords.Y);

            foreach (var neighbour in neighbours)
            {
                if (neighbour.X >= matrix.Width || neighbour.Y >= matrix.Height)
                {
                    return(false);
                }

                if (!matrix.Items[neighbour.X, neighbour.Y])
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// Выполняет заливку области в поле шестиугольников с учётом размера в 7 узлов.
        /// </summary>
        /// <param name="matrix"> Поле шестиугольников. Будут заливаться ячейки со сзначением <b>true</b>. </param>
        /// <param name="point"> Точка, с которой начинается заливка. Должна указывать на ячейку со значением <b>true</b>. </param>
        /// <returns> Возвращает точки, которые были залиты. </returns>
        public static IEnumerable <OffsetCoords> FloodFill7(Matrix <bool> matrix, OffsetCoords point)
        {
            if (matrix is null)
            {
                throw new ArgumentNullException(nameof(matrix));
            }

            var snapshotCellmap = (bool[, ])matrix.Items.Clone();

            var regionPoints = new List <OffsetCoords>();

            var openPoints = new HashSet <OffsetCoords>
            {
                point
            };

            while (openPoints.Count > 0)
            {
                var currentCell = openPoints.First();
                openPoints.Remove(currentCell);

                var isInBound = IsInBounds(currentCell, matrix.Width, matrix.Height);

                if (!isInBound)
                {
                    // Если текущая точка указывает за край карты, то не пытаемся её заливать.
                    // Пропускаем.
                    continue;
                }

                if (!snapshotCellmap[currentCell.X, currentCell.Y])
                {
                    // Заливаем только живые клетки.
                    // Мертвые клетки являются границей, они не попадают в заливку.
                    continue;
                }

                regionPoints.Add(currentCell);
                snapshotCellmap[currentCell.X, currentCell.Y] = false;

                var cubeCoords       = HexHelper.ConvertToCube(currentCell);
                var clockwiseOffsets = HexHelper.GetOffsetClockwise();

                foreach (var offset in clockwiseOffsets)
                {
                    var neighbourCubeCoords = cubeCoords + offset;

                    var neighbourCoords = HexHelper.ConvertToOffset(neighbourCubeCoords);

                    if (!openPoints.Contains(neighbourCoords))
                    {
                        var isAvailbleFor7 = CheckAvailableFor7(neighbourCoords, matrix);
                        if (isAvailbleFor7)
                        {
                            openPoints.Add(neighbourCoords);
                        }
                    }
                }
            }

            return(regionPoints);
        }