public KeyValuePair <float, Tile[]> GetDijkstraPath(Tile source, Tile destination, PathType givenPathType) { bool pathFound = false; int count = 0; Tile[] bestPath = new Tile[0]; float distance = -1; float[][] distanceMap = new float[MAPWIDTH][]; Position?[][] previousTilePos = new Position?[MAPWIDTH][]; SearchAbleArray <Tile> queue = new SearchAbleArray <Tile>(); SearchAbleArray <Tile> diagonalQueue = new SearchAbleArray <Tile>(); SearchAbleArray <Tile> sidewaysQueue = new SearchAbleArray <Tile>(); SearchAbleArray <Tile> backwardsQueue = new SearchAbleArray <Tile>(); TileArray explored = new TileArray(); queue.Add(source); for (int i = 0; i < MAPWIDTH; i++) { distanceMap[i] = new float[MAPHEIGHT]; previousTilePos[i] = new Position?[MAPHEIGHT]; for (int j = 0; j < MAPHEIGHT; j++) { distanceMap[i][j] = -1; previousTilePos[i][j] = null; } } previousTilePos[source.GetX()][source.GetY()] = new Position(source.GetX(), source.GetY()); distanceMap[source.GetX()][source.GetY()] = 0; while ((queue.GetSize() > 0 || sidewaysQueue.GetSize() > 0 || backwardsQueue.GetSize() > 0) && !pathFound) { Tile[] currQueueArray; SearchAbleArray <Tile> currentQueue; if (queue.GetSize() > 0) { currentQueue = queue; } else if (diagonalQueue.GetSize() > 0) { currentQueue = diagonalQueue; } else if (sidewaysQueue.GetSize() > 0) { currentQueue = sidewaysQueue; } else { currentQueue = backwardsQueue; } currQueueArray = currentQueue.GetOrderedArray(); Tile currentElement = currQueueArray[0]; float minQueueDistance = distanceMap[currQueueArray[0].GetX()][currQueueArray[0].GetY()]; for (int i = 0; i < currQueueArray.Length; i++) { if (distanceMap[currQueueArray[i].GetX()][currQueueArray[i].GetY()] < minQueueDistance) { currentElement = currQueueArray[i]; } } explored.AddTile(currentElement); if (currentElement == destination) { pathFound = true; } else { Tile[] queueAdjacent = GetAdjacent(currentElement, destination); for (int i = 0; i < queueAdjacent.Length; i++) { float currToNextTravelDistance = GetAdjacentTravelDistance(currentElement, queueAdjacent[i], givenPathType); if (currToNextTravelDistance > 0) { if (previousTilePos[queueAdjacent[i].GetX()][queueAdjacent[i].GetY()] == null) { if (i < 1) { queue.Add(queueAdjacent[i]); } else if (i < 3) { diagonalQueue.Add(queueAdjacent[i]); } else if (i < 5) { sidewaysQueue.Add(queueAdjacent[i]); } else { backwardsQueue.Add(queueAdjacent[i]); } float alteredDistance = distanceMap[currentElement.GetX()][currentElement.GetY()] + currToNextTravelDistance; if (distanceMap[queueAdjacent[i].GetX()][queueAdjacent[i].GetY()] < 0 || alteredDistance < distanceMap[queueAdjacent[i].GetX()][queueAdjacent[i].GetY()]) { distanceMap[queueAdjacent[i].GetX()][queueAdjacent[i].GetY()] = alteredDistance; previousTilePos[queueAdjacent[i].GetX()][queueAdjacent[i].GetY()] = new Position(currentElement.GetX(), currentElement.GetY()); } } } } } currentQueue.Remove(currentElement); } Tile[] tempBestPath = new Tile[0]; Tile previousTile = destination; do { if (previousTilePos[previousTile.GetX()][previousTile.GetY()] != null) { TestMain.AddElement <Tile>(ref tempBestPath, previousTile); previousTile = GetTile((Position)previousTilePos[previousTile.GetX()][previousTile.GetY()]); } else { throw new NoPathException("There is no path between " + source + " and " + destination + " when travelling by " + givenPathType); } }while (previousTile != source); if (tempBestPath.Length > 5) { Debug.Log("cool"); } TestMain.AddElement <Tile>(ref tempBestPath, source); bestPath = new Tile[tempBestPath.Length]; for (int i = tempBestPath.Length - 1; i >= 0; i--) { bestPath[i] = tempBestPath[i]; } return(new KeyValuePair <float, Tile[]>(distance, bestPath)); }
public Tile[] FillArea(Tile[] outerPoint) { if (outerPoint.Length > 2) { TileArray perimeter = new TileArray(); SearchAbleArray <Tile> corner = new SearchAbleArray <Tile>(); for (int i = 0; i < outerPoint.Length; i++) { int nextPoint = i + 1; if (nextPoint == outerPoint.Length) { nextPoint = 0; } Tile[] tempPerimeter = GetBestPath(outerPoint[i], outerPoint[nextPoint], PathType.IgnoreAll); int precedingIndex; int afterIndex; if (nextPoint == 0) { precedingIndex = outerPoint.Length - 1; } else { precedingIndex = nextPoint - 1; } if (nextPoint == outerPoint.Length - 1) { afterIndex = 0; } else { afterIndex = nextPoint + 1; } while (outerPoint[afterIndex].GetX() == outerPoint[nextPoint].GetX()) { corner.Add(outerPoint[afterIndex]); if (++afterIndex >= outerPoint.Length) { afterIndex = 0; } } if ((outerPoint[precedingIndex].GetX() <= outerPoint[nextPoint].GetX() && outerPoint[afterIndex].GetX() <= outerPoint[nextPoint].GetX()) || (outerPoint[precedingIndex].GetX() >= outerPoint[nextPoint].GetX() && outerPoint[afterIndex].GetX() >= outerPoint[nextPoint].GetX())) { corner.Add(outerPoint[nextPoint]); } for (int j = 0; j < tempPerimeter.Length; j++) { //if the end tile just addhave already assigned a corner or not if (j == tempPerimeter.Length - 1) { perimeter.AddTile(tempPerimeter[j]); } //else if not the startTile else if (j != 0) { //if it is inline with the following tile or with the endTile int temp1 = tempPerimeter[j].GetX(); int temp2 = tempPerimeter[j + 1].GetX(); bool temp3 = (tempPerimeter[j].GetX() == tempPerimeter[j + 1].GetX()); if (tempPerimeter[j].GetX() == tempPerimeter[j + 1].GetX() || (tempPerimeter[j].GetX() == outerPoint[nextPoint].GetX() && corner.Contains(outerPoint[nextPoint]))) { corner.Add(tempPerimeter[j]); } perimeter.AddTile(tempPerimeter[j]); } } } Tile[] area = new Tile[0]; for (int i = 0; i < perimeter.GetAmountofRows(); i++) { Tile[] rowArray = perimeter.IterateThroughRows(i); for (int j = 0; j < rowArray.Length; j++) { if (!corner.Contains(rowArray[j])) { Tile currTile = rowArray[j]; Tile endTile = rowArray[j + 1]; while (corner.Contains(endTile)) { j++; endTile = rowArray[j + 1]; } for (int k = currTile.GetY(); k <= endTile.GetY(); k++) { Position currPos = new Position(currTile.GetX(), k); TestMain.AddElement <Tile>(ref area, GetTile(currPos)); } j++; } else { TestMain.AddElement <Tile>(ref area, rowArray[j]); } } } return(area); } else { return(null); } }
public Tile[] GetBestPath(Tile startTile, Tile endTile, PathType givenPathType) { if (givenPathType == PathType.IgnoreAll) { SearchAbleArray <Tile> bestPath = new SearchAbleArray <Tile>(); int[] direction = GetDirection(startTile, endTile); bestPath.Add(startTile); Tile lastItem = startTile; if (Mathf.Abs(direction[0]) > Mathf.Abs(direction[1])) { for (int i = 0; i < Mathf.Abs(direction[0]); i++) { Position nextTilepos = bestPath.GetLastItem().GetPosition(); lastItem = GetTile(nextTilepos); //formatting from float to int hack if ((i < (Mathf.Abs((float)direction[1] / 2)) || i >= (Mathf.Abs((float)direction[0]) - (Mathf.Abs((float)direction[1]) / 2)))) { //go diagonal in direction[0] nextTilepos.x += direction[0] / (int)Mathf.Abs(direction[0]); nextTilepos.y += direction[1] / (int)Mathf.Abs(direction[1]); if (direction[1] % 2 == 1 && Mathf.Abs(direction[0]) - i < 1) { direction[1] -= direction[1] / (int)Mathf.Abs(direction[1]); } } else { //go in direction[0] nextTilepos.x += direction[0] / (int)Mathf.Abs(direction[0]); } bestPath.Add(GetTile(nextTilepos)); } return(bestPath.GetOrderedArray()); } else //if (difference < 0) { Position nextTilepos = bestPath.GetLastItem().GetPosition(); for (int i = 0; i < Mathf.Abs(direction[1]); i++) { if ((i < (Mathf.Abs((float)direction[0] / 2)) || i >= (Mathf.Abs((float)direction[1]) - (Mathf.Abs((float)direction[0]) / 2)))) { //go diagonal in direction[1] nextTilepos.x += direction[0] / (int)Mathf.Abs(direction[0]); nextTilepos.y += direction[1] / (int)Mathf.Abs(direction[1]); if (direction[0] % 2 == 1 && Mathf.Abs(direction[0]) - i < 1) { direction[0] -= direction[0] / (int)Mathf.Abs(direction[0]); } } else { //go in direction[1] nextTilepos.y += direction[1] / (int)Mathf.Abs(direction[1]); } bestPath.Add(GetTile(nextTilepos)); } } return(bestPath.GetOrderedArray()); } else { KeyValuePair <float, Tile[]> output = GetDijkstraPath(startTile, endTile, givenPathType); return(output.Value); } }