@@ -22,19 +22,9 @@ public static class AStar
2222 public static List < T > ? FindPath < T > (
2323 T start ,
2424 T goal ,
25- Func < T , IEnumerable < ( T node , double cost ) > > getNeighbors ,
25+ Func < T , IEnumerable < ( T Node , double Cost ) > > getNeighbors ,
2626 Func < T , T , double > heuristic ) where T : notnull
2727 {
28- if ( start == null )
29- {
30- throw new ArgumentNullException ( nameof ( start ) ) ;
31- }
32-
33- if ( goal == null )
34- {
35- throw new ArgumentNullException ( nameof ( goal ) ) ;
36- }
37-
3828 if ( getNeighbors == null )
3929 {
4030 throw new ArgumentNullException ( nameof ( getNeighbors ) ) ;
@@ -87,10 +77,10 @@ public static class AStar
8777 /// <param name="goal">Goal position (row, col).</param>
8878 /// <param name="allowDiagonal">Whether diagonal movement is allowed.</param>
8979 /// <returns>List of positions representing the path, or null if no path exists.</returns>
90- public static List < ( int row , int col ) > ? FindPathInGrid (
80+ public static List < ( int Row , int Col ) > ? FindPathInGrid (
9181 bool [ , ] grid ,
92- ( int row , int col ) start ,
93- ( int row , int col ) goal ,
82+ ( int Row , int Col ) start ,
83+ ( int Row , int Col ) goal ,
9484 bool allowDiagonal = false )
9585 {
9686 if ( grid == null )
@@ -101,77 +91,94 @@ public static class AStar
10191 int rows = grid . GetLength ( 0 ) ;
10292 int cols = grid . GetLength ( 1 ) ;
10393
104- if ( start . row < 0 || start . row >= rows || start . col < 0 || start . col >= cols )
94+ ValidateGridPosition ( grid , start , rows , cols , nameof ( start ) ) ;
95+ ValidateGridPosition ( grid , goal , rows , cols , nameof ( goal ) ) ;
96+
97+ IEnumerable < ( ( int Row , int Col ) Node , double Cost ) > GetNeighbors ( ( int Row , int Col ) pos )
10598 {
106- throw new ArgumentException ( "Start position is out of bounds." , nameof ( start ) ) ;
99+ return GetGridNeighbors ( pos , rows , cols , grid , allowDiagonal ) ;
107100 }
108101
109- if ( goal . row < 0 || goal . row >= rows || goal . col < 0 || goal . col >= cols )
102+ double ManhattanDistance ( ( int Row , int Col ) a , ( int Row , int Col ) b )
110103 {
111- throw new ArgumentException ( "Goal position is out of bounds." , nameof ( goal ) ) ;
104+ return Math . Abs ( a . Row - b . Row ) + Math . Abs ( a . Col - b . Col ) ;
112105 }
113106
114- if ( ! grid [ start . row , start . col ] )
107+ double EuclideanDistance ( ( int Row , int Col ) a , ( int Row , int Col ) b )
115108 {
116- throw new ArgumentException ( "Start position is not walkable." , nameof ( start ) ) ;
109+ int dr = a . Row - b . Row ;
110+ int dc = a . Col - b . Col ;
111+ return Math . Sqrt ( ( dr * dr ) + ( dc * dc ) ) ;
117112 }
118113
119- if ( ! grid [ goal . row , goal . col ] )
114+ Func < ( int Row , int Col ) , ( int Row , int Col ) , double > heuristic = allowDiagonal
115+ ? EuclideanDistance
116+ : ManhattanDistance ;
117+
118+ return FindPath ( start , goal , GetNeighbors , heuristic ) ;
119+ }
120+
121+ private static void ValidateGridPosition (
122+ bool [ , ] grid ,
123+ ( int Row , int Col ) position ,
124+ int rows ,
125+ int cols ,
126+ string paramName )
127+ {
128+ bool isOutOfBounds = position . Row < 0 || position . Row >= rows ;
129+ isOutOfBounds = isOutOfBounds || position . Col < 0 || position . Col >= cols ;
130+
131+ if ( isOutOfBounds )
120132 {
121- throw new ArgumentException ( "Goal position is not walkable ." , nameof ( goal ) ) ;
133+ throw new ArgumentException ( "Position is out of bounds ." , paramName ) ;
122134 }
123135
124- IEnumerable < ( ( int row , int col ) node , double cost ) > GetNeighbors ( ( int row , int col ) pos )
136+ if ( ! grid [ position . Row , position . Col ] )
125137 {
126- var neighbors = new List < ( ( int row , int col ) , double ) > ( ) ;
138+ throw new ArgumentException ( "Position is not walkable." , paramName ) ;
139+ }
140+ }
141+
142+ private static IEnumerable < ( ( int Row , int Col ) , double ) > GetGridNeighbors (
143+ ( int Row , int Col ) pos ,
144+ int rows ,
145+ int cols ,
146+ bool [ , ] grid ,
147+ bool allowDiagonal )
148+ {
149+ var neighbors = new List < ( ( int Row , int Col ) , double ) > ( ) ;
127150
128- // Cardinal directions (up, down, left, right)
129- var directions = new [ ]
151+ var directions = new [ ]
130152 {
131153 ( - 1 , 0 ) , ( 1 , 0 ) , ( 0 , - 1 ) , ( 0 , 1 ) ,
132- } ;
154+ } ;
133155
134- // Add diagonal directions if allowed
135- if ( allowDiagonal )
136- {
137- directions = directions . Concat ( new [ ]
156+ if ( allowDiagonal )
157+ {
158+ directions = directions . Concat ( new [ ]
138159 {
139160 ( - 1 , - 1 ) , ( - 1 , 1 ) , ( 1 , - 1 ) , ( 1 , 1 ) ,
140- } ) . ToArray ( ) ;
141- }
161+ } ) . ToArray ( ) ;
162+ }
142163
143- foreach ( var ( dr , dc ) in directions )
164+ foreach ( var ( dr , dc ) in directions )
144165 {
145- int newRow = pos . row + dr ;
146- int newCol = pos . col + dc ;
166+ int newRow = pos . Row + dr ;
167+ int newCol = pos . Col + dc ;
168+
169+ bool isInBounds = newRow >= 0 && newRow < rows ;
170+ isInBounds = isInBounds && newCol >= 0 && newCol < cols ;
147171
148- if ( newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols && grid [ newRow , newCol ] )
172+ if ( isInBounds && grid [ newRow , newCol ] )
149173 {
150174 // Cost is sqrt(2) for diagonal, 1 for cardinal
151- double cost = ( dr != 0 && dc != 0 ) ? Math . Sqrt ( 2 ) : 1.0 ;
175+ bool isDiagonal = dr != 0 && dc != 0 ;
176+ double cost = isDiagonal ? Math . Sqrt ( 2 ) : 1.0 ;
152177 neighbors . Add ( ( ( newRow , newCol ) , cost ) ) ;
153- }
154178 }
155-
156- return neighbors ;
157179 }
158180
159- double ManhattanDistance ( ( int row , int col ) a , ( int row , int col ) b )
160- {
161- return Math . Abs ( a . row - b . row ) + Math . Abs ( a . col - b . col ) ;
162- }
163-
164- double EuclideanDistance ( ( int row , int col ) a , ( int row , int col ) b )
165- {
166- int dr = a . row - b . row ;
167- int dc = a . col - b . col ;
168- return Math . Sqrt ( ( dr * dr ) + ( dc * dc ) ) ;
169- }
170-
171- // Use Euclidean distance for diagonal movement, Manhattan for cardinal only
172- var heuristic = allowDiagonal ? EuclideanDistance : ManhattanDistance ;
173-
174- return FindPath ( start , goal , GetNeighbors , heuristic ) ;
181+ return neighbors ;
175182 }
176183
177184 /// <summary>
0 commit comments