diff --git a/src/Client/RoutePlanner/Class1.cs b/src/Client/RoutePlanner/Class1.cs deleted file mode 100644 index 8d4d15f..0000000 --- a/src/Client/RoutePlanner/Class1.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace RoutePlanner -{ - public class Class1 - { - - } -} diff --git a/src/CoveragePathPlanner/CoveragePathPlanner.cs b/src/CoveragePathPlanner/CoveragePathPlanner.cs new file mode 100644 index 0000000..4cb4ef6 --- /dev/null +++ b/src/CoveragePathPlanner/CoveragePathPlanner.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Drawing; + +public class CoveragePathPlanner +{ + private int _width; + private int _height; + private List _cells; + + public CoveragePathPlanner(int width, int height) + { + _width = width; + _height = height; + _cells = new List(); + + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + _cells.Add(new Cell { X = x, Y = y, IsObstacle = false, IsVisited = false, Cost = double.MaxValue }); + } + } + } + + public List PlanPath(List obstacles) + { + // Add obstacles to the grid + foreach (Obstacle obstacle in obstacles) + { + for (int x = obstacle.X; x < obstacle.X + obstacle.Width; x++) + { + for (int y = obstacle.Y; y < obstacle.Y + obstacle.Height; y++) + { + _cells[x + y * _width].IsObstacle = true; + } + } + } + + // Initialize the start cell + Cell startCell = _cells[0]; + startCell.Cost = 0; + + // Create a priority queue to hold the cells to be processed + var queue = new PriorityQueue(); + queue.Enqueue(startCell, 0); + + while (queue.Count > 0) + { + // Dequeue the cell with the lowest cost + Cell currentCell = queue.Dequeue(); + + // If the cell is the goal, construct the path + if (currentCell.X == _width - 1 && currentCell.Y == _height - 1) + { + List path = new List(); + while (currentCell != null) + { + path.Add(new Point(currentCell.X, currentCell.Y)); + currentCell = currentCell.Parent; + } + return path; + } + + // Mark the cell as visited + currentCell.IsVisited = true; + + // Explore the neighbors + foreach (Cell neighbor in GetNeighbors(currentCell)) + { + if (!neighbor.IsVisited && !neighbor.IsObstacle) + { + // Calculate the cost of the neighbor + double cost = currentCell.Cost + 1; + if (cost < neighbor.Cost) + { + neighbor.Cost = cost; + neighbor.Parent = currentCell; + queue.Enqueue(neighbor, cost + Heuristic(neighbor)); + } + } + } + } + + // If no path is found, return an empty list + return new List(); + } + + private List GetNeighbors(Cell cell) + { + List neighbors = new List(); + + for (int x = -1; x <= 1; x++) + { + for (int y = -1; y <= 1; y++) + { + if (x == 0 && y == 0) continue; + + int neighborX = cell.X + x; + int neighborY = cell.Y + y; + + if (neighborX >= 0 && neighborX < _width && neighborY >= 0 && neighborY < _height) + { + neighbors.Add(_cells[neighborX + neighborY * _width]); + } + } + } + + return neighbors; + } + + private double Heuristic(Cell cell) + { + // Manhattan distance heuristic + return Math.Abs(cell.X - (_width - 1)) + Math.Abs(cell.Y - (_height - 1)); + } + + public List test() + { + CoveragePathPlanner planner = new CoveragePathPlanner(500, 500); + + List obstacles = new List + { + new Obstacle { X = 100, Y = 100, Width = 50, Height = 50 }, + new Obstacle { X = 200, Y = 200, Width = 100, Height = 100 }, + new Obstacle { X = 300, Y = 300, Width = 150, Height = 150 } + }; + + return planner.PlanPath(obstacles); + + } +} + +public class Obstacle +{ + public int X { get; set; } + public int Y { get; set; } + public int Width { get; set; } + public int Height { get; set; } +} + +public class Cell +{ + public int X { get; set; } + public int Y { get; set; } + public bool IsObstacle { get; set; } + public bool IsVisited { get; set; } + public double Cost { get; set; } + public Cell Parent { get; set; } +} diff --git a/src/Client/RoutePlanner/RoutePlanner.csproj b/src/CoveragePathPlanner/CoveragePathPlanner.csproj similarity index 100% rename from src/Client/RoutePlanner/RoutePlanner.csproj rename to src/CoveragePathPlanner/CoveragePathPlanner.csproj diff --git a/src/Client/RoutePlanner/RoutePlanner.sln b/src/CoveragePathPlanner/CoveragePathPlanner.sln similarity index 58% rename from src/Client/RoutePlanner/RoutePlanner.sln rename to src/CoveragePathPlanner/CoveragePathPlanner.sln index 04b0764..e268ce3 100644 --- a/src/Client/RoutePlanner/RoutePlanner.sln +++ b/src/CoveragePathPlanner/CoveragePathPlanner.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.9.34723.18 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RoutePlanner", "RoutePlanner.csproj", "{88355634-1B39-4827-BF30-7F28679F9F29}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoveragePathPlanner", "CoveragePathPlanner.csproj", "{19337BCA-6374-4DAE-90D4-38CF1D236D30}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +11,15 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {88355634-1B39-4827-BF30-7F28679F9F29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {88355634-1B39-4827-BF30-7F28679F9F29}.Debug|Any CPU.Build.0 = Debug|Any CPU - {88355634-1B39-4827-BF30-7F28679F9F29}.Release|Any CPU.ActiveCfg = Release|Any CPU - {88355634-1B39-4827-BF30-7F28679F9F29}.Release|Any CPU.Build.0 = Release|Any CPU + {19337BCA-6374-4DAE-90D4-38CF1D236D30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19337BCA-6374-4DAE-90D4-38CF1D236D30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19337BCA-6374-4DAE-90D4-38CF1D236D30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19337BCA-6374-4DAE-90D4-38CF1D236D30}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {34DA189D-30EE-4764-9FA7-E0231AAB553B} + SolutionGuid = {45198B26-DA54-465D-98BD-3568A4250889} EndGlobalSection EndGlobal