Skip to content

Commit 8c951aa

Browse files
author
Gabriel Derrien
committed
Added files
1 parent c5686a7 commit 8c951aa

23 files changed

+1579
-0
lines changed

.classpath

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
4+
<classpathentry kind="src" path="src"/>
5+
<classpathentry kind="output" path="bin"/>
6+
</classpath>

.project

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>M4202C-Maze_solver</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.eclipse.jdt.core.javanature</nature>
16+
</natures>
17+
</projectDescription>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
eclipse.preferences.version=1
2+
encoding//src/Maze.java=UTF-8

.settings/org.eclipse.jdt.core.prefs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
eclipse.preferences.version=1
2+
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3+
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
4+
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
5+
org.eclipse.jdt.core.compiler.compliance=1.8
6+
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
7+
org.eclipse.jdt.core.compiler.debug.localVariable=generate
8+
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
9+
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
10+
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
11+
org.eclipse.jdt.core.compiler.source=1.8

bin/AStarSolver$1.class

1.02 KB
Binary file not shown.

bin/AStarSolver$2.class

1.2 KB
Binary file not shown.

bin/AStarSolver.class

5.92 KB
Binary file not shown.

bin/BFS_Solver.class

4.9 KB
Binary file not shown.

bin/DFS_Solver.class

5.14 KB
Binary file not shown.

bin/Main.class

1.42 KB
Binary file not shown.

bin/Maze.class

7.37 KB
Binary file not shown.

bin/Node.class

1.65 KB
Binary file not shown.

bin/Square.class

2.88 KB
Binary file not shown.

data/lab.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
XOOOOX
2+
SOXOXX
3+
XOXOXX
4+
XOXOOE
5+
XOXXOX
6+
XOOOOX

data/lab_samuel.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
xxx_xx___xxxx
2+
__x____x_x___
3+
x_xxxx_x___xe
4+
x__x___x_xxxx
5+
xx___x_x____x
6+
xxxx___xx_xxx
7+
_____xxx____x
8+
sx_x___x_x__x
9+
xx_x_x_______
10+
_______xx_xxx
11+
_xx_xx_______
12+
__xxxx_xxxxxx

data/test.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-----------------e-
2+
--xxxxxxxxxxxx-----
3+
-------------x-----
4+
-------------x-----
5+
-------------x-----
6+
-------------------
7+
--s----------------

src/AStarSolver.java

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
import java.util.Comparator;
2+
import java.util.Iterator;
3+
import java.util.LinkedList;
4+
import java.util.PriorityQueue;
5+
import java.util.Queue;
6+
7+
public class AStarSolver
8+
{
9+
private Maze maze;
10+
private String result;
11+
private Queue<Square> openNodes;
12+
private Queue<Node<Square>> dynTreeNodes;
13+
private int nodesCounter;
14+
private int pathLength;
15+
16+
/*
17+
* Constructor
18+
* m: The maze to solve
19+
*/
20+
public AStarSolver(Maze m)
21+
{
22+
this.maze = m;
23+
this.result = "";
24+
this.openNodes = new PriorityQueue<Square>(new Comparator<Square>()
25+
{
26+
public int compare(Square s1, Square s2)
27+
{
28+
Double cs1 = s1.getF();
29+
Double cs2 = s2.getF();
30+
31+
if(cs1 > cs2)
32+
return 1;
33+
else if(cs1 == cs2)
34+
return 0;
35+
else
36+
return -1;
37+
}
38+
});
39+
this.dynTreeNodes = new PriorityQueue<Node<Square>>(new Comparator<Node<Square>>()
40+
{
41+
public int compare(Node<Square> s1, Node<Square> s2)
42+
{
43+
Double cs1 = s1.getContent().getF();
44+
Double cs2 = s2.getContent().getF();
45+
46+
if(cs1 > cs2)
47+
return 1;
48+
else if(cs1 == cs2)
49+
return 0;
50+
else
51+
return -1;
52+
}
53+
});
54+
}
55+
56+
/*
57+
* Solves the maze with the A* algorithm
58+
* manhattan: Set as true to use the MANHATTAN DISTANCE instead of EUCLIDEAN DISTANCE
59+
*/
60+
public void solve(boolean manhattan)
61+
{
62+
this.maze.initGrid(); //Re-init maze
63+
64+
Boolean endfound = false;
65+
this.nodesCounter = 0;
66+
this.pathLength = 0;
67+
68+
//Compute F value of Starting square
69+
if(manhattan)
70+
this.maze.getStart().calcManhattanH(this.maze.getEnd());
71+
else
72+
this.maze.getStart().calcEuclidH(this.maze.getEnd());
73+
74+
this.maze.getStart().calcF();
75+
76+
//Init data structures
77+
this.openNodes.clear(); //Clear openNodes Queue
78+
this.openNodes.offer(maze.getStart()); //Adding the first node (Start node) (G is at 0, Start to Start = 0)
79+
this.maze.closedNodes.clear(); //Clear closedNodes
80+
81+
//Init Tree nodes
82+
this.dynTreeNodes.clear();
83+
this.dynTreeNodes.offer(new Node<Square>(this.maze.getStart()));
84+
Node<Square> revertedTree = null;
85+
86+
//Measure run time
87+
long startTime = System.currentTimeMillis();
88+
89+
while(!endfound)
90+
{
91+
if(this.openNodes.isEmpty())
92+
break;
93+
94+
else
95+
{
96+
Square current = this.openNodes.remove();
97+
98+
if(current.getCol() == this.maze.getEnd().getCol() && current.getLine() == this.maze.getEnd().getLine())
99+
endfound = true;
100+
101+
else
102+
{
103+
revertedTree = this.dynTreeNodes.remove();
104+
105+
LinkedList<Square> nexts = this.getNextSquares(current, manhattan);
106+
this.maze.closedNodes.add(current);
107+
108+
Iterator<Square> it = nexts.iterator();
109+
while(it.hasNext())
110+
{
111+
Square neighbor = it.next();
112+
113+
if(this.maze.closedNodes.contains(neighbor))
114+
continue; //Ignore if already evaluated
115+
else
116+
{
117+
if(!this.openNodes.contains(neighbor))
118+
{
119+
this.openNodes.offer(neighbor);
120+
this.nodesCounter++;
121+
122+
Node<Square> temp = new Node<Square>(neighbor);
123+
temp.setFather(revertedTree);
124+
this.dynTreeNodes.offer(temp);
125+
}
126+
}
127+
}
128+
}
129+
}
130+
}
131+
long endTime = System.currentTimeMillis();
132+
133+
this.setResult(endfound, manhattan, endTime - startTime);
134+
}
135+
136+
/*
137+
* Sets the result in this format :
138+
* - Path trace
139+
* - Path length
140+
* - Number of nodes created
141+
* - The maze with the path written
142+
*
143+
* PRIVATE: This method must be called only at the end of the solve method. Any other call may throw errors.
144+
*/
145+
private void setResult(boolean success, boolean manhattan, long time)
146+
{
147+
if(this.maze.unicodeIsTheNewBlack())
148+
{
149+
if(manhattan)
150+
this.result = " ___ __ ___ __ __ __ \r\n" +
151+
" / | __/|_ / |/ /___ _____ / /_ ____ _/ /_/ /_____ _____ \r\n" +
152+
" / /| || / ______ / /|_/ / __ `/ __ \\/ __ \\/ __ `/ __/ __/ __ `/ __ \\\r\n" +
153+
" / ___ /_ __| /_____/ / / / / /_/ / / / / / / / /_/ / /_/ /_/ /_/ / / / /\r\n" +
154+
"/_/ |_||/ /_/ /_/\\__,_/_/ /_/_/ /_/\\__,_/\\__/\\__/\\__,_/_/ /_/ \n";
155+
else
156+
this.result = " ___ ______ ___ __\r\n" +
157+
" / | __/|_ / ____/_ _______/ (_)___/ /\r\n" +
158+
" / /| || / ______ / __/ / / / / ___/ / / __ / \r\n" +
159+
" / ___ /_ __| /_____/ / /___/ /_/ / /__/ / / /_/ / \r\n" +
160+
"/_/ |_||/ /_____/\\__,_/\\___/_/_/\\__,_/ \n";
161+
}
162+
else
163+
{
164+
this.result = "/*********************/\nA* ALGORITHM";
165+
if(manhattan)
166+
this.result += " - MANHATTAN DISTANCE\n";
167+
else
168+
this.result += " - EUCLIDEAN DISTANCE\n";
169+
}
170+
171+
if(success)
172+
{
173+
Node<Square> revertedTree = this.dynTreeNodes.remove();
174+
this.maze.initGrid();
175+
176+
this.result += "Path: " + this.maze.getEnd().toString() + "(End) <- ";
177+
178+
revertedTree = revertedTree.getFather();
179+
this.pathLength++;
180+
181+
while(revertedTree.hasFather())
182+
{
183+
if(!revertedTree.getContent().equals(this.maze.getEnd()))
184+
{
185+
result += revertedTree.getContent().toString() + " <- ";
186+
this.maze.getGrid()[revertedTree.getContent().getLine()][revertedTree.getContent().getCol()].setAttribute("*");
187+
this.pathLength++;
188+
}
189+
revertedTree = revertedTree.getFather();
190+
}
191+
192+
this.result += this.maze.getStart().toString() + "(Start) \n" + "Path length: " + this.pathLength + "\nNumber of nodes created: " + this.nodesCounter + "\nExecution time: " + time/1000d + " seconds\n";
193+
this.result += this.maze.toString();
194+
}
195+
else
196+
{
197+
this.result += "Failed : Unable to go further and/or end is unreachable.";
198+
}
199+
}
200+
201+
/*
202+
* Get the next ("walkables") squares from the given square
203+
* c: Square from where to get the nexts squares
204+
* manhattan: If True, the distances computed will use the MANHATTAN DISTANCE instead of EUCLIDEAN DISTANCE
205+
*/
206+
public LinkedList<Square> getNextSquares(Square c, Boolean manhattan)
207+
{
208+
LinkedList<Square> res = new LinkedList<Square>();
209+
210+
//Get 4 next squares
211+
Square[] nextsquares = this.maze.getNexts(c);
212+
213+
Square start = this.maze.getStart();
214+
Square end = this.maze.getEnd();
215+
216+
for(Square s : nextsquares)
217+
{
218+
if(s != null && !s.isWall()) //Check if the square at next position is not null and if it's not a wall
219+
{
220+
//Calc G / H / F
221+
if(manhattan)
222+
{
223+
//Manhattan
224+
s.calcManhattanG(start);
225+
s.calcManhattanH(end);
226+
}
227+
else
228+
{
229+
//Euclid
230+
s.calcEuclidG(start);
231+
s.calcEuclidH(end);
232+
}
233+
234+
s.calcF(); //Calc F value
235+
236+
res.add(s); //Add the square
237+
}
238+
}
239+
return res;
240+
}
241+
242+
/*
243+
* Returns the result from the last solving
244+
*/
245+
public String getResult()
246+
{
247+
if(this.result == "")
248+
return "No resolution computed, use the solve method first";
249+
else
250+
return this.result;
251+
}
252+
}

0 commit comments

Comments
 (0)