2021-11-23 21:42:18 +01:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using Microsoft.Xna.Framework;
|
|
|
|
|
using MLEM.Pathfinding;
|
|
|
|
|
using NUnit.Framework;
|
|
|
|
|
|
|
|
|
|
namespace Tests {
|
|
|
|
|
public class PathfindingTests {
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public void TestConsistency() {
|
|
|
|
|
var area = new[] {
|
|
|
|
|
"XXXX",
|
|
|
|
|
"X X",
|
|
|
|
|
"X X",
|
|
|
|
|
"XXXX"
|
|
|
|
|
};
|
|
|
|
|
|
2022-06-15 11:38:11 +02:00
|
|
|
|
var noDiagonals = PathfindingTests.FindPathInArea(new Point(1, 1), new Point(2, 2), area, false).ToArray();
|
2021-11-23 21:42:18 +01:00
|
|
|
|
Assert.AreEqual(noDiagonals.Length, 3);
|
|
|
|
|
Assert.AreEqual(noDiagonals[0], new Point(1, 1));
|
|
|
|
|
Assert.AreEqual(noDiagonals[2], new Point(2, 2));
|
|
|
|
|
|
2022-06-15 11:38:11 +02:00
|
|
|
|
var diagonals = PathfindingTests.FindPathInArea(new Point(1, 1), new Point(2, 2), area, true).ToArray();
|
2021-11-23 21:42:18 +01:00
|
|
|
|
Assert.AreEqual(diagonals.Length, 2);
|
|
|
|
|
Assert.AreEqual(diagonals[0], new Point(1, 1));
|
|
|
|
|
Assert.AreEqual(diagonals[1], new Point(2, 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public void TestPathCost() {
|
|
|
|
|
var area = new[] {
|
|
|
|
|
"XXXXXXXX",
|
|
|
|
|
"X 5 X",
|
|
|
|
|
"X 5 X",
|
|
|
|
|
"XXXXXXXX"
|
|
|
|
|
};
|
|
|
|
|
|
2022-06-15 11:38:11 +02:00
|
|
|
|
var firstPath = PathfindingTests.FindPathInArea(new Point(1, 1), new Point(3, 1), area, false).ToArray();
|
2021-11-23 21:42:18 +01:00
|
|
|
|
var firstExpected = new[] {new Point(1, 1), new Point(1, 2), new Point(2, 2), new Point(3, 2), new Point(3, 1)};
|
|
|
|
|
Assert.AreEqual(firstPath, firstExpected);
|
|
|
|
|
|
2022-06-15 11:38:11 +02:00
|
|
|
|
var secondPath = PathfindingTests.FindPathInArea(new Point(1, 1), new Point(5, 2), area, false).ToArray();
|
2021-11-23 21:42:18 +01:00
|
|
|
|
var secondExpected = firstExpected.Concat(new[] {new Point(4, 1), new Point(5, 1), new Point(5, 2)}).ToArray();
|
|
|
|
|
Assert.AreEqual(secondPath, secondExpected);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public void TestBlocked() {
|
|
|
|
|
var area = new[] {
|
|
|
|
|
"XXXX",
|
|
|
|
|
"X XX",
|
|
|
|
|
"XX X",
|
|
|
|
|
"X X",
|
|
|
|
|
"XXXX"
|
|
|
|
|
};
|
|
|
|
|
// non-diagonal pathfinding should get stuck in the corner
|
2022-06-15 11:38:11 +02:00
|
|
|
|
Assert.IsNull(PathfindingTests.FindPathInArea(new Point(1, 1), new Point(2, 3), area, false));
|
2021-11-23 21:42:18 +01:00
|
|
|
|
// diagonal pathfinding should be able to cross the diagonal gap
|
2022-06-15 11:38:11 +02:00
|
|
|
|
Assert.IsNotNull(PathfindingTests.FindPathInArea(new Point(1, 1), new Point(2, 3), area, true));
|
2021-11-23 21:42:18 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Stack<Point> FindPathInArea(Point start, Point end, IEnumerable<string> area, bool allowDiagonals) {
|
|
|
|
|
var costs = area.Select(s => s.Select(c => c switch {
|
|
|
|
|
' ' => 1,
|
2022-06-15 11:38:11 +02:00
|
|
|
|
'X' => float.PositiveInfinity,
|
2021-11-23 21:42:18 +01:00
|
|
|
|
_ => (float) char.GetNumericValue(c)
|
|
|
|
|
}).ToArray()).ToArray();
|
|
|
|
|
var pathFinder = new AStar2((p1, p2) => costs[p2.Y][p2.X], allowDiagonals);
|
|
|
|
|
return pathFinder.FindPath(start, end);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2022-06-17 18:23:47 +02:00
|
|
|
|
}
|