Beispiel #1
0
        public void GlobalSetup()
        {
            var map = new Generator(MapSize, MapSize)
                      .ConfigAndGenerateSafe(gen => gen.AddSteps(DefaultAlgorithms.RectangleMapSteps()))
                      .Context.GetFirst <IGridView <bool> >("WallFloor");

            var goalsBase =
                new LambdaTranslationGridView <bool, GoalState>(map, val => val ? GoalState.Clear : GoalState.Obstacle);

            var singleGoalView = new ArrayView <GoalState>(map.Width, map.Height);

            singleGoalView.ApplyOverlay(goalsBase);
            singleGoalView[map.Bounds().Center] = GoalState.Goal;

            _singleGoalMap = new GoalMap(singleGoalView, DistanceCalc);
            _singleFleeMap = new FleeMap(_singleGoalMap);

            var dualGoalView = new ArrayView <GoalState>(map.Width, map.Height);

            dualGoalView.ApplyOverlay(goalsBase);
            foreach (var rect in dualGoalView.Bounds().BisectVertically())
            {
                dualGoalView[rect.Center] = GoalState.Goal;
            }

            _dualGoalMap = new GoalMap(dualGoalView, DistanceCalc);
            _dualFleeMap = new FleeMap(_dualGoalMap);
        }
        public static ISettableGridView <bool> RectangleBooleanGrid(int width, int height)
        {
            ISettableGridView <bool> grid = new ArrayView <bool>(width, height);

            foreach (var pos in grid.Bounds().Expand(-1, -1).Positions())
            {
                grid[pos] = true;
            }

            return(grid);
        }
        public void GlobalSetup()
        {
            // Make two rectangles
            _rects = new ArrayView <bool>(Size, Size);
            _rects.Fill(true);

            var sects = _rects.Bounds().BisectVertically().ToArray();

            foreach (var rect in sects)
            {
                foreach (var pos in rect.PerimeterPositions())
                {
                    _rects[pos] = false;
                }
            }
        }
Beispiel #4
0
        private bool UpdatePathsOnlyUnchecked()
        {
            bool visitedNodes  = false;
            var  adjacencyRule = (AdjacencyRule)DistanceMeasurement;
            var  highVal       = (double)(BaseMap.Width * BaseMap.Height);

            _openEdges.Clear();
            _closedSet.SetAll(false);

            var mapBounds = _goalMap.Bounds();

            for (int i = 0; i < _walkable.Count; i++)
            {
                var point = _walkable[i];
                var state = BaseMap[point];
                if (state == GoalState.Clear)
                {
                    _goalMap[point] = highVal;
                }
                else
                {
                    _goalMap[point] = 0.0;
                    _openEdges.Enqueue(point);
                }
            }

            while (_openEdges.Count > 0)
            {
                var point = _openEdges.Dequeue();

                // Known to be not null since the else condition above will have assigned to it.
                var current = _goalMap[point] !.Value;
                for (int j = 0; j < adjacencyRule.DirectionsOfNeighborsCache.Length; j++)
                {
                    // We only want to process walkable, non-visited cells that are within the map
                    var openPoint = point + adjacencyRule.DirectionsOfNeighborsCache[j];
                    if (!mapBounds.Contains(openPoint))
                    {
                        continue;
                    }
                    if (_closedSet[openPoint.ToIndex(Width)] || BaseMap[openPoint] == GoalState.Obstacle)
                    {
                        continue;
                    }

                    // Known to be not null since it must be walkable.
                    var neighborValue = _goalMap[openPoint] !.Value;
                    var newValue      = current + DistanceMeasurement.Calculate(point, openPoint);
                    if (newValue < neighborValue)
                    {
                        _goalMap[openPoint] = newValue;
                        _openEdges.Enqueue(openPoint);
                    }
                }

                _closedSet[point.ToIndex(Width)] = true;
                visitedNodes = true;
            }

            Updated();
            return(visitedNodes);
        }
Beispiel #5
0
        private void Update()
        {
            int           width         = Width;
            AdjacencyRule adjacencyRule = _baseMap.DistanceMeasurement;

            var mapBounds = _goalMap.Bounds();

            var walkable = _baseMap.Walkable;

            for (int i = 0; i < walkable.Count; i++)
            {
                var point = walkable[i];

                // Value won't be null as null only happens for non-walkable squares
                var newPoint = _baseMap[point] !.Value * -Magnitude;
                _goalMap[point] = newPoint;

                _openSet.Enqueue(_nodes[point], newPoint);
            }

            _edgeSet.Clear();
            _closedSet.SetAll(false);

            while (_openSet.Count > 0) // Multiple runs are needed to deal with islands
            {
                var minNode = _openSet.Dequeue();
                _closedSet[minNode.Position.ToIndex(width)] = true;

                for (int i = 0; i < adjacencyRule.DirectionsOfNeighborsCache.Length; i++)
                {
                    var openPoint = minNode.Position + adjacencyRule.DirectionsOfNeighborsCache[i];
                    if (!mapBounds.Contains(openPoint))
                    {
                        continue;
                    }

                    if (!_closedSet[openPoint.ToIndex(width)] && _baseMap.BaseMap[openPoint] != GoalState.Obstacle)
                    {
                        _edgeSet.Enqueue(openPoint);
                    }
                }

                while (_edgeSet.Count > 0)
                {
                    var point      = _edgeSet.Dequeue();
                    var pointIndex = point.ToIndex(width);
                    if (!mapBounds.Contains(point) || _closedSet[pointIndex])
                    {
                        continue;
                    }

                    var current = _goalMap[point] !.Value; // Never added non-nulls so this is fine

                    for (int j = 0; j < adjacencyRule.DirectionsOfNeighborsCache.Length; j++)
                    {
                        var openPoint = point + adjacencyRule.DirectionsOfNeighborsCache[j];
                        if (!mapBounds.Contains(openPoint))
                        {
                            continue;
                        }
                        if (_closedSet[openPoint.ToIndex(width)] || _baseMap.BaseMap[openPoint] == GoalState.Obstacle)
                        {
                            continue;
                        }

                        var neighborValue = _goalMap[openPoint] !.Value; // Never added non-nulls so this is fine
                        var newValue      = current + _baseMap.DistanceMeasurement.Calculate(point, openPoint);
                        if (newValue < neighborValue)
                        {
                            _goalMap[openPoint] = newValue;
                            _openSet.UpdatePriority(_nodes[openPoint], newValue);
                            _edgeSet.Enqueue(openPoint);
                        }
                    }

                    _closedSet[pointIndex] = true;
                    _openSet.Remove(_nodes[point]);
                }
            }
        }