movement equivalence classes

These can be used as a basis for a bunch of pathing optimizations.

- Feasability of movement can be precomputed for each class, avoiding
  the worst-case pathfinding behavior

- A path could potentially be shared between all members of a class.
  This isnt necessarily the best path for any single unit, as it
  doesn't care about efficiency of movement across various terrain --
  but it would be a "reasonable" path that the whole group could take
  together.

- General pathing checks can be converted from intersection of sets of
  strings to a simple AND.

- Other, wilder things.

V2: be paranoid about too-long bit vectors.
This commit is contained in:
Chris Forbes
2013-06-26 20:39:17 +12:00
parent fc6a38182d
commit c0e0efd0ef
2 changed files with 23 additions and 0 deletions

View File

@@ -225,6 +225,20 @@ namespace OpenRA
} }
public static Rectangle Bounds(this Bitmap b) { return new Rectangle(0, 0, b.Width, b.Height); } public static Rectangle Bounds(this Bitmap b) { return new Rectangle(0, 0, b.Width, b.Height); }
public static int ToBits(this IEnumerable<bool> bits)
{
var i = 0;
var result = 0;
foreach (var b in bits)
if (b)
result |= (1 << i++);
else
i++;
if (i > 33)
throw new InvalidOperationException("ToBits only accepts up to 32 values.");
return result;
}
} }
public static class Enum<T> public static class Enum<T>

View File

@@ -72,6 +72,15 @@ namespace OpenRA.Mods.RA.Move
return TerrainSpeeds[type].Cost; return TerrainSpeeds[type].Cost;
} }
public int GetMovementClass(TileSet tileset)
{
/* collect our ability to cross *all* terraintypes, in a bitvector */
var passability = tileset.Terrain.OrderBy(t => t.Key)
.Select(t => TerrainSpeeds.ContainsKey(t.Key) && TerrainSpeeds[t.Key].Cost < int.MaxValue);
return passability.ToBits();
}
public readonly Dictionary<SubCell, PVecInt> SubCellOffsets = new Dictionary<SubCell, PVecInt>() public readonly Dictionary<SubCell, PVecInt> SubCellOffsets = new Dictionary<SubCell, PVecInt>()
{ {
{SubCell.TopLeft, new PVecInt(-7,-6)}, {SubCell.TopLeft, new PVecInt(-7,-6)},