diff --git a/.gitignore b/.gitignore index ec6cb9f..3e21425 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ src/tmp node_modules/ obj/ -out/ \ No newline at end of file +out/ +/src/Client/RobotController/.vs +/.vs diff --git a/src/Pathfinder/AStarPathfinding.sln b/src/Pathfinder/AStarPathfinding.sln new file mode 100644 index 0000000..ae00c25 --- /dev/null +++ b/src/Pathfinder/AStarPathfinding.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AStarPathfinding", "AStarPathfinding\AStarPathfinding.csproj", "{97647F1E-1A0A-444D-A437-A809F9EB855F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {97647F1E-1A0A-444D-A437-A809F9EB855F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97647F1E-1A0A-444D-A437-A809F9EB855F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97647F1E-1A0A-444D-A437-A809F9EB855F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97647F1E-1A0A-444D-A437-A809F9EB855F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/Pathfinder/AStarPathfinding/AStarPathfinding.csproj b/src/Pathfinder/AStarPathfinding/AStarPathfinding.csproj new file mode 100644 index 0000000..ac6f6a3 --- /dev/null +++ b/src/Pathfinder/AStarPathfinding/AStarPathfinding.csproj @@ -0,0 +1,59 @@ + + + + + Debug + AnyCPU + {97647F1E-1A0A-444D-A437-A809F9EB855F} + Exe + Properties + AStarPathfinding + AStarPathfinding + v4.8 + 512 + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Pathfinder/AStarPathfinding/App.config b/src/Pathfinder/AStarPathfinding/App.config new file mode 100644 index 0000000..4bfa005 --- /dev/null +++ b/src/Pathfinder/AStarPathfinding/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/Pathfinder/AStarPathfinding/Program.cs b/src/Pathfinder/AStarPathfinding/Program.cs new file mode 100644 index 0000000..9efb94d --- /dev/null +++ b/src/Pathfinder/AStarPathfinding/Program.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AStarPathfinding +{ + class Location + { + public int X; + public int Y; + public int F; + public int G; + public int H; + public Location Parent; + } + + class Program + { + static void Main(string[] args) + { + Console.Title = "A* Pathfinding"; + + // draw map + + string[] map = new string[] + { + "+------+", + "| |", + "|A X |", + "|XXX |", + "| X |", + "| B |", + "| |", + "+------+", + }; + + foreach (var line in map) + Console.WriteLine(line); + + // algorithm + + Location current = null; + var start = new Location { X = 1, Y = 2 }; + var target = new Location { X = 2, Y = 5 }; + var openList = new List(); + var closedList = new List(); + int g = 0; + + // start by adding the original position to the open list + openList.Add(start); + + while (openList.Count > 0) + { + // get the square with the lowest F score + var lowest = openList.Min(l => l.F); + current = openList.First(l => l.F == lowest); + + // add the current square to the closed list + closedList.Add(current); + + // show current square on the map + Console.SetCursorPosition(current.X, current.Y); + Console.Write('.'); + Console.SetCursorPosition(current.X, current.Y); + System.Threading.Thread.Sleep(1000); + + // remove it from the open list + openList.Remove(current); + + // if we added the destination to the closed list, we've found a path + if (closedList.FirstOrDefault(l => l.X == target.X && l.Y == target.Y) != null) + break; + + var adjacentSquares = GetWalkableAdjacentSquares(current.X, current.Y, map); + g++; + + foreach(var adjacentSquare in adjacentSquares) + { + // if this adjacent square is already in the closed list, ignore it + if (closedList.FirstOrDefault(l => l.X == adjacentSquare.X + && l.Y == adjacentSquare.Y) != null) + continue; + + // if it's not in the open list... + if (openList.FirstOrDefault(l => l.X == adjacentSquare.X + && l.Y == adjacentSquare.Y) == null) + { + // compute its score, set the parent + adjacentSquare.G = g; + adjacentSquare.H = ComputeHScore(adjacentSquare.X, adjacentSquare.Y, target.X, target.Y); + adjacentSquare.F = adjacentSquare.G + adjacentSquare.H; + adjacentSquare.Parent = current; + + // and add it to the open list + openList.Insert(0, adjacentSquare); + } + else + { + // test if using the current G score makes the adjacent square's F score + // lower, if yes update the parent because it means it's a better path + if (g + adjacentSquare.H < adjacentSquare.F) + { + adjacentSquare.G = current.G + 1; + adjacentSquare.F = adjacentSquare.G + adjacentSquare.H; + adjacentSquare.Parent = current; + } + } + } + } + + // assume path was found; let's show it + while (current != null) + { + Console.SetCursorPosition(current.X, current.Y); + Console.Write('_'); + Console.SetCursorPosition(current.X, current.Y); + current = current.Parent; + System.Threading.Thread.Sleep(1000); + } + + // end + + Console.ReadLine(); + } + + static List GetWalkableAdjacentSquares(int x, int y, string[] map) + { + var proposedLocations = new List() + { + new Location { X = x, Y = y - 1 }, + new Location { X = x, Y = y + 1 }, + new Location { X = x - 1, Y = y }, + new Location { X = x + 1, Y = y }, + }; + + return proposedLocations.Where(l => map[l.Y][l.X] == ' ' || map[l.Y][l.X] == 'B').ToList(); + } + + static int ComputeHScore(int x, int y, int targetX, int targetY) + { + return Math.Abs(targetX - x) + Math.Abs(targetY - y); + } + } +} diff --git a/src/Pathfinder/AStarPathfinding/Properties/AssemblyInfo.cs b/src/Pathfinder/AStarPathfinding/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4d824f2 --- /dev/null +++ b/src/Pathfinder/AStarPathfinding/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AStarPathfinding")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AStarPathfinding")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("41c6c38d-e6f0-4437-b8a8-fa0a8ea19eab")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Pathfinder/AStarPathfinding/bin/Debug/AStarPathfinding.exe b/src/Pathfinder/AStarPathfinding/bin/Debug/AStarPathfinding.exe new file mode 100644 index 0000000..692050c Binary files /dev/null and b/src/Pathfinder/AStarPathfinding/bin/Debug/AStarPathfinding.exe differ diff --git a/src/Pathfinder/AStarPathfinding/bin/Debug/AStarPathfinding.exe.config b/src/Pathfinder/AStarPathfinding/bin/Debug/AStarPathfinding.exe.config new file mode 100644 index 0000000..4bfa005 --- /dev/null +++ b/src/Pathfinder/AStarPathfinding/bin/Debug/AStarPathfinding.exe.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/Pathfinder/AStarPathfinding/bin/Debug/AStarPathfinding.pdb b/src/Pathfinder/AStarPathfinding/bin/Debug/AStarPathfinding.pdb new file mode 100644 index 0000000..5b97d58 Binary files /dev/null and b/src/Pathfinder/AStarPathfinding/bin/Debug/AStarPathfinding.pdb differ