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(start.x, start.y, GridNodeType.Start, GridNodeType.Empty));
|
||||||
ChangeController.AddChange(new Change(end.x, end.y, GridNodeType.End, GridNodeType.Empty));
|
ChangeController.AddChange(new Change(end.x, end.y, GridNodeType.End, GridNodeType.Empty));
|
||||||
|
|
||||||
|
Node startNode = _nodeGrid.Grid[start.x, start.y];
|
||||||
var startNode = new Node(start, true);
|
Node endNode = _nodeGrid.Grid[end.x, end.y];
|
||||||
var endNode = new Node(end, true);
|
|
||||||
|
|
||||||
|
|
||||||
_path = new Stack<Node>();
|
_path = new Stack<Node>();
|
||||||
_openList = new List<Node>();
|
_openList = new List<Node>();
|
||||||
@@ -41,11 +39,12 @@ namespace Algorithms {
|
|||||||
Node current = startNode;
|
Node current = startNode;
|
||||||
|
|
||||||
// add start node to Open List
|
// add start node to Open List
|
||||||
|
startNode.State = NodeState.Open;
|
||||||
_openList.Add(startNode);
|
_openList.Add(startNode);
|
||||||
|
|
||||||
while (_openList.Count != 0) {
|
while (_openList.Count != 0) {
|
||||||
current = _openList.First();
|
current = _openList[0];
|
||||||
_openList.Remove(current);
|
_openList.RemoveAt(0);
|
||||||
|
|
||||||
current.State = NodeState.Closed;
|
current.State = NodeState.Closed;
|
||||||
ChangeController.AddChange(new Change(
|
ChangeController.AddChange(new Change(
|
||||||
@@ -56,8 +55,6 @@ namespace Algorithms {
|
|||||||
if (current.Position == endNode.Position)
|
if (current.Position == endNode.Position)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
RecordState();
|
|
||||||
|
|
||||||
Node[] adjacentNodes = this._nodeGrid.GetAdjacentNodesArray(current);
|
Node[] adjacentNodes = this._nodeGrid.GetAdjacentNodesArray(current);
|
||||||
for (int i = 0; i < adjacentNodes.Length; i++) {
|
for (int i = 0; i < adjacentNodes.Length; i++) {
|
||||||
Node node = adjacentNodes[i];
|
Node node = adjacentNodes[i];
|
||||||
@@ -68,7 +65,8 @@ namespace Algorithms {
|
|||||||
node.Cost = node.Weight + node.Parent.Cost;
|
node.Cost = node.Weight + node.Parent.Cost;
|
||||||
|
|
||||||
node.State = NodeState.Open;
|
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
|
// Insert the new node into the sorted open list in ascending order
|
||||||
int index = _openList.BinarySearch(node);
|
int index = _openList.BinarySearch(node);
|
||||||
@@ -83,12 +81,14 @@ namespace Algorithms {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix start position being overriden
|
||||||
|
ChangeController.RemovePositions(start, 1);
|
||||||
|
|
||||||
// if all good, return path
|
// if all good, return path
|
||||||
Node temp = _closedList[_closedList.IndexOf(current)];
|
Node temp = _closedList[_closedList.IndexOf(current)];
|
||||||
if (temp == null) return null;
|
if (temp == null) return null;
|
||||||
do {
|
do {
|
||||||
_path.Push(temp);
|
_path.Push(temp);
|
||||||
RecordState();
|
|
||||||
temp = temp.Parent;
|
temp = temp.Parent;
|
||||||
} while (temp != null && !temp.Equals(startNode));
|
} while (temp != null && !temp.Equals(startNode));
|
||||||
|
|
||||||
|
|||||||
@@ -12,4 +12,8 @@
|
|||||||
this.Old = oldType;
|
this.Old = oldType;
|
||||||
this.Time = UnityEngine.Time.realtimeSinceStartup;
|
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;
|
private readonly List<Change> _changes;
|
||||||
public int Count => _changes.Count;
|
public int Count => _changes.Count;
|
||||||
public Change CurrentChange => _changes[Index];
|
public Change CurrentChange => _changes[Index];
|
||||||
|
public double CurrentRuntime => _changes[Index].Time - _changes[0].Time;
|
||||||
|
|
||||||
public ChangeController(GridNodeType[,] initial) {
|
public ChangeController(GridNodeType[,] initial) {
|
||||||
_initial = initial;
|
_initial = initial;
|
||||||
Current = initial;
|
Current = initial;
|
||||||
Index = 0;
|
Index = -1;
|
||||||
_changes = new List<Change>();
|
_changes = new List<Change>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,4 +105,25 @@ public class ChangeController {
|
|||||||
else
|
else
|
||||||
Move(diff);
|
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 ChangeController _state;
|
||||||
private int _curIndex;
|
private int _curIndex;
|
||||||
private Stack<Node> _path;
|
private Stack<Node> _path;
|
||||||
private float _lastStart;
|
|
||||||
private float _runtime;
|
private float _runtime;
|
||||||
|
|
||||||
public Camera mainCamera;
|
public Camera mainCamera;
|
||||||
@@ -45,16 +44,10 @@ public class Manager : MonoBehaviour {
|
|||||||
_runtime += increment;
|
_runtime += increment;
|
||||||
|
|
||||||
if (CurrentIndex < _state.Count)
|
if (CurrentIndex < _state.Count)
|
||||||
this.LoadNextState();
|
LoadNextState();
|
||||||
else {
|
else {
|
||||||
try {
|
GeneratePath();
|
||||||
_lastStart = Time.realtimeSinceStartup;
|
CurrentIndex = 0;
|
||||||
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);
|
_state.MoveTo(CurrentIndex);
|
||||||
gridController.LoadGridState(_state.Current);
|
gridController.LoadGridState(_state.Current);
|
||||||
|
|
||||||
float change = _state.CurrentChange.Time - _lastStart;
|
|
||||||
string pathCount = _path != null ? $"{_path.Count}" : "N/A";
|
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" +
|
$"{this.CurrentIndex:000} / {_state.Count:000}\n" +
|
||||||
$"Path: {pathCount} tiles";
|
$"Path: {pathCount} tiles";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user