Пример #1
0
        private static bool CheckMapPassable(IEnumerable <OffsetCoords> currentCoords, OffsetCoords targetCoords)
        {
            var matrix = new Matrix <bool>(2002, 2002);

            foreach (var coords in currentCoords)
            {
                try
                {
                    var x = coords.X;
                    var y = coords.Y;
                    matrix.Items[x, y] = true;
                }
                catch (IndexOutOfRangeException)
                {
                    // Do nothing. The solution by using matrix is code smell.
                    // There is the catch block just for debug.
                }
            }

            // Закрываем проверяемый узел
            matrix.Items[targetCoords.X, targetCoords.Y] = false;

            // Не выбираем првоеряемую координату, как стартовую, потому что
            // она уже закрыта. Заливка от неё не пройдёт.
            var availableStartPoints = currentCoords.Where(x => x != targetCoords).ToArray();

            if (!availableStartPoints.Any())
            {
                // Если нет доступных координат для старта,
                // значит стартовая координата была единственной.
                // Её нельзя закрывать препятсвием.
                return(false);
            }

            var startPoint  = availableStartPoints.First(x => MapFactoryHelper.IsAvailableFor(matrix, x));
            var floodPoints = HexBinaryFiller.FloodFill(matrix, startPoint);

            foreach (var point in floodPoints)
            {
                matrix.Items[point.X, point.Y] = false;
            }

            foreach (var node in currentCoords)
            {
                var x = node.X;
                var y = node.Y;
                if (matrix.Items[x, y])
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #2
0
        public void FloodFill7_OneSize7Area_ReturnsOneCentralPoint()
        {
            // ARRANGE
            var matrix = new Matrix <bool>(10, 10);

            PlaceArea(4, 4, matrix);

            // ACT
            var regions = HexBinaryFiller.FloodFill7(matrix, new OffsetCoords(4, 4));

            // ASSERT
            regions.Should().BeEquivalentTo(new[] { new OffsetCoords(4, 4) });
        }
        private static IEnumerable <OffsetCoords> FloodFillRegions(Matrix <bool> matrix, OffsetCoords point)
        {
            var regionPoints = HexBinaryFiller.FloodFill(
                matrix,
                point);

            // В регионе должна быть хоть одна точка - стартовая.
            // Потому что заливка начинается с выбора незалитых точек.
            // Если этот метод не будет возращать точки, то будет бесконечный цикл.
            // Это критично, поэтому выбрасываем исключение.
            if (!regionPoints.Any())
            {
                throw new InvalidOperationException("Должна быть залита хотя бы одна точка.");
            }

            return(regionPoints);
        }
Пример #4
0
        public Task Validate(ISector sector, IServiceProvider scopeContainer)
        {
            // Проверяем проходимость карты.
            // Для этого убеждаемся, что из любого узла есть путь до любого другого.
            // При поиске пути:
            // - Считаем непроходимыме все статические объекты. Это декоратиные препятствия и сундуки.
            // - Игнорируем все перемещаемые. Например, монстров.

            return(Task.Run(() =>
            {
                var staticObjectManager = sector.StaticObjectManager;
                var containerNodes = staticObjectManager.Items.Select(x => x.Node);

                var allNonObstacleNodes = sector.Map.Nodes.OfType <HexNode>().ToArray();
                var allNonContainerNodes = allNonObstacleNodes.Where(x => !containerNodes.Contains(x));
                var allNodes = allNonContainerNodes.ToArray();

                var matrix = new Matrix <bool>(1000, 1000);
                foreach (var node in allNodes)
                {
                    var x = node.OffsetCoords.X;
                    var y = node.OffsetCoords.Y;
                    matrix.Items[x, y] = true;
                }

                var startNode = allNodes.First();
                var startPoint = startNode.OffsetCoords;
                var floodPoints = HexBinaryFiller.FloodFill(matrix, startPoint);

                foreach (var point in floodPoints)
                {
                    matrix.Items[point.X, point.Y] = false;
                }

                foreach (var node in allNodes)
                {
                    var x = node.OffsetCoords.X;
                    var y = node.OffsetCoords.Y;
                    if (matrix.Items[x, y])
                    {
                        throw new SectorValidationException($"Точка ({x}, {y}) недоступна для прохода.");
                    }
                }
            }));
        }
Пример #5
0
        private static bool CheckMap(ISector sector, HexNode containerNode)
        {
            var map = sector.Map;
            var currentStaticObjectsNodes = sector.StaticObjectManager.Items.Select(x => x.Node).OfType <HexNode>();

            var allNonObstacleNodes  = map.Nodes.OfType <HexNode>().ToArray();
            var allNonContainerNodes = allNonObstacleNodes.Where(x => !currentStaticObjectsNodes.Contains(x));
            var allNodes             = allNonContainerNodes.ToArray();

            var matrix = new Matrix <bool>(1000, 1000);

            foreach (var node in allNodes)
            {
                var x = node.OffsetCoords.X;
                var y = node.OffsetCoords.Y;
                matrix.Items[x, y] = true;
            }

            // Закрываем проверяемый узел
            matrix.Items[containerNode.OffsetCoords.X, containerNode.OffsetCoords.Y] = false;

            var startNode   = allNodes.First();
            var startPoint  = startNode.OffsetCoords;
            var floodPoints = HexBinaryFiller.FloodFill(matrix, startPoint);

            foreach (var point in floodPoints)
            {
                matrix.Items[point.X, point.Y] = false;
            }

            foreach (var node in allNodes)
            {
                var x = node.OffsetCoords.X;
                var y = node.OffsetCoords.Y;
                if (matrix.Items[x, y])
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #6
0
        private bool CheckMap(ISectorMap map, HexNode containerNode)
        {
            var containerNodes = _propContainerManager.Items.Select(x => x.Node);

            var allNonObstacleNodes  = map.Nodes.OfType <HexNode>().Where(x => !x.IsObstacle).ToArray();
            var allNonContainerNodes = allNonObstacleNodes.Where(x => !containerNodes.Contains(x));
            var allNodes             = allNonContainerNodes.ToArray();

            var matrix = new Matrix <bool>(1000, 1000);

            foreach (var node in allNodes)
            {
                var x = node.OffsetX;
                var y = node.OffsetY;
                matrix.Items[x, y] = true;
            }

            // Закрываем проверяемый узел
            matrix.Items[containerNode.OffsetX, containerNode.OffsetY] = false;

            var startNode   = allNodes.First();
            var startPoint  = new OffsetCoords(startNode.OffsetX, startNode.OffsetY);
            var floodPoints = HexBinaryFiller.FloodFill(matrix, startPoint);

            foreach (var point in floodPoints)
            {
                matrix.Items[point.X, point.Y] = false;
            }

            foreach (var node in allNodes)
            {
                var x = node.OffsetX;
                var y = node.OffsetY;
                if (matrix.Items[x, y])
                {
                    return(false);
                }
            }

            return(true);
        }