Clean up PathSearch

- Remove functionality for tracking cells considered during the search, as nothing relies on this.
- Rename various parameters in the expand function to closer match naming of fields used in CellInfo, intended to improve clarity.
This commit is contained in:
RoosterDragon
2021-11-18 15:42:48 +00:00
committed by Matthias Mailänder
parent e1ade59a32
commit 8c627aa185
2 changed files with 16 additions and 47 deletions

View File

@@ -10,7 +10,6 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives; using OpenRA.Primitives;
@@ -24,15 +23,8 @@ namespace OpenRA.Mods.Common.Pathfinder
/// </summary> /// </summary>
IGraph<CellInfo> Graph { get; } IGraph<CellInfo> Graph { get; }
/// <summary>
/// Stores the analyzed nodes by the expand function
/// </summary>
IEnumerable<(CPos Cell, int Cost)> Considered { get; }
Player Owner { get; } Player Owner { get; }
int MaxCost { get; }
IPathSearch Reverse(); IPathSearch Reverse();
IPathSearch WithCustomBlocker(Func<CPos, bool> customBlock); IPathSearch WithCustomBlocker(Func<CPos, bool> customBlock);
@@ -68,11 +60,7 @@ namespace OpenRA.Mods.Common.Pathfinder
protected IPriorityQueue<GraphConnection> OpenQueue { get; private set; } protected IPriorityQueue<GraphConnection> OpenQueue { get; private set; }
public abstract IEnumerable<(CPos Cell, int Cost)> Considered { get; }
public Player Owner => Graph.Actor.Owner; public Player Owner => Graph.Actor.Owner;
public int MaxCost { get; protected set; }
public bool Debug { get; set; }
protected Func<CPos, int> heuristic; protected Func<CPos, int> heuristic;
protected Func<CPos, bool> isGoal; protected Func<CPos, bool> isGoal;
protected int heuristicWeightPercentage; protected int heuristicWeightPercentage;
@@ -91,7 +79,6 @@ namespace OpenRA.Mods.Common.Pathfinder
Graph = graph; Graph = graph;
OpenQueue = new PriorityQueue<GraphConnection>(GraphConnection.ConnectionCostComparer); OpenQueue = new PriorityQueue<GraphConnection>(GraphConnection.ConnectionCostComparer);
StartPoints = new PriorityQueue<GraphConnection>(GraphConnection.ConnectionCostComparer); StartPoints = new PriorityQueue<GraphConnection>(GraphConnection.ConnectionCostComparer);
MaxCost = 0;
heuristicWeightPercentage = 100; heuristicWeightPercentage = 100;
// Determine the minimum possible cost for moving horizontally between cells based on terrain speeds. // Determine the minimum possible cost for moving horizontally between cells based on terrain speeds.

View File

@@ -29,16 +29,9 @@ namespace OpenRA.Mods.Common.Pathfinder
return LayerPoolTable.GetValue(world, CreateLayerPool); return LayerPoolTable.GetValue(world, CreateLayerPool);
} }
public override IEnumerable<(CPos, int)> Considered => considered;
LinkedList<(CPos, int)> considered;
#region Constructors
private PathSearch(IGraph<CellInfo> graph) private PathSearch(IGraph<CellInfo> graph)
: base(graph) : base(graph)
{ {
considered = new LinkedList<(CPos, int)>();
} }
public static IPathSearch Search(World world, Locomotor locomotor, Actor self, BlockedByActor check, Func<CPos, bool> goalCondition) public static IPathSearch Search(World world, Locomotor locomotor, Actor self, BlockedByActor check, Func<CPos, bool> goalCondition)
@@ -90,11 +83,8 @@ namespace OpenRA.Mods.Common.Pathfinder
var connection = new GraphConnection(location, cost); var connection = new GraphConnection(location, cost);
OpenQueue.Add(connection); OpenQueue.Add(connection);
StartPoints.Add(connection); StartPoints.Add(connection);
considered.AddLast((location, 0));
} }
#endregion
/// <summary> /// <summary>
/// This function analyzes the neighbors of the most promising node in the Pathfinding graph /// This function analyzes the neighbors of the most promising node in the Pathfinding graph
/// using the A* algorithm (A-star) and returns that node /// using the A* algorithm (A-star) and returns that node
@@ -104,8 +94,8 @@ namespace OpenRA.Mods.Common.Pathfinder
{ {
var currentMinNode = OpenQueue.Pop().Destination; var currentMinNode = OpenQueue.Pop().Destination;
var currentCell = Graph[currentMinNode]; var currentInfo = Graph[currentMinNode];
Graph[currentMinNode] = new CellInfo(CellStatus.Closed, currentCell.CostSoFar, currentCell.EstimatedTotalCost, currentCell.PreviousNode); Graph[currentMinNode] = new CellInfo(CellStatus.Closed, currentInfo.CostSoFar, currentInfo.EstimatedTotalCost, currentInfo.PreviousNode);
if (Graph.CustomCost != null && Graph.CustomCost(currentMinNode) == PathGraph.PathCostForInvalidPath) if (Graph.CustomCost != null && Graph.CustomCost(currentMinNode) == PathGraph.PathCostForInvalidPath)
return currentMinNode; return currentMinNode;
@@ -113,38 +103,30 @@ namespace OpenRA.Mods.Common.Pathfinder
foreach (var connection in Graph.GetConnections(currentMinNode)) foreach (var connection in Graph.GetConnections(currentMinNode))
{ {
// Calculate the cost up to that point // Calculate the cost up to that point
var gCost = currentCell.CostSoFar + connection.Cost; var costSoFarToNeighbor = currentInfo.CostSoFar + connection.Cost;
var neighborCPos = connection.Destination; var neighbor = connection.Destination;
var neighborCell = Graph[neighborCPos]; var neighborInfo = Graph[neighbor];
// Cost is even higher; next direction: // Cost is even higher; next direction:
if (neighborCell.Status == CellStatus.Closed || if (neighborInfo.Status == CellStatus.Closed ||
(neighborCell.Status == CellStatus.Open && gCost >= neighborCell.CostSoFar)) (neighborInfo.Status == CellStatus.Open && costSoFarToNeighbor >= neighborInfo.CostSoFar))
continue; continue;
// Now we may seriously consider this direction using heuristics. If the cell has // Now we may seriously consider this direction using heuristics. If the cell has
// already been processed, we can reuse the result (just the difference between the // already been processed, we can reuse the result (just the difference between the
// estimated total and the cost so far // estimated total and the cost so far)
int hCost; int estimatedRemainingCostToTarget;
if (neighborCell.Status == CellStatus.Open) if (neighborInfo.Status == CellStatus.Open)
hCost = neighborCell.EstimatedTotalCost - neighborCell.CostSoFar; estimatedRemainingCostToTarget = neighborInfo.EstimatedTotalCost - neighborInfo.CostSoFar;
else else
hCost = heuristic(neighborCPos); estimatedRemainingCostToTarget = heuristic(neighbor);
var estimatedCost = gCost + hCost; var estimatedTotalCostToTarget = costSoFarToNeighbor + estimatedRemainingCostToTarget;
Graph[neighborCPos] = new CellInfo(CellStatus.Open, gCost, estimatedCost, currentMinNode); Graph[neighbor] = new CellInfo(CellStatus.Open, costSoFarToNeighbor, estimatedTotalCostToTarget, currentMinNode);
if (neighborCell.Status != CellStatus.Open) if (neighborInfo.Status != CellStatus.Open)
OpenQueue.Add(new GraphConnection(neighborCPos, estimatedCost)); OpenQueue.Add(new GraphConnection(neighbor, estimatedTotalCostToTarget));
if (Debug)
{
if (gCost > MaxCost)
MaxCost = gCost;
considered.AddLast((neighborCPos, gCost));
}
} }
return currentMinNode; return currentMinNode;