From f4e5c63408bd2c98e76de86e5a980b560df7e45c Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 22 Nov 2014 17:06:55 +1300 Subject: [PATCH] Pathfinder: Only consider useful neighbors Depending on the direction we came from, many neighbors are completely useless. This is the first step to implementing the ideas in 'Jump Point Search' V2: Added comment describing what the array is for. --- OpenRA.Mods.RA/Move/PathSearch.cs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.RA/Move/PathSearch.cs b/OpenRA.Mods.RA/Move/PathSearch.cs index bdfed9a183..42d10a37f5 100755 --- a/OpenRA.Mods.RA/Move/PathSearch.cs +++ b/OpenRA.Mods.RA/Move/PathSearch.cs @@ -138,6 +138,32 @@ namespace OpenRA.Mods.RA.Move return this; } + // Sets of neighbors for each incoming direction. These exclude the neighbors which are guaranteed + // to be reached more cheaply by a path through our parent cell which does not include the current cell. + // For horizontal/vertical directions, the set is the three cells 'ahead'. For diagonal directions, the set + // is the three cells ahead, plus the two cells to the side, which we cannot exclude without knowing if + // the cell directly between them and our parent is passable. + static CVec[][] DirectedNeighbors = { + new CVec[] { new CVec(-1, -1), new CVec(0, -1), new CVec(1, -1), new CVec(-1, 0), new CVec(-1, 1) }, + new CVec[] { new CVec(-1, -1), new CVec(0, -1), new CVec(1, -1) }, + new CVec[] { new CVec(-1, -1), new CVec(0, -1), new CVec(1, -1), new CVec(1, 0), new CVec(1, 1) }, + new CVec[] { new CVec(-1, -1), new CVec(-1, 0), new CVec(-1, 1) }, + CVec.directions, + new CVec[] { new CVec(1, -1), new CVec(1, 0), new CVec(1, 1) }, + new CVec[] { new CVec(-1, -1), new CVec(-1, 0), new CVec(-1, 1), new CVec(0, 1), new CVec(1, 1) }, + new CVec[] { new CVec(-1, 1), new CVec(0, 1), new CVec(1, 1) }, + new CVec[] { new CVec(1, -1), new CVec(1, 0), new CVec(-1, 1), new CVec(0, 1), new CVec(1, 1) }, + }; + + static CVec[] GetNeighbors(CPos p, CPos prev) + { + var dx = p.X - prev.X; + var dy = p.Y - prev.Y; + var index = dy * 3 + dx + 4; + + return DirectedNeighbors[index]; + } + public CPos Expand(World world) { var p = Queue.Pop(); @@ -165,10 +191,10 @@ namespace OpenRA.Mods.RA.Move return p.Location; } - // This current cell is ok; check all immediate directions: + // This current cell is ok; check useful immediate directions: Considered.Add(p.Location); - var directions = CVec.directions; + var directions = GetNeighbors(p.Location, pCell.Path); for (var i = 0; i < directions.Length; ++i) {