public IEnumerable<ITerrainBehaviour> Search(ITerrainBehaviour startTerrainBehaviour, ITerrainBehaviour targetTerrainBehaviour, ITerrainNodeContainer terrainContainer) { var coastArray = new int[terrainContainer.RowsLength, terrainContainer.ColumnsLength]; coastArray[startTerrainBehaviour.RowIndex, startTerrainBehaviour.ColsIndex] = startTerrainBehaviour.MoveCoast; var resoult = FindPath(startTerrainBehaviour, targetTerrainBehaviour, terrainContainer, coastArray); resoult.Reverse(); return resoult; }
private List<ITerrainBehaviour> FindPath(ITerrainBehaviour startTerrainBehaviour, ITerrainBehaviour targetTerrainBehaviour, ITerrainNodeContainer terrainContainer, int[,] coastArray) { var queue = new List<ITerrainNode>() { terrainContainer.TerrainNodesArray[startTerrainBehaviour.RowIndex, startTerrainBehaviour.ColsIndex] }; var canFinish = false; do { var current = queue.First(); queue.RemoveAt(0); foreach (var terrainNode in current.Nodes) { if (terrainNode.Item.TerrainType == TerrainType.Land) { var row = terrainNode.RowIndex; var column = terrainNode.ColumnIndex; var potential = coastArray[current.RowIndex, current.ColumnIndex] + terrainNode.Item.MoveCoast; if (coastArray[row, column] == 0 || potential < coastArray[row, column]) { coastArray[row, column] = potential; queue.Add(terrainNode); } } } } while (queue.Any()); var pathCollection = new List<ITerrainBehaviour>() {targetTerrainBehaviour}; canFinish = false; var item = terrainContainer.TerrainNodesArray[targetTerrainBehaviour.RowIndex, targetTerrainBehaviour.ColsIndex]; ITerrainNode nextNode = null; while (!canFinish) { var min = coastArray[item.RowIndex, item.ColumnIndex]; foreach (var terrainNode in item.Nodes) { var row = terrainNode.RowIndex; var column = terrainNode.ColumnIndex; if (coastArray[row, column] < min && coastArray[row, column] > 0) { nextNode = terrainNode; min = coastArray[row, column]; if (terrainNode.Item == startTerrainBehaviour) { canFinish = true; break; } } } item = nextNode; pathCollection.Add(item.Item); } return pathCollection; }