Add project files.
This commit is contained in:
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
.idea/
|
||||
.vs/
|
||||
bin/
|
||||
obj/
|
||||
Properties/
|
||||
App.config
|
||||
*.DotSettings.user
|
||||
53
AStar Pathfinding.csproj
Normal file
53
AStar Pathfinding.csproj
Normal file
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{A7DEE69C-2567-45A5-9694-795832A800E0}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>AStar_Pathfinding</RootNamespace>
|
||||
<AssemblyName>AStar Pathfinding</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
25
AStar Pathfinding.sln
Normal file
25
AStar Pathfinding.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29411.108
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AStar Pathfinding", "AStar Pathfinding.csproj", "{A7DEE69C-2567-45A5-9694-795832A800E0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A7DEE69C-2567-45A5-9694-795832A800E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A7DEE69C-2567-45A5-9694-795832A800E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A7DEE69C-2567-45A5-9694-795832A800E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A7DEE69C-2567-45A5-9694-795832A800E0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E46F2074-9111-48FB-8443-52F330576EAE}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
20
Input.txt
Normal file
20
Input.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
X X XX X X X X
|
||||
X XXX X X X X X
|
||||
X X X XXXXXXXXXXXXX XXXXXXX
|
||||
X XX XX X X X
|
||||
X XXX XX X X X
|
||||
X X X XXXX X
|
||||
X X E XXXXXX X
|
||||
X X X XXXXXXX X
|
||||
X XX XXXX X
|
||||
X X X
|
||||
X X X
|
||||
X X X
|
||||
X X XXXXXXXXXXXX X
|
||||
X X XXXXXXXXXXXXX X
|
||||
X XXXX XXXX X X XXXXX X
|
||||
X X X XXXXXS X X
|
||||
X X X X X X
|
||||
X X X X XX XX
|
||||
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
322
Program.cs
Normal file
322
Program.cs
Normal file
@@ -0,0 +1,322 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AStar_Pathfinding
|
||||
{
|
||||
public enum TypeOfNode { Start, Normal, End, Wall };
|
||||
|
||||
public readonly struct Coordinates
|
||||
{
|
||||
public readonly int X;
|
||||
public readonly int Y;
|
||||
|
||||
public Coordinates(int x, int y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
}
|
||||
|
||||
public class Node
|
||||
{
|
||||
public TypeOfNode TypeOfNode;
|
||||
//Vorherige Node / weg zu dieser Node
|
||||
public Node Previous;
|
||||
// X und Y position
|
||||
public Coordinates Coordinates;
|
||||
//G = Distance from starting node / H = Distance from end node / F = G + H
|
||||
public int G, H, F;
|
||||
|
||||
public Node(Coordinates coordinates)
|
||||
{
|
||||
Coordinates = coordinates;
|
||||
TypeOfNode = TypeOfNode.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
public class Map
|
||||
{
|
||||
private int Width { get; set; }
|
||||
private int Height { get; set; }
|
||||
private Node _start;
|
||||
private Node _end;
|
||||
private readonly Node[,] _map;
|
||||
|
||||
// Auch offene Liste gennant
|
||||
private readonly List<Node> _searching = new List<Node>();
|
||||
// Auch geschlossene Liste gennant
|
||||
public readonly List<Node> Searched = new List<Node>();
|
||||
|
||||
public Map(int wi, int he)
|
||||
{
|
||||
Width = wi;
|
||||
Height = he;
|
||||
|
||||
_map = new Node[wi, he];
|
||||
for (int i = 0; i < Width; i++)
|
||||
{
|
||||
for (int j = 0; j < Height; j++)
|
||||
{
|
||||
_map[i, j] = new Node(new Coordinates(i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
public void SetStart(Coordinates cor)
|
||||
{
|
||||
_map[cor.X, cor.Y].Coordinates = cor;
|
||||
_map[cor.X, cor.Y].TypeOfNode = TypeOfNode.Start;
|
||||
_start = _map[cor.X, cor.Y];
|
||||
}
|
||||
public void SetEnd(Coordinates cor)
|
||||
{
|
||||
_map[cor.X, cor.Y].Coordinates = cor;
|
||||
_map[cor.X, cor.Y].TypeOfNode = TypeOfNode.End;
|
||||
_end = _map[cor.X, cor.Y];
|
||||
}
|
||||
|
||||
public Node GetEnd()
|
||||
{
|
||||
return _end;
|
||||
}
|
||||
public void SetWalls(List<int[]> walls)
|
||||
{
|
||||
foreach (int[] t in walls)
|
||||
{
|
||||
_map[t[0], t[1]].TypeOfNode = TypeOfNode.Wall;
|
||||
}
|
||||
}
|
||||
|
||||
//Errechnet die G Cost / die Distanz zu dem Startpunkt
|
||||
private void CalculateGCost(int x, int y, Node previous)
|
||||
{
|
||||
int cost = 10;
|
||||
|
||||
if (_map[x, y].TypeOfNode == TypeOfNode.Start || _map[x, y].TypeOfNode == TypeOfNode.End) return;
|
||||
if (previous.Coordinates.X != x && previous.Coordinates.Y != y)
|
||||
{
|
||||
cost += 4;
|
||||
}
|
||||
|
||||
_map[x, y].G = previous.G + cost;
|
||||
_map[x, y].Previous = previous;
|
||||
}
|
||||
|
||||
//Errechnet für die ganze Karte die H Cost / die Distanz zu dem Endpunkt
|
||||
public void CalculateAllHCost()
|
||||
{
|
||||
for (int i = 0; i < Width; i++)
|
||||
{
|
||||
for (int j = 0; j < Height; j++)
|
||||
{
|
||||
CalculateHCost(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Errechnet für dieses eine Feld die H Cost / die Distanz zu dem Endpunkt
|
||||
private void CalculateHCost(int x, int y)
|
||||
{
|
||||
if (_map[x, y].TypeOfNode == TypeOfNode.End) return;
|
||||
//Wie weit das ende von dem jetzigen Punkt entfernt ist
|
||||
_map[x, y].H = (Math.Abs(_end.Coordinates.X - x) + Math.Abs(_end.Coordinates.Y - y)) * 10;
|
||||
}
|
||||
|
||||
//F Cost ist H Cost + G Cost
|
||||
private void CalculateFCost(int x, int y) => _map[x, y].F = _map[x, y].G + _map[x, y].H;
|
||||
public void StartPathFinding()
|
||||
{
|
||||
_searching.Add(_start);
|
||||
ShowMap();
|
||||
Search();
|
||||
}
|
||||
//Findet die benachbarten Nodes und fügt sie in die offene Liste hinzu, wenn sie dort nicht schon sind mit einem besseren vorgänger.
|
||||
private void PathFinding(int x, int y)
|
||||
{
|
||||
for (int i = -1; i < 2; i++)
|
||||
{
|
||||
for (int j = -1; j < 2; j++)
|
||||
{
|
||||
if (!((x + i >= 0 && x + i < Width) & (y + j >= 0 && y + j < Height))) continue;
|
||||
if (_map[x + i, y + j].TypeOfNode == TypeOfNode.Wall) continue;
|
||||
if (_map[x + i, y + j].G == 0 & _map[x + i, y + j].TypeOfNode != TypeOfNode.Start)
|
||||
{
|
||||
_map[x + i, y + j].Previous = _map[x, y];
|
||||
_searching.Add(_map[x + i, y + j]);
|
||||
}
|
||||
else if (_map[x + i, y + j].G > _map[x, y].G + (i == 0 && j == 0 ? 10 : 14))
|
||||
{
|
||||
_map[x + i, y + j].Previous = _map[x, y];
|
||||
var t = Searched.Find(
|
||||
item => item.Coordinates.X == x +
|
||||
i && item.Coordinates.Y == y + j);
|
||||
Searched.Remove(t);
|
||||
_searching.Add(_map[x + i, y + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Anweisungen wie der Weg gefunden wird
|
||||
private void Search()
|
||||
{
|
||||
Node node;
|
||||
do
|
||||
{
|
||||
foreach (var item in _searching)
|
||||
{
|
||||
CalculateGCost(item.Coordinates.X, item.Coordinates.Y, item.Previous);
|
||||
CalculateFCost(item.Coordinates.X, item.Coordinates.Y);
|
||||
}
|
||||
|
||||
//Sucht die niedrigste F Cost
|
||||
int lowestF = _searching.Min(c => c.F);
|
||||
//Sucht in der offenen Liste nach den Nodes mit der niedrigsten F Cost
|
||||
var nodes = _searching.FindAll(c => c.F == lowestF);
|
||||
//Sucht unter den niedrigsten F Cost Nodes nach der niedrigsten H Cost
|
||||
int lowestH = nodes.Min(c => c.H);
|
||||
//Wählt die Node mit der niedrigsten F und H Cost aus
|
||||
node = nodes.Find(c => c.H == lowestH);
|
||||
|
||||
//Sollte die Node zufälligerweise die End-Node sein, wird die Suche nach der End-Node abgebrochen
|
||||
if (node.TypeOfNode == TypeOfNode.End)
|
||||
break;
|
||||
|
||||
//Sucht für die Node mit der niedrigsten F und H Cost die Nachbarn und fügt sie der offenen Liste hinzu
|
||||
PathFinding(node.Coordinates.X, node.Coordinates.Y);
|
||||
//Entfernt die Node von der offenen Liste
|
||||
_searching.Remove(node);
|
||||
//und fügt sie der geschlossenen Liste hinzu
|
||||
Searched.Add(node);
|
||||
} while (_searching.Count != 0 && node.TypeOfNode != TypeOfNode.End);
|
||||
}
|
||||
public void ShowMap()
|
||||
{
|
||||
for (int i = 0; i < Width; i++)
|
||||
{
|
||||
for (int j = 0; j < Height; j++)
|
||||
{
|
||||
Console.SetCursorPosition(i, j);
|
||||
|
||||
switch (_map[i,j].TypeOfNode)
|
||||
{
|
||||
case TypeOfNode.Start:
|
||||
Console.ForegroundColor = ConsoleColor.Blue;
|
||||
break;
|
||||
case TypeOfNode.End:
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
break;
|
||||
default:
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
break;
|
||||
}
|
||||
|
||||
//Schreibt ein X wenn es sich bei dem Feld um eine Wand / das Ende / den Start handelt
|
||||
Console.WriteLine(_map[i, j].TypeOfNode == TypeOfNode.Wall |
|
||||
_map[i, j].TypeOfNode == TypeOfNode.End |
|
||||
_map[i, j].TypeOfNode == TypeOfNode.Start ? "X" : " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowPath(Node node)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
System.Threading.Thread.Sleep(100);
|
||||
Console.SetCursorPosition(node.Coordinates.X, node.Coordinates.Y);
|
||||
Console.BackgroundColor = ConsoleColor.White;
|
||||
Console.WriteLine("*");
|
||||
Console.BackgroundColor = ConsoleColor.Black;
|
||||
switch (node.TypeOfNode)
|
||||
{
|
||||
case TypeOfNode.Start:
|
||||
//Die Reihe ist fertig, es wird an das ende der Map gesetzt um weiter Infos
|
||||
//auf der Konsole auszugeben ohne die Karte zu überschreiben
|
||||
Console.SetCursorPosition(0, Height + 1);
|
||||
break;
|
||||
default:
|
||||
//Zeigt die nächste Node in der Reihe
|
||||
node = node.Previous;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
private static void Main()
|
||||
{
|
||||
Console.ReadKey(true);
|
||||
|
||||
int lineCount = 0;
|
||||
int longestLine = 0;
|
||||
string line;
|
||||
|
||||
List<int[]> walls = new List<int[]>();
|
||||
|
||||
Coordinates start = new Coordinates();
|
||||
Coordinates end = new Coordinates();
|
||||
|
||||
System.IO.StreamReader file =
|
||||
new System.IO.StreamReader(@"..\..\Input.txt");
|
||||
while ((line = file.ReadLine()) != null)
|
||||
{
|
||||
if (line.Length > longestLine)
|
||||
{
|
||||
longestLine = line.Length;
|
||||
}
|
||||
|
||||
int counter2 = 0;
|
||||
foreach (char x in line)
|
||||
{
|
||||
switch (x)
|
||||
{
|
||||
case 'X':
|
||||
walls.Add(new[] { counter2, lineCount });
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
start = new Coordinates(counter2, lineCount);
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
end = new Coordinates(counter2, lineCount);
|
||||
break;
|
||||
}
|
||||
counter2++;
|
||||
}
|
||||
lineCount++;
|
||||
}
|
||||
|
||||
var map = new Map(longestLine, lineCount);
|
||||
|
||||
map.SetStart(start);
|
||||
map.SetEnd(end);
|
||||
map.SetWalls(walls);
|
||||
|
||||
file.Dispose();
|
||||
var sw = new System.Diagnostics.Stopwatch();
|
||||
sw.Start();
|
||||
map.CalculateAllHCost();
|
||||
map.StartPathFinding();
|
||||
sw.Stop();
|
||||
|
||||
map.ShowMap();
|
||||
map.ShowPath(map.GetEnd());
|
||||
|
||||
Console.WriteLine("The Path took {0} ms to calculate", sw.ElapsedMilliseconds);
|
||||
|
||||
foreach (var node in map.Searched)
|
||||
{
|
||||
//Alle untersuchten Nodes werden einmal aufgeführt
|
||||
Console.WriteLine("{0,-6} : G = {1,-4}| H = {2,-4}| F = {3,-4}",
|
||||
node.Coordinates.X + ", " + node.Coordinates.Y, node.G, node.H, node.F);
|
||||
}
|
||||
|
||||
Console.ReadKey(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user