2
2
3
3
import java .util .ArrayList ;
4
4
import java .util .LinkedList ;
5
+ import java .util .List ;
5
6
import java .util .PriorityQueue ;
6
7
7
8
public class Board implements SlidingBlock {
@@ -11,11 +12,7 @@ public class Board implements SlidingBlock {
11
12
int [] board ;
12
13
Node [] node ;
13
14
int startPosition ;
14
-
15
-
16
- //PriorityQueue<Node> openSet;
17
- //ArrayList<Node> closedSet;
18
-
15
+
19
16
public Board (int n ){
20
17
this .n = n ;
21
18
board = new int [n *n ];
@@ -31,8 +28,7 @@ public int[] solve(int[] start, int[] goal, int maxMoves) {
31
28
public int [] shortestPath (int startPosition ) {
32
29
this .startPosition = startPosition ;
33
30
initialiseSPNodes (startPosition );
34
- this .aStar (node [startPosition ], node [0 ], Integer .MAX_VALUE );
35
- return null ;
31
+ return this .aStar (node [startPosition ], node [0 ], Integer .MAX_VALUE );
36
32
}
37
33
38
34
@ Override
@@ -41,16 +37,7 @@ public void addWall(int positionI, int positionJ) {
41
37
42
38
}
43
39
44
- public void initialiseBoard (int startPos ){
45
- for (int i = 0 ; i < this .board .length ; i ++){
46
- if (i == startPos ){
47
- this .board [i ] = 0 ;
48
- } else {
49
- this .board [i ] = 1 ;
50
- }
51
- }
52
- }
53
-
40
+ // Initalise a node represention of the input array
54
41
public void initialiseSPNodes (int startPos ){
55
42
node = new SPNode [n *n ];
56
43
for (int i = 0 ; i < this .node .length ; i ++){
@@ -74,40 +61,69 @@ public void initialiseSPNodes(int startPos){
74
61
node [0 ].setN (n );
75
62
}
76
63
64
+ // prints the board as a matrix
77
65
public void printBoardToConsole (){
78
66
for (int i = 0 ; i < this .node .length ; i ++){
79
- System .out .print (this .node [i ].location +" " );
67
+ System .out .print (this .node [i ].location +" " );
68
+ if (this .node [i ].location < 10 ) System .out .print (" " );
80
69
if ((i +1 ) % n == 0 ){
81
70
System .out .print ("\n " );
82
71
}
83
72
}
84
73
}
85
74
75
+
76
+ /*
77
+ * Return the node located above, if there is one
78
+ */
86
79
public Node up (Node node ){
87
80
if (node .indexOfUp () < 0 ) return null ;
88
81
return this .node [node .indexOfUp ()];
89
82
}
83
+
84
+ /*
85
+ * Return the node located below, if there is one
86
+ */
90
87
public Node down (Node node ){
91
88
if (node .indexOfDown () < 0 ) return null ;
92
89
return this .node [node .indexOfDown ()];
93
90
}
91
+
92
+ /*
93
+ * Return the node located on the left, if there is one
94
+ */
94
95
public Node left (Node node ){
95
96
if (node .indexOfLeft () < 0 ) return null ;
96
97
return this .node [node .indexOfLeft ()];
97
98
}
99
+
100
+ /*
101
+ * Return the node located on the right, if there is one
102
+ */
98
103
public Node right (Node node ){
99
104
if (node .indexOfRight () < 0 ) return null ;
100
105
return this .node [node .indexOfRight ()];
101
106
}
102
107
108
+ /*
109
+ * Return the node from the stated position
110
+ */
103
111
public Node getNode (int pos ){
104
112
return node [pos ];
105
113
}
106
114
115
+ /*
116
+ * For the shortest path algo
117
+ *
118
+ * Return true if the node is in the first row
119
+ */
107
120
public boolean reachedGoal (Node node ){
108
121
return node .location < n ;
109
122
}
110
123
124
+ /*
125
+ * Add directly attached nodes to a list for processing in A*
126
+ */
111
127
public ArrayList <Node > getDirectlyAttachedNodes (Node n ){
112
128
ArrayList <Node > list = new ArrayList <Node >();
113
129
if (this .up (n ) != null ) list .add (this .up (n ));
@@ -117,56 +133,99 @@ public ArrayList<Node> getDirectlyAttachedNodes(Node n){
117
133
return list ;
118
134
}
119
135
120
-
136
+ /*
137
+ * A* Algo from psuedo code from wikipedia
138
+ * http://en.wikipedia.org/wiki/A*_search_algorithm
139
+ */
121
140
private int [] aStar (Node startNode , Node goalNode , int maxLength ) {
122
141
ArrayList <Node > closedSet = new ArrayList <Node >();
123
142
PriorityQueue <Node > openSet = new PriorityQueue <Node >();
124
- startNode .h = this .heuristicDistance (startNode , goalNode );
125
- int tempG ;
143
+
144
+ // When handling SPNodes
145
+ if (goalNode instanceof SPNode ){
146
+ goalNode = node [startNode .col ()];
147
+ }
148
+
149
+ int tentativeG ;
126
150
Node current ;
127
- boolean yInOpenSet ;
151
+ boolean tentativeBetter = false ;
152
+
153
+ //set details of start node
154
+ startNode .g = 0 ;
155
+ startNode .h = this .heuristicDistance (startNode , goalNode );
156
+ startNode .f = startNode .h ;
157
+
158
+ //add startNode to openset
159
+ openSet .add (startNode );
128
160
129
161
while (!openSet .isEmpty ()) {
130
162
current = openSet .poll ();
131
163
if (this .reachedGoal (current )){
132
- System .out .print ("done" );
164
+ reconstructPath (current );
165
+ return this .toIntArray (this .path );
133
166
}
134
167
closedSet .add (current );
135
168
if (current .g >= maxLength ) continue ;
136
- this .printBoardToConsole ();
137
169
for (Node attached : getDirectlyAttachedNodes (current )) {
138
170
if (closedSet .contains (attached )) continue ;
139
- tempG = current .g + 1 ;
140
-
141
- yInOpenSet = false ;
142
- for (Node thisState : openSet ) {
143
- if (attached .equals (thisState )) {
144
- attached = thisState ;
145
- yInOpenSet = true ;
146
- }
147
- }
148
- if (!yInOpenSet || tempG < attached .g ) {
149
- attached .parent = current ;
150
- attached .g = tempG ;
151
- attached .h = heuristicDistance (attached , goalNode );
152
- attached .f = attached .g + attached .h ;
153
- }
154
- if (!yInOpenSet && attached .f <= maxLength ) openSet .add (attached );
171
+ tentativeG = current .g + 1 ;
172
+ if (!(openSet .contains (attached ))){
173
+ tentativeBetter = true ;
174
+ }else if (tentativeG < attached .g ){
175
+ tentativeBetter = true ;
176
+ }else {
177
+ tentativeBetter = false ;
178
+ }
179
+ if (tentativeBetter ){
180
+ attached .parent = current ;
181
+ attached .g = tentativeG ;
182
+ attached .h = heuristicDistance (attached , goalNode );
183
+ attached .f = attached .g + attached .h ;
184
+ openSet .add (attached );
185
+ }
155
186
}
156
187
}
157
-
158
188
return null ;
159
189
}
160
190
191
+ /*
192
+ * Return the distance away in terms of the sum of the row and col dofferences
193
+ */
161
194
private int heuristicDistance (Node from , Node to ){
162
195
return (Math .abs (from .col () - to .col ()) + Math .abs (from .row () - to .row ()));
163
196
}
164
197
198
+ /*
199
+ * Reconstruct the path to the start, the data is kept in a list
200
+ */
165
201
public void reconstructPath (Node node ){
166
202
if (node .parent != null ){
167
203
reconstructPath (node .parent );
168
- } else {
204
+ }
169
205
path .add (node .location );
206
+ }
207
+
208
+ /*
209
+ * Return the Integer List as a primitive int array
210
+ * code found at taken from here http://stackoverflow.com/questions/960431/how-to-convert-listinteger-to-int-in-java
211
+ */
212
+ int [] toIntArray (List <Integer > list ) {
213
+ int [] ret = new int [list .size ()];
214
+ int i = 0 ;
215
+ for (Integer e : list )
216
+ ret [i ++] = e .intValue ();
217
+ return ret ;
218
+ }
219
+
220
+ /*
221
+ * Return array contents as a string
222
+ */
223
+ public String arrayToString (int [] theArray ){
224
+ if (theArray == null ) return "" ;
225
+ StringBuilder arrayAsString = new StringBuilder ();
226
+ for (int i = 0 ; i < theArray .length ; i ++){
227
+ arrayAsString .append (theArray [i ]+" " );
170
228
}
229
+ return arrayAsString .toString ();
171
230
}
172
231
}
0 commit comments