fix(pathfinder): Implement robust forward insertion sort for PathfindCell::putOnSortedOpenList()#2432
Conversation
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Include/GameLogic/AIPathfind.h | Adds public declarations for forwardInsertionSortRetailCompatible (guarded by RETAIL_COMPATIBLE_PATHFINDING) and forwardInsertionSort. Both are exposed as public methods, which the PR justifies as groundwork for the upcoming skip list. No license, macro-guard, or nullptr issues found. |
| Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp | Refactors the old putOnSortedOpenList into two clearly-separated helpers. The new forwardInsertionSort is logically correct (all linked-list pointer updates are sound, equal-cost ordering matches the retail path). Two style issues: brace placement in forwardInsertionSort differs from the Allman style used in forwardInsertionSortRetailCompatible, and the explanatory @bugfix comment about the infinite-loop guard was dropped during the refactor. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["putOnSortedOpenList(list)"] --> B{RETAIL_COMPATIBLE\n_PATHFINDING?}
B -- No --> F["forwardInsertionSort(list)"]
B -- Yes --> C{s_useFixedPathfinding?}
C -- false --> D["forwardInsertionSortRetailCompatible(list)\n(with PATHFIND_CELLS_PER_FRAME guard)"]
C -- true --> F
F --> G{list.m_head\n== nullptr?}
G -- Yes --> H["Set as sole node\n(prevOpen=nullptr, nextOpen=nullptr)\nlist.m_head = this"]
G -- No --> I{totalCost <\nhead->totalCost?}
I -- Yes --> J["Prepend:\nupdate head->prevOpen,\nset nextOpen=old head,\nlist.m_head = this"]
I -- No --> K["Traverse: advance while\nnextOpen != null &&\nnextOpen->totalCost <= totalCost"]
K --> L["Insert after 'current':\nlink nextOpen / prevOpen\npointers"]
Last reviewed commit: cdce1d3
2bc038d to
6053149
Compare
|
|
||
| // Traverse the list to find correct position | ||
| PathfindCell* current = list.m_head; | ||
| while (current->m_info->m_nextOpen && current->m_info->m_nextOpen->m_totalCost <= m_info->m_totalCost) { |
There was a problem hiding this comment.
Note: This is a bit of a hard read, but it is correct.
It is somewhat confusing with the retail-version, but basically previousCell (retail) = current and currentCell (retail) = current->m_nextOpen
There was a problem hiding this comment.
Yes compared to the retail it seems more confusing, but it is also algorithmically more stable and doesn't require the second variable to be tracked.
head insertion is handled before the loop and any subsequent insertions are handled inside the loop.
There was a problem hiding this comment.
This design also makes extending this into a skip list easier as well without needing the multiple loop bodged earlier variants i created
6053149 to
cdce1d3
Compare
|
Tweaked based on feedback |
This PR implements a new and more robust forward insertion sort function.
This code is only retail compatible up to the point where a pathfinding crash would normally occur.
This is why the original code is maintained as a retail compatible pathway.
This code builds part of the foundation of the skip list that will be coming in further changes.