11package com .ai .astar ;
22
3+ import com .ai .astar .searchstrategy .DiagonalMapChecker ;
4+ import com .ai .astar .searchstrategy .HorizontalVerticalChecker ;
5+ import com .ai .astar .searchstrategy .MapChecker ;
6+ import com .ai .astar .searchstrategy .NoOpChecker ;
7+
38import java .util .*;
49
5- /**
6- * A Star Algorithm
7- *
8- * @author Marcelo Surriabre
9- * @version 2.1, 2017-02-23
10- */
1110public class AStar {
1211 private static final int DEFAULT_HV_COST = 10 ; // Horizontal - Vertical Cost
1312 private static final int DEFAULT_DIAGONAL_COST = 14 ;
14- private final int hvCost ;
15- private final int diagonalCost ;
1613 private final Node [][] searchArea ;
1714 private final PriorityQueue <Node > openList ;
1815 private final Set <Node > closedSet ;
1916 private final Node initialNode ;
2017 private final Node finalNode ;
18+ private final MapChecker diagonalsChecker ;
19+ private final MapChecker hvChecker ;
2120
22- public AStar (int rows , int cols , Node initialNode , Node finalNode , int hvCost , int diagonalCost ) {
23- this .hvCost = hvCost ;
24- this .diagonalCost = diagonalCost ;
21+ public AStar (int rows , int cols , Node initialNode , Node finalNode , boolean searchDiagonals ) {
2522 this .initialNode = initialNode ;
2623 this .finalNode = finalNode ;
2724 this .searchArea = new Node [rows ][cols ];
2825 this .openList = new PriorityQueue <>(Comparator .comparingInt (Node ::f ));
2926 initNodes ();
3027 this .closedSet = new HashSet <>();
31- }
32-
33- public AStar (int rows , int cols , Node initialNode , Node finalNode ) {
34- this (rows , cols , initialNode , finalNode , DEFAULT_HV_COST , DEFAULT_DIAGONAL_COST );
28+ if (searchDiagonals ) {
29+ this .diagonalsChecker = new DiagonalMapChecker (searchArea , openList , closedSet , DEFAULT_DIAGONAL_COST );
30+ } else {
31+ this .diagonalsChecker = new NoOpChecker (null , null , null );
32+ }
33+ this .hvChecker = new HorizontalVerticalChecker (searchArea , openList , closedSet , DEFAULT_HV_COST );
3534 }
3635
3736 private void initNodes () {
@@ -58,15 +57,15 @@ public List<Node> findPath() {
5857 Node currentNode = openList .poll ();
5958 closedSet .add (currentNode );
6059 if (isFinalNode (currentNode )) {
61- return generatePath (currentNode );
60+ return bestPath (currentNode );
6261 } else {
6362 addAdjacentNodes (currentNode );
6463 }
6564 }
6665 return new ArrayList <>();
6766 }
6867
69- private List <Node > generatePath (Node currentNode ) {
68+ private List <Node > bestPath (Node currentNode ) {
7069 List <Node > path = new ArrayList <>();
7170 path .add (currentNode );
7271 Node parent ;
@@ -78,71 +77,26 @@ private List<Node> generatePath(Node currentNode) {
7877 }
7978
8079 private void addAdjacentNodes (Node currentNode ) {
81- addAdjacentUpperRow (currentNode );
82- addAdjacentMiddleRow (currentNode );
83- addAdjacentLowerRow (currentNode );
84- }
85-
86- private void addAdjacentLowerRow (Node currentNode ) {
8780 int row = currentNode .row ();
8881 int col = currentNode .col ();
89- int lowerRow = row + 1 ;
90- if (lowerRow >= searchArea .length ) {
91- return ;
92- }
93- if (col - 1 >= 0 ) {
94- checkNode (currentNode , col - 1 , lowerRow , diagonalCost ); // Comment this line if diagonal movements are not allowed
95- }
96- if (col + 1 < searchArea [0 ].length ) {
97- checkNode (currentNode , col + 1 , lowerRow , diagonalCost ); // Comment this line if diagonal movements are not allowed
98- }
99- checkNode (currentNode , col , lowerRow , hvCost );
82+ addAdjacentUpperRow (currentNode , row , col );
83+ addAdjacentMiddleRow (currentNode , row , col );
84+ addAdjacentLowerRow (currentNode , row , col );
10085 }
10186
102- private void addAdjacentMiddleRow (Node currentNode ) {
103- int row = currentNode .row ();
104- int col = currentNode .col ();
105- if (col - 1 >= 0 ) {
106- checkNode (currentNode , col - 1 , row , hvCost );
107- }
108- if (col + 1 < searchArea [0 ].length ) {
109- checkNode (currentNode , col + 1 , row , hvCost );
110- }
87+ private void addAdjacentLowerRow (Node currentNode , int row , int col ) {
88+ diagonalsChecker .checkNode (currentNode , col , row + 1 );
89+ hvChecker .checkNode (currentNode , col , row + 1 );
11190 }
11291
113- private void addAdjacentUpperRow (Node currentNode ) {
114- int row = currentNode .row ();
115- int col = currentNode .col ();
116- int upperRow = row - 1 ;
117- if (upperRow < 0 ) {
118- return ;
119- }
120- if (col - 1 >= 0 ) {
121- checkNode (currentNode , col - 1 , upperRow , diagonalCost ); // Comment this if diagonal movements are not allowed
122- }
123- if (col + 1 < searchArea [0 ].length ) {
124- checkNode (currentNode , col + 1 , upperRow , diagonalCost ); // Comment this if diagonal movements are not allowed
125- }
126- checkNode (currentNode , col , upperRow , hvCost );
92+ private void addAdjacentMiddleRow (Node currentNode , int row , int col ) {
93+ hvChecker .checkNode (currentNode , col - 1 , row );
94+ hvChecker .checkNode (currentNode , col + 1 , row );
12795 }
12896
129- private void checkNode (Node currentNode , int col , int row , int cost ) {
130- Node adjacentNode = searchArea [row ][col ];
131- if (adjacentNode .isBlocked () || closedSet .contains (adjacentNode )) {
132- return ;
133- }
134- if (!openList .contains (adjacentNode )) {
135- adjacentNode .setNodeData (currentNode , cost );
136- openList .add (adjacentNode );
137- } else {
138- boolean changed = adjacentNode .checkBetterPath (currentNode , cost );
139- if (changed ) {
140- // Remove and Add the changed node, so that the PriorityQueue can sort again its
141- // contents with the modified "finalCost" value of the modified node
142- openList .remove (adjacentNode );
143- openList .add (adjacentNode );
144- }
145- }
97+ private void addAdjacentUpperRow (Node currentNode , int row , int col ) {
98+ diagonalsChecker .checkNode (currentNode , col , row - 1 );
99+ hvChecker .checkNode (currentNode , col , row - 1 );
146100 }
147101
148102 private boolean isFinalNode (Node currentNode ) {
0 commit comments