Skip to content

Commit defc5c9

Browse files
authored
Merge pull request TheAlgorithms#19 from Laundry-96/master
Added A-Star algorithm for maze solving
2 parents 888f214 + fa8d459 commit defc5c9

File tree

2 files changed

+290
-0
lines changed

2 files changed

+290
-0
lines changed

searches/AStar/Location.cs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System;
2+
using System.Runtime.CompilerServices;
3+
4+
namespace AStar
5+
{
6+
public class Location : IEquatable<Location>
7+
{
8+
//
9+
// Properties
10+
//
11+
public int F
12+
{
13+
get;
14+
set;
15+
}
16+
17+
public int G
18+
{
19+
get;
20+
set;
21+
}
22+
23+
public int H
24+
{
25+
get;
26+
}
27+
28+
public Location Parent
29+
{
30+
get;
31+
set;
32+
}
33+
34+
public int X
35+
{
36+
get;
37+
}
38+
39+
public int Y
40+
{
41+
get;
42+
}
43+
44+
//
45+
// Constructors
46+
//
47+
public Location(int a, int b, Location p)
48+
{
49+
X = a;
50+
Y = b;
51+
Parent = p;
52+
53+
if (p == null)
54+
G = 0;
55+
56+
else
57+
G = p.G + 1;
58+
59+
60+
H = Program.ComputeHScore(X, Y);
61+
this.F = this.G + this.H;
62+
}
63+
64+
//
65+
// Methods
66+
//
67+
public bool Equals(Location other)
68+
{
69+
return this.X == other.X && this.Y == other.Y;
70+
}
71+
}
72+
}

searches/AStar/Program.cs

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace AStar
5+
{
6+
internal class Program
7+
{
8+
//Map to use
9+
public static string[] map = new string[] {
10+
"+------+",
11+
"| |",
12+
"|A X |",
13+
"|XXX |",
14+
"| X |",
15+
"| B |",
16+
"| |",
17+
"+------+"
18+
};
19+
20+
//Begin and end
21+
public static Location end;
22+
public static Location start;
23+
24+
//get valid adjacent steps to the current location
25+
public static List<Location> adjacentSteps(Location l)
26+
{
27+
List<Location> proposedLocations = new List<Location> {
28+
new Location (l.X - 1, l.Y, l),
29+
new Location (l.X, l.Y - 1, l),
30+
new Location (l.X + 1, l.Y, l),
31+
new Location (l.X, l.Y + 1, l)
32+
};
33+
34+
List<Location> actualLocations = new List<Location>();
35+
foreach (Location a in proposedLocations)
36+
{
37+
if (Program.map[a.Y][a.X] == ' ' || Program.map[a.Y][a.X] == 'B')
38+
{
39+
actualLocations.Add(a);
40+
}
41+
}
42+
43+
return actualLocations;
44+
}
45+
46+
//The one and only AStar algorithm
47+
public static List<Location> AStar()
48+
{
49+
//Going there
50+
List<Location> OpenedList = new List<Location>();
51+
52+
//Been there
53+
List<Location> ClosedList = new List<Location>();
54+
55+
Program.end = Program.FindEnd();
56+
Program.start = Program.FindStart();
57+
58+
OpenedList.Add(Program.start);
59+
60+
//While there are still nodes to visit
61+
while (OpenedList.Count > 0)
62+
{
63+
//Get the node that has the best chance
64+
Location bestChoice = Program.MinimumF(OpenedList);
65+
66+
//Mark as visited
67+
OpenedList.Remove(bestChoice);
68+
ClosedList.Add(bestChoice);
69+
70+
//Did we hit the end?
71+
if (bestChoice.X == Program.end.X && bestChoice.Y == Program.end.Y)
72+
{
73+
break;
74+
}
75+
76+
//Find the next moves
77+
List<Location> adjacentChoices = Program.adjacentSteps(bestChoice);
78+
foreach (Location l in adjacentChoices)
79+
{
80+
//Been there
81+
if (ClosedList.Contains(l))
82+
continue;
83+
84+
//Haven't gone there yet!
85+
if (!OpenedList.Contains(l))
86+
{
87+
OpenedList.Insert(0, l);
88+
}
89+
90+
//We are going to go there, but did we come from a better path?
91+
else
92+
{
93+
//Find the same location we had
94+
Location sameLocation = OpenedList.Find((Location a) => a.X == l.X && a.Y == l.Y);
95+
96+
//If our current location is better than the location we found earlier, update it with
97+
//our new location
98+
if (bestChoice.G + 1 + l.H < sameLocation.F)
99+
{
100+
OpenedList.Remove(sameLocation);
101+
OpenedList.Add(l);
102+
}
103+
}
104+
}
105+
}
106+
107+
//Path to return
108+
List<Location> result;
109+
110+
111+
if (!ClosedList.Contains(Program.end))
112+
result = null;
113+
114+
else
115+
result = ReconstructPath(ClosedList);
116+
117+
118+
return result;
119+
}
120+
121+
public static int ComputeHScore(int x, int y)
122+
{
123+
//If we created a new location for the end node,
124+
//don't worry about the Hueristic
125+
int result;
126+
127+
if (Program.end == null)
128+
result = 0;
129+
130+
else
131+
result = Math.Abs(x - Program.end.X) + Math.Abs(y - Program.end.Y);
132+
133+
return result;
134+
}
135+
136+
public static Location FindEnd()
137+
{
138+
Location result = null;
139+
for (int i = 0; i < Program.map.Length; i++)
140+
{
141+
bool flag = Program.map[i].Contains("B");
142+
if (flag)
143+
{
144+
result = new Location(Program.map[i].IndexOf('B'), i, null);
145+
return result;
146+
}
147+
}
148+
149+
return result;
150+
}
151+
152+
public static Location FindStart()
153+
{
154+
Location result = null;
155+
for (int i = 0; i < Program.map.Length; i++)
156+
{
157+
bool flag = Program.map[i].Contains("A");
158+
if (flag)
159+
{
160+
result = new Location(Program.map[i].IndexOf('A'), i, null);
161+
return result;
162+
}
163+
}
164+
165+
return result;
166+
}
167+
168+
//Get the best F score out of the list of locations
169+
public static Location MinimumF(List<Location> l)
170+
{
171+
Location min = l[0];
172+
foreach (Location current in l)
173+
{
174+
if (current.F < min.F)
175+
{
176+
min = current;
177+
}
178+
}
179+
return min;
180+
}
181+
182+
//Reconstructs the path from beginning to end
183+
public static List<Location> ReconstructPath(List<Location> ClosedList)
184+
{
185+
List<Location> path = new List<Location>();
186+
187+
Location location = ClosedList.Find(x => x.X == end.X && x.Y == end.Y);
188+
189+
path.Add(location);
190+
191+
while (location.Parent != null)
192+
{
193+
location = location.Parent;
194+
path.Insert(0, location);
195+
}
196+
197+
return path;
198+
}
199+
200+
public static void Main(string[] args)
201+
{
202+
List<Location> list = Program.AStar();
203+
204+
if (list == null)
205+
{
206+
Console.WriteLine("No solution!");
207+
}
208+
else
209+
{
210+
Console.WriteLine("Solution found as follows:");
211+
foreach (Location current in list)
212+
{
213+
Console.WriteLine(current.X + ", " + current.Y);
214+
}
215+
}
216+
}
217+
}
218+
}

0 commit comments

Comments
 (0)