1- using System ;
21using System . Linq ;
32using System . Collections ;
43using System . Collections . Generic ;
@@ -14,8 +13,8 @@ public class PathfindingManager : MonoBehaviour
1413
1514 private readonly List < MapTile > mapTilesInScene = new ( ) ;
1615 private readonly List < MapTileNode > pathMapTileNodes = new ( ) ;
16+ private readonly List < MapTileNode > mapTileNodesWaitingForVisit = new ( ) ;
1717 private readonly List < IMapEditingElement > mapEditingElements = new ( ) ;
18- private readonly PriorityQueue < MapTileNode > priorityQueue = new ( ) ;
1918
2019 private MapTile startMapTile ;
2120 private MapTile destinationMapTile ;
@@ -59,7 +58,6 @@ private bool PathfindingWasStarted
5958 }
6059 }
6160
62- public float GetHeuristicValue ( Vector2 positionA , Vector2 positionB ) => heuristicManager != null ? heuristicManager . GetHeuristicValue ( positionA , positionB ) : 0f ;
6361 public bool DiagonalMovementIsEnabled ( ) => diagonalMovementIsEnabled ;
6462
6563 public void FindPath ( )
@@ -86,18 +84,6 @@ public void ClearResults()
8684 resultsWereClearedEvent ? . Invoke ( ) ;
8785 }
8886
89- public void OperateOnMapTileNodes ( MapTileNode mapTileNodeToStartFrom , Action < MapTileNode > action )
90- {
91- var currentMapTileNode = mapTileNodeToStartFrom ;
92-
93- while ( currentMapTileNode . Parent != null )
94- {
95- action ? . Invoke ( currentMapTileNode ) ;
96-
97- currentMapTileNode = currentMapTileNode . Parent ;
98- }
99- }
100-
10187 public void SetDiagonalMovementEnabled ( bool enabled )
10288 {
10389 diagonalMovementIsEnabled = enabled ;
@@ -202,7 +188,7 @@ private void ClearData()
202188 destinationMapTile = mapTilesInScene . FirstOrDefault ( mapTile => mapTile . GetTileType ( ) == MapTileType . Destination ) ;
203189
204190 ClearResults ( ) ;
205- priorityQueue . Clear ( ) ;
191+ mapTileNodesWaitingForVisit . Clear ( ) ;
206192 CreateConnectionsBetweenMapTileNodes ( ) ;
207193 }
208194
@@ -221,19 +207,28 @@ private void InitiatePathfinder()
221207 }
222208
223209 mapTilesInScene . ForEach ( mapTile => mapTile . GetMapTileNode ( ) . ResetData ( ) ) ;
224- startMapTile . SetWeightTo ( 0 ) ;
225- AddMapTileNodeToQueue ( startMapTile . GetMapTileNode ( ) ) ;
210+ InitiateStartMapTile ( ) ;
226211
227212 PathWasFound = false ;
228213 }
229214
215+ private void InitiateStartMapTile ( )
216+ {
217+ if ( startMapTile != null )
218+ {
219+ mapTileNodesWaitingForVisit . Add ( startMapTile . GetMapTileNode ( ) ) ;
220+ }
221+ }
222+
230223 private IEnumerator FindPathToDestination ( )
231224 {
232225 var simulationIsEnabled = simulationManager != null && simulationManager . SimulationIsEnabled ( ) ;
233226
234- while ( ! pathWasFound && priorityQueue . Count > 0 )
227+ while ( ! pathWasFound && mapTileNodesWaitingForVisit . Count > 0 )
235228 {
236- if ( VisitMapTileNodeIfNeeded ( priorityQueue . Dequeue ( ) ) && simulationIsEnabled )
229+ var currentMapTileNode = mapTileNodesWaitingForVisit . OrderBy ( mapTileNode => mapTileNode . GetMapTileNodeData ( ) . TotalCost ) . FirstOrDefault ( ) ;
230+
231+ if ( VisitMapTileNodeIfPossible ( currentMapTileNode ) && simulationIsEnabled )
237232 {
238233 yield return simulationManager . GetNextStepDelayDependingOnSimulationType ( ) ;
239234 }
@@ -242,16 +237,17 @@ private IEnumerator FindPathToDestination()
242237 PathfindingWasStarted = false ;
243238 }
244239
245- private bool VisitMapTileNodeIfNeeded ( MapTileNode mapTileNode )
240+ private bool VisitMapTileNodeIfPossible ( MapTileNode mapTileNode )
246241 {
247- if ( mapTileNode == null || mapTileNode . GetMapTileNodeType ( ) == MapTileNodeType . Visited || destinationMapTile == null )
242+ if ( mapTileNode == null )
248243 {
249244 return false ;
250245 }
251-
246+
252247 mapTileNode . SetTileNodeType ( MapTileNodeType . Visited ) ;
253- OperateOnMapTileNode ( mapTileNode ) ;
248+ mapTileNodesWaitingForVisit . Remove ( mapTileNode ) ;
254249 mapTileNodeWasVisitedEvent ? . Invoke ( mapTileNode ) ;
250+ OperateOnMapTileNode ( mapTileNode ) ;
255251
256252 return true ;
257253 }
@@ -269,7 +265,7 @@ private void OperateOnMapTileNode(MapTileNode mapTileNode)
269265 }
270266 else
271267 {
272- AddNeighboursOf ( mapTileNode ) ;
268+ OperateOnNeighboursOf ( mapTileNode ) ;
273269 }
274270 }
275271
@@ -282,40 +278,66 @@ private void FinishSearchingOn(MapTileNode mapTileNode)
282278
283279 PathWasFound = true ;
284280
285- OperateOnMapTileNodes ( mapTileNode , mapTileNode => pathMapTileNodes . Add ( mapTileNode ) ) ;
281+ DefinePathMapTileNodes ( mapTileNode ) ;
286282 pathMapTileNodes . ForEach ( mapTileNode => mapTileNode . SetTileNodeType ( MapTileNodeType . BelongingToPath ) ) ;
287283 pathWasFoundEvent ? . Invoke ( pathMapTileNodes ) ;
288284 }
289285
290- private void AddNeighboursOf ( MapTileNode mapTileNode )
286+ private void DefinePathMapTileNodes ( MapTileNode mapTileNodeToStartFrom )
291287 {
292- if ( mapTileNode == null )
293- {
294- return ;
295- }
288+ var currentMapTileNode = mapTileNodeToStartFrom ;
289+ var currentMapTileNodeData = currentMapTileNode . GetMapTileNodeData ( ) ;
296290
297- var neighbours = mapTileNode . GetNeighbours ( ) . Where ( neighbour => neighbour . GetMapTileNodeType ( ) != MapTileNodeType . Visited ) . ToList ( ) ;
291+ while ( currentMapTileNodeData . Parent != null )
292+ {
293+ pathMapTileNodes . Add ( currentMapTileNode ) ;
298294
299- neighbours ? . ForEach ( neighbour => SetupAndAddNeighbour ( neighbour , mapTileNode ) ) ;
295+ currentMapTileNode = currentMapTileNodeData . Parent ;
296+ currentMapTileNodeData = currentMapTileNode . GetMapTileNodeData ( ) ;
297+ }
300298 }
301299
302- private void SetupAndAddNeighbour ( MapTileNode neighbouringMapTile , MapTileNode parentMapTile )
300+ private void OperateOnNeighboursOf ( MapTileNode parentMapTileNode )
303301 {
304- neighbouringMapTile . Parent = parentMapTile ;
302+ if ( parentMapTileNode == null )
303+ {
304+ return ;
305+ }
306+
307+ var neighbours = parentMapTileNode . GetNeighbours ( ) . Where ( neighbour => neighbour . GetMapTileNodeType ( ) != MapTileNodeType . Visited ) . ToList ( ) ;
305308
306- AddMapTileNodeToQueue ( neighbouringMapTile ) ;
309+ neighbours . ForEach ( neighbour => OperateOnNeighbourIfNeeded ( parentMapTileNode , neighbour ) ) ;
307310 }
308311
309- private void AddMapTileNodeToQueue ( MapTileNode mapTileNode )
312+ private void OperateOnNeighbourIfNeeded ( MapTileNode parentMapTileNode , MapTileNode neighbouringMapTileNode )
310313 {
311- if ( mapTileNode == null )
314+ if ( parentMapTileNode == null || neighbouringMapTileNode == null )
312315 {
313316 return ;
314317 }
318+
319+ var totalCostToReachNeighbourFromParent = GetTotalCostToReachNeighbourFromParent ( parentMapTileNode , neighbouringMapTileNode ) ;
320+ var neighbourIsAlreadyWaitingForVisit = mapTileNodesWaitingForVisit . Contains ( neighbouringMapTileNode ) ;
321+ var neighbourMapTileNodeData = neighbouringMapTileNode . GetMapTileNodeData ( ) ;
315322
316- var mapTileNodeCost = mapTileNode . GetCostToReachTo ( destinationMapTile . GetMapTileNode ( ) ) ;
317- var mapTileNodeWithCost = new PriorityQueueElement < MapTileNode > ( mapTileNode , mapTileNodeCost ) ;
323+ if ( neighbourIsAlreadyWaitingForVisit && totalCostToReachNeighbourFromParent >= neighbourMapTileNodeData . RealValue )
324+ {
325+ return ;
326+ }
327+
328+ neighbourMapTileNodeData . SetValues ( parentMapTileNode , totalCostToReachNeighbourFromParent , heuristicManager != null ? heuristicManager . GetHeuristicValue ( neighbouringMapTileNode . GetPosition ( ) , destinationMapTile . GetMapTileNode ( ) . GetPosition ( ) ) : 0f ) ;
329+
330+ if ( ! neighbourIsAlreadyWaitingForVisit )
331+ {
332+ mapTileNodesWaitingForVisit . Add ( neighbouringMapTileNode ) ;
333+ }
334+ }
318335
319- priorityQueue . Enqueue ( mapTileNodeWithCost ) ;
336+ private float GetTotalCostToReachNeighbourFromParent ( MapTileNode parentMapTileNode , MapTileNode neighbouringMapTileNode )
337+ {
338+ var distanceToNeighbour = DistanceMethods . DistanceBetweenPositionsIsSingleAxis ( parentMapTileNode . GetPosition ( ) , neighbouringMapTileNode . GetPosition ( ) ) ? 1 : Mathf . Sqrt ( 2 ) ;
339+ var neighbourRealValue = distanceToNeighbour * neighbouringMapTileNode . Weight ;
340+
341+ return parentMapTileNode . GetMapTileNodeData ( ) . RealValue + neighbourRealValue ;
320342 }
321343}
0 commit comments