GodotComponentTest/tests/HexGridPathFindingTests.cs

293 lines
9.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Godot;
using GoDotTest;
using Xunit;
namespace GodotComponentTest.tests;
public class HexGridPathFindingTests : TestClass
{
private HexGrid _hexGrid;
private HexCell _hexCell;
private HexCell _positionA = new HexCell(new Vector2(2, 0));
private HexCell _positionB = new HexCell(new Vector2(4, 2));
private HexCell _positionC = new HexCell(new Vector2(7, 0));
private HexCell _positionD = new HexCell(new Vector2(5, 0));
private HexCell _positionE = new HexCell(new Vector2(2, 2));
private HexCell _positionF = new HexCell(new Vector2(1, 3));
private HexCell _positionG = new HexCell(new Vector2(1, 0));
private Vector2[] _obstacles =
{
new Vector2(2, 1),
new Vector2(3, 1),
new Vector2(4, 1),
new Vector2(1, 2),
new Vector2(3, 2),
new Vector2(1, 3),
new Vector2(2, 3),
};
public HexGridPathFindingTests(Node testScene) : base(testScene)
{
}
[Setup]
public void Setup()
{
_hexGrid = new HexGrid();
_hexCell = new HexCell();
_hexGrid.SetBounds(new Vector2(0, 0), new Vector2(7, 4));
foreach (Vector2 obstacle in _obstacles)
{
_hexGrid.AddObstacle(new HexCell(obstacle));
}
}
[Test]
public void TestBounds()
{
Assert.Equal(_hexGrid.PathCostDefault, _hexGrid.GetHexCost(new Vector2(0, 0)));
Assert.Equal(_hexGrid.PathCostDefault, _hexGrid.GetHexCost(new Vector2(0, 4)));
Assert.Equal(_hexGrid.PathCostDefault, _hexGrid.GetHexCost(new Vector2(7, 0)));
Assert.Equal(_hexGrid.PathCostDefault, _hexGrid.GetHexCost(new Vector2(7, 4)));
Assert.Equal(0, _hexGrid.GetHexCost(new Vector2(8, 2)));
Assert.Equal(0, _hexGrid.GetHexCost(new Vector2(6, 5)));
Assert.Equal(0, _hexGrid.GetHexCost(new Vector2(-1, 2)));
Assert.Equal(0, _hexGrid.GetHexCost(new Vector2(6, -1)));
}
[Test]
public void TestNegativeBounds()
{
HexGrid grid = new HexGrid();
grid.SetBounds(new Vector2(-5, -5), new Vector2(-2, -2));
Assert.Equal(grid.PathCostDefault, grid.GetHexCost(new Vector2(-2, -2)));
Assert.Equal(grid.PathCostDefault, grid.GetHexCost(new Vector2(-5, -5)));
Assert.Equal(0, grid.GetHexCost(new Vector2(0, 0)));
Assert.Equal(0, grid.GetHexCost(new Vector2(-6, -3)));
Assert.Equal(0, grid.GetHexCost(new Vector2(-3, -1)));
}
[Test]
public void TestNegativeBoundsAlt()
{
HexGrid grid = new HexGrid();
grid.SetBounds(new Vector2(-3, -3), new Vector2(2, 2));
Assert.Equal(grid.PathCostDefault, grid.GetHexCost(new Vector2(-3, -3)));
Assert.Equal(grid.PathCostDefault, grid.GetHexCost(new Vector2(2, 2)));
Assert.Equal(grid.PathCostDefault, grid.GetHexCost(new Vector2(0, 0)));
Assert.Equal(0, grid.GetHexCost(new Vector2(-4, 0)));
Assert.Equal(0, grid.GetHexCost(new Vector2(0, 3)));
}
[Test]
public void TestGridObstacles()
{
Assert.Equal(_obstacles.Length, _hexGrid.Obstacles.Count);
// Adding an obstacle
_hexGrid.AddObstacle(new HexCell(new Vector2(0, 0)));
Assert.Equal(0, _hexGrid.Obstacles[new Vector2(0, 0)]);
// Replacing obstacle
_hexGrid.AddObstacle(new HexCell(new Vector2(0, 0)), 2);
Assert.Equal(2, _hexGrid.Obstacles[new Vector2(0, 0)]);
// Removing obstacle
_hexGrid.RemoveObstacle(new HexCell(new Vector2(0, 0)));
Assert.DoesNotContain(new Vector2(0, 0), _hexGrid.Obstacles);
// Removing invalid does not cause error
_hexGrid.RemoveObstacle(new HexCell(new Vector2(0, 0)));
}
[Test]
public void TestHexCost()
{
Assert.Equal(_hexGrid.PathCostDefault, _hexGrid.GetHexCost(new Vector2(1, 1)));
Assert.Equal(0, _hexGrid.GetHexCost(new HexCell(new Vector3(2, 1, -3))));
_hexGrid.AddObstacle(new HexCell(1, 1), 1.337f);
Assert.Equal(1.337f, _hexGrid.GetHexCost(new Vector2(1, 1)));
}
[Test]
public void TestMoveCost()
{
Assert.Equal(_hexGrid.PathCostDefault, _hexGrid.GetMoveCost(new Vector2(0, 0), HexCell.DIR_N));
}
[Test]
public void TestMovieCostCumulative()
{
_hexGrid.AddObstacle(new Vector2(0, 0), 1);
_hexGrid.AddObstacle(new Vector2(0, 1), 2);
_hexGrid.AddBarrier(new Vector2(0, 0), HexCell.DIR_N, 4);
Assert.Single(_hexGrid.Barriers);
_hexGrid.AddBarrier(new Vector2(0, 1), HexCell.DIR_S, 8);
Assert.Equal(2, _hexGrid.Barriers.Count);
Assert.Equal(14, _hexGrid.GetMoveCost(new Vector2(0, 0), HexCell.DIR_N));
}
void ComparePath(List<HexCell> expected, List<HexCell> path)
{
Assert.Equal(expected.Count, path.Count());
foreach (int i in Enumerable.Range(0, Math.Min(expected.Count, path.Count())))
{
HexCell pathCell = path[i];
HexCell expectedCell = expected[i];
Assert.Equal(expectedCell.AxialCoords, pathCell.AxialCoords);
}
}
[Test]
public void TestStraightLine()
{
List<HexCell> expectedPath = new List<HexCell>()
{
_positionA,
new HexCell(new Vector2(3, 0)),
new HexCell(new Vector2(4, 0)),
new HexCell(new Vector2(5, 0)),
new HexCell(new Vector2(6, 0)),
_positionC
};
ComparePath(expectedPath, _hexGrid.FindPath(expectedPath.First(), expectedPath.Last()));
}
// TODO: verify what the issue is here
// [Test]
// public void TestWonkyLine()
// {
// List<HexCell> expectedPath = new List<HexCell>()
// {
// _positionB,
// new HexCell(new Vector2(5, 1)),
// new HexCell(new Vector2(5, 2)),
// new HexCell(new Vector2(6, 0)),
// new HexCell(new Vector2(6, 1)),
// _positionC
// };
//
// ComparePath(expectedPath, _hexGrid.FindPath(expectedPath.First(), expectedPath.Last()));
// }
[Test]
public void TestObstacle()
{
List<HexCell> expectedPath = new List<HexCell>()
{
_positionA,
new HexCell(new Vector2(3, 0)),
new HexCell(new Vector2(4, 0)),
new HexCell(new Vector2(5, 0)),
new HexCell(new Vector2(5, 1)),
_positionB
};
ComparePath(expectedPath, _hexGrid.FindPath(expectedPath.First(), expectedPath.Last()));
}
[Test]
public void TestWalls()
{
Vector3[] walls =
{
HexCell.DIR_N,
HexCell.DIR_NE,
HexCell.DIR_SE,
HexCell.DIR_S,
// DIR_SE is open
HexCell.DIR_NW
};
foreach (Vector3 wall in walls)
{
_hexGrid.AddBarrier(_positionG, wall);
}
List<HexCell> expectedPath = new List<HexCell>()
{
_positionA,
new HexCell(new Vector2(1, 1)),
new HexCell(new Vector2(0, 1)),
new HexCell(new Vector2(0, 0)),
_positionG
};
ComparePath(expectedPath, _hexGrid.FindPath(expectedPath.First(), expectedPath.Last()));
}
[Test]
public void TestSlopes()
{
_hexGrid.AddBarrier(_positionG, HexCell.DIR_NE, 3);
_hexGrid.AddBarrier(_positionG, HexCell.DIR_N, _hexGrid.PathCostDefault - 0.1f);
List<HexCell> expectedPath = new List<HexCell>()
{
_positionA,
new HexCell(new Vector2(1, 1)),
_positionG
};
ComparePath(expectedPath, _hexGrid.FindPath(expectedPath.First(), expectedPath.Last()));
}
[Test]
public void TestRoughTerrain()
{
List<HexCell> shortPath = new List<HexCell>()
{
_positionA,
new HexCell(new Vector2(3, 0)),
new HexCell(new Vector2(4, 0)),
_positionD,
new HexCell(new Vector2(5, 1)),
_positionB,
};
List<HexCell> longPath = new List<HexCell>()
{
_positionA,
new HexCell(new Vector2(1, 1)),
new HexCell(new Vector2(0, 2)),
new HexCell(new Vector2(0, 3)),
new HexCell(new Vector2(0, 4)),
new HexCell(new Vector2(1, 4)),
new HexCell(new Vector2(2, 4)),
new HexCell(new Vector2(3, 3)),
_positionB,
};
_hexGrid.PathCostDefault = 1f;
ComparePath(shortPath, _hexGrid.FindPath(shortPath.First(), shortPath.Last()));
_hexGrid.PathCostDefault = 2f;
ComparePath(shortPath, _hexGrid.FindPath(shortPath.First(), shortPath.Last()));
_hexGrid.PathCostDefault = 3.9f;
ComparePath(shortPath, _hexGrid.FindPath(shortPath.First(), shortPath.Last()));
// TODO: check what causes the difference here
// _hexGrid.PathCostDefault = 4.1f;
// ComparePath(longPath, _hexGrid.FindPath(longPath.First(), longPath.Last()));
//
// _hexGrid.PathCostDefault = 51f;
// ComparePath(longPath, _hexGrid.FindPath(longPath.First(), longPath.Last()));
//
// _hexGrid.PathCostDefault = 0f;
// ComparePath(longPath, _hexGrid.FindPath(longPath.First(), longPath.Last()));
}
}