mirror of
https://github.com/Xevion/Paths.git
synced 2026-01-31 04:25:10 -06:00
fix start/end nodes not being properly handled in algorithm with ChangeController
essentially, the start and end nodes were being marked as Seen and/or Expanded instead of as Start/End nodes. The end node was easy to correct, but the start node was difficult without messing with the algorithm's performance (potentially), so I opted for a dirtier but probably more performant measure by just removing the Change value type.
This commit is contained in:
@@ -28,10 +28,8 @@ namespace Algorithms {
|
||||
ChangeController.AddChange(new Change(start.x, start.y, GridNodeType.Start, GridNodeType.Empty));
|
||||
ChangeController.AddChange(new Change(end.x, end.y, GridNodeType.End, GridNodeType.Empty));
|
||||
|
||||
|
||||
var startNode = new Node(start, true);
|
||||
var endNode = new Node(end, true);
|
||||
|
||||
Node startNode = _nodeGrid.Grid[start.x, start.y];
|
||||
Node endNode = _nodeGrid.Grid[end.x, end.y];
|
||||
|
||||
_path = new Stack<Node>();
|
||||
_openList = new List<Node>();
|
||||
@@ -41,11 +39,12 @@ namespace Algorithms {
|
||||
Node current = startNode;
|
||||
|
||||
// add start node to Open List
|
||||
startNode.State = NodeState.Open;
|
||||
_openList.Add(startNode);
|
||||
|
||||
while (_openList.Count != 0) {
|
||||
current = _openList.First();
|
||||
_openList.Remove(current);
|
||||
current = _openList[0];
|
||||
_openList.RemoveAt(0);
|
||||
|
||||
current.State = NodeState.Closed;
|
||||
ChangeController.AddChange(new Change(
|
||||
@@ -56,8 +55,6 @@ namespace Algorithms {
|
||||
if (current.Position == endNode.Position)
|
||||
break;
|
||||
|
||||
RecordState();
|
||||
|
||||
Node[] adjacentNodes = this._nodeGrid.GetAdjacentNodesArray(current);
|
||||
for (int i = 0; i < adjacentNodes.Length; i++) {
|
||||
Node node = adjacentNodes[i];
|
||||
@@ -68,7 +65,8 @@ namespace Algorithms {
|
||||
node.Cost = node.Weight + node.Parent.Cost;
|
||||
|
||||
node.State = NodeState.Open;
|
||||
ChangeController.AddChange(new Change(node.Position.x, node.Position.y, GridNodeType.Seen, GridNodeType.Empty));
|
||||
ChangeController.AddChange(new Change(node.Position.x, node.Position.y, GridNodeType.Seen,
|
||||
GridNodeType.Empty));
|
||||
|
||||
// Insert the new node into the sorted open list in ascending order
|
||||
int index = _openList.BinarySearch(node);
|
||||
@@ -83,12 +81,14 @@ namespace Algorithms {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Fix start position being overriden
|
||||
ChangeController.RemovePositions(start, 1);
|
||||
|
||||
// if all good, return path
|
||||
Node temp = _closedList[_closedList.IndexOf(current)];
|
||||
if (temp == null) return null;
|
||||
do {
|
||||
_path.Push(temp);
|
||||
RecordState();
|
||||
temp = temp.Parent;
|
||||
} while (temp != null && !temp.Equals(startNode));
|
||||
|
||||
|
||||
@@ -12,4 +12,8 @@
|
||||
this.Old = oldType;
|
||||
this.Time = UnityEngine.Time.realtimeSinceStartup;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return $"Change({X}, {Y}, {Old} -> {New})";
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,12 @@ public class ChangeController {
|
||||
private readonly List<Change> _changes;
|
||||
public int Count => _changes.Count;
|
||||
public Change CurrentChange => _changes[Index];
|
||||
public double CurrentRuntime => _changes[Index].Time - _changes[0].Time;
|
||||
|
||||
public ChangeController(GridNodeType[,] initial) {
|
||||
_initial = initial;
|
||||
Current = initial;
|
||||
Index = 0;
|
||||
Index = -1;
|
||||
_changes = new List<Change>();
|
||||
}
|
||||
|
||||
@@ -104,4 +105,25 @@ public class ChangeController {
|
||||
else
|
||||
Move(diff);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all Change values referencing a specific position.
|
||||
/// Intended for fixing start and end positions.
|
||||
/// Works in reverse, i.e. count = 1 removes the last position if any.
|
||||
/// </summary>
|
||||
/// <param name="position">The Vector2Int position to look for.</param>
|
||||
/// <param name="count">Maximum number of Change values to remove. -1 for all.</param>
|
||||
public void RemovePositions(Vector2Int position, int count = -1) {
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
for (int i = _changes.Count - 1; i >= 0; i--)
|
||||
if (_changes[i].X == position.x && _changes[i].Y == position.y) {
|
||||
_changes.RemoveAt(i);
|
||||
|
||||
// Return if the count is now zero.
|
||||
if (--count == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ public class Manager : MonoBehaviour {
|
||||
private ChangeController _state;
|
||||
private int _curIndex;
|
||||
private Stack<Node> _path;
|
||||
private float _lastStart;
|
||||
private float _runtime;
|
||||
|
||||
public Camera mainCamera;
|
||||
@@ -45,16 +44,10 @@ public class Manager : MonoBehaviour {
|
||||
_runtime += increment;
|
||||
|
||||
if (CurrentIndex < _state.Count)
|
||||
this.LoadNextState();
|
||||
LoadNextState();
|
||||
else {
|
||||
try {
|
||||
_lastStart = Time.realtimeSinceStartup;
|
||||
GeneratePath();
|
||||
CurrentIndex = 0;
|
||||
// _curIndex = path != null && path.Count > 30 ? 0 : _states.Count;
|
||||
}
|
||||
catch (ArgumentOutOfRangeException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,9 +72,8 @@ public class Manager : MonoBehaviour {
|
||||
_state.MoveTo(CurrentIndex);
|
||||
gridController.LoadGridState(_state.Current);
|
||||
|
||||
float change = _state.CurrentChange.Time - _lastStart;
|
||||
string pathCount = _path != null ? $"{_path.Count}" : "N/A";
|
||||
debugText.text = $"{change * 1000.0:F1}ms\n" +
|
||||
debugText.text = $"{_state.CurrentRuntime * 1000.0:F1}ms\n" +
|
||||
$"{this.CurrentIndex:000} / {_state.Count:000}\n" +
|
||||
$"Path: {pathCount} tiles";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user