public FindPath ( |
||
start | ||
end | ||
maxDist | int | |
controllingPlayerId | int | |
리턴 | List |
public List<Tile> FindPath(Tile start, Tile end, int maxDist, int controllingPlayerId)
{
var ret = new List<Tile>();
if(start == end) return ret;
// The set of nodes already evaluated.
var closedset = new List<Tile>();
// The set of tentative nodes to be evaluated, initially containing the start node
var openset = new List<Tile>(){ start };
// The map of navigated nodes.
var came_from = new Dictionary<Tile, Tile>();
var g_score = new Dictionary<Tile, int>();
g_score[start] = 0; // Cost from start along best known path.
// Estimated total cost from start to goal through y.
var f_score = new Dictionary<Tile, int>();
f_score[start] = g_score[start] + heuristic_cost_estimate(start, end);
while (openset.Count > 0) {
// the node in openset having the lowest f_score[] value
var current = openset.OrderBy(x => getValueOrMax(f_score,x)).First();
if (current == end) {
return ReconstructPath(came_from, end);
}
openset.Remove(current);
closedset.Add(current);
var neighbors = GetMovableNeighbors(current, controllingPlayerId, end);
foreach (var neighborDict in neighbors) {
var neighbor = neighborDict.Value;
if(closedset.Contains(neighbor)){
continue;
}
var tentative_g_score = getValueOrMax(g_score,current) + TileDistance(current.position, neighbor.position);
if (!openset.Contains(neighbor) || tentative_g_score < getValueOrMax(g_score,neighbor)) {
//check for max dist along path
if (tentative_g_score > maxDist)
{
continue;
}
came_from[neighbor] = current;
g_score[neighbor] = tentative_g_score;
f_score[neighbor] = getValueOrMax(g_score,neighbor) + TileDistance(neighbor.position, end.position);
if (!openset.Contains(neighbor)) {
openset.Add(neighbor);
}
}
}
}
return null;
}
public void FindPath() { var mapService = new MapService(); mapService.mapModel = new MapModel() { name = "test map", maxPlayers = 0, root = null, tiles = CreateTiles(10, 10) }; mapService.pieces = new PiecesModel() { Pieces = new List<PieceModel>() { MockPiece(new Vector2(1, 2), false), MockPiece(new Vector2(2, 3), true), MockPiece(new Vector2(3, 2), true), MockPiece(new Vector2(4, 2), true), MockPiece(new Vector2(5, 2), false) } }; var start = mapService.mapModel.tiles[new Vector2(2,2)]; //test to walk around enemy var enemyEnd = mapService.mapModel.tiles[new Vector2(0,2)]; var enemyPath = mapService.FindPath(start, enemyEnd, 4, 1); var expectedEnemyPath = new List<Vector2>() { new Vector2(2, 3), new Vector2(1, 3), new Vector2(0, 3), new Vector2(0, 2), }; CollectionAssert.AreEqual( enemyPath.Select(t => t.position).ToList(), expectedEnemyPath ); //test to walk through friendly var end = mapService.mapModel.tiles[new Vector2(2,4)]; var tilePath = mapService.FindPath(start, end, 2, 1); var expectedTiles = new List<Vector2>() { new Vector2(2, 3), new Vector2(2, 4) }; CollectionAssert.AreEqual( tilePath.Select(t => t.position).ToList(), expectedTiles ); //test to attack enemy but not land on a friendly var passThroughEnd = mapService.mapModel.tiles[new Vector2(5,2)]; var passTilePath = mapService.FindPath(start, passThroughEnd, 6, 1); var passExpectedTiles = new List<Vector2>() { new Vector2(3, 2), new Vector2(3, 3), new Vector2(4, 3), new Vector2(5, 3), new Vector2(5, 2) }; CollectionAssert.AreEqual( passTilePath.Select(t => t.position).ToList(), passExpectedTiles ); }