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; } } }
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); }
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]); } } }