public static unsafe int GetShortestPathToOutsideLength(Point startPoint, Direction direction, PointsSet territory) { var queue = stackalloc int[GameParams.MapSize.Width * GameParams.MapSize.Height]; int queueHead = 0; int queueTail = 0; var visited = stackalloc bool[GameParams.MapSize.Width * GameParams.MapSize.Height]; var moves = stackalloc int[GameParams.MapSize.Width * GameParams.MapSize.Height]; visited[startPoint.X + startPoint.Y * GameParams.MapSize.Width] = true; moves[startPoint.X + startPoint.Y * GameParams.MapSize.Width] = 0; queue[queueHead++] = startPoint.X + startPoint.Y * GameParams.MapSize.Width; while (queueTail != queueHead) { int coord = queue[queueTail++]; var point = new Point(coord % GameParams.MapSize.Width, coord / GameParams.MapSize.Width); int currentPathLength = moves[coord]; foreach (var neighbor in point.GetNeighbors()) { int neighborCoord = neighbor.X + neighbor.Y * GameParams.MapSize.Width; if (!GameParams.MapSize.ContainsPoint(neighbor) || visited[neighborCoord] || currentPathLength == 0 && neighbor == startPoint.MoveLogic(direction.GetOpposite())) { continue; } if (!territory.Contains(neighbor)) { return(currentPathLength + 1); } visited[neighborCoord] = true; moves[neighborCoord] = currentPathLength + 1; queue[queueHead++] = neighborCoord; } } return(-1); }
public static PointsSet GetBoundary(this PointsSet pointsSet) { return(new PointsSet(pointsSet.Where(p => p.GetEightNeighbors().Any(n => !pointsSet.Contains(n))))); }