11package com .ai .astar ;
22
3+ import com .ai .astar .domain .Node ;
4+ import com .ai .astar .domain .searchstrategy .DiagonalMapChecker ;
5+ import com .ai .astar .domain .searchstrategy .HorizontalVerticalChecker ;
6+ import com .ai .astar .domain .searchstrategy .MapChecker ;
7+ import com .ai .astar .domain .searchstrategy .NoOpChecker ;
8+
39import java .util .*;
410
5- /**
6- * A Star Algorithm
7- *
8- * @author Marcelo Surriabre
9- * @version 2.1, 2017-02-23
10- */
1111public class AStar {
1212 private static final int DEFAULT_HV_COST = 10 ; // Horizontal - Vertical Cost
1313 private static final int DEFAULT_DIAGONAL_COST = 14 ;
14- private final int hvCost ;
15- private final int diagonalCost ;
1614 private final Node [][] searchArea ;
1715 private final PriorityQueue <Node > openList ;
1816 private final Set <Node > closedSet ;
1917 private final Node initialNode ;
2018 private final Node finalNode ;
19+ private final MapChecker diagonalsChecker ;
20+ private final MapChecker hvChecker ;
2121
22- public AStar (int rows , int cols , Node initialNode , Node finalNode , int hvCost , int diagonalCost ) {
23- this .hvCost = hvCost ;
24- this .diagonalCost = diagonalCost ;
22+ public AStar (int rows , int cols , Node initialNode , Node finalNode , int [][] blocksArray , boolean searchDiagonals ) {
2523 this .initialNode = initialNode ;
2624 this .finalNode = finalNode ;
2725 this .searchArea = new Node [rows ][cols ];
2826 this .openList = new PriorityQueue <>(Comparator .comparingInt (Node ::f ));
2927 initNodes ();
28+ initBlocks (blocksArray );
3029 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 );
30+ if (searchDiagonals ) {
31+ this .diagonalsChecker = new DiagonalMapChecker (searchArea , openList , closedSet , DEFAULT_DIAGONAL_COST );
32+ } else {
33+ this .diagonalsChecker = new NoOpChecker (null , null , null );
34+ }
35+ this .hvChecker = new HorizontalVerticalChecker (searchArea , openList , closedSet , DEFAULT_HV_COST );
3536 }
3637
3738 private void initNodes () {
@@ -44,10 +45,16 @@ private void initNodes() {
4445 }
4546 }
4647
47- public void initBlocks (int [][] blocksArray ) {
48+ private void initBlocks (int [][] blocksArray ) {
4849 for (int [] ints : blocksArray ) {
4950 int row = ints [0 ];
5051 int col = ints [1 ];
52+ if (row < 0 || row >= searchArea .length ) {
53+ continue ;
54+ }
55+ if (col < 0 || col >= searchArea [0 ].length ) {
56+ continue ;
57+ }
5158 this .searchArea [row ][col ].setAsBlocked ();
5259 }
5360 }
@@ -58,15 +65,15 @@ public List<Node> findPath() {
5865 Node currentNode = openList .poll ();
5966 closedSet .add (currentNode );
6067 if (isFinalNode (currentNode )) {
61- return generatePath (currentNode );
68+ return bestPath (currentNode );
6269 } else {
6370 addAdjacentNodes (currentNode );
6471 }
6572 }
6673 return new ArrayList <>();
6774 }
6875
69- private List <Node > generatePath (Node currentNode ) {
76+ private List <Node > bestPath (Node currentNode ) {
7077 List <Node > path = new ArrayList <>();
7178 path .add (currentNode );
7279 Node parent ;
@@ -78,71 +85,26 @@ private List<Node> generatePath(Node currentNode) {
7885 }
7986
8087 private void addAdjacentNodes (Node currentNode ) {
81- addAdjacentUpperRow (currentNode );
82- addAdjacentMiddleRow (currentNode );
83- addAdjacentLowerRow (currentNode );
84- }
85-
86- private void addAdjacentLowerRow (Node currentNode ) {
8788 int row = currentNode .row ();
8889 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 );
90+ addAdjacentUpperRow (currentNode , row , col );
91+ addAdjacentMiddleRow (currentNode , row , col );
92+ addAdjacentLowerRow (currentNode , row , col );
10093 }
10194
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- }
95+ private void addAdjacentLowerRow (Node currentNode , int row , int col ) {
96+ diagonalsChecker .checkNode (currentNode , col , row + 1 );
97+ hvChecker .checkNode (currentNode , col , row + 1 );
11198 }
11299
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 );
100+ private void addAdjacentMiddleRow (Node currentNode , int row , int col ) {
101+ hvChecker .checkNode (currentNode , col - 1 , row );
102+ hvChecker .checkNode (currentNode , col + 1 , row );
127103 }
128104
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- }
105+ private void addAdjacentUpperRow (Node currentNode , int row , int col ) {
106+ diagonalsChecker .checkNode (currentNode , col , row - 1 );
107+ hvChecker .checkNode (currentNode , col , row - 1 );
146108 }
147109
148110 private boolean isFinalNode (Node currentNode ) {
0 commit comments