public void Play() { //Sanitize the input OptionsController.instance.MapSize = Mathf.Max(mapSize.text == "" ? OptionsController.instance.defaultMapSize : int.Parse(mapSize.text), 2); int MapSizeLocal = OptionsController.instance.MapSize; OptionsController.instance.XStart = Mathf.Clamp(startX.text == "" ? OptionsController.instance.defaultXStart : int.Parse(startX.text), 0, OptionsController.instance.MapSize - 1); OptionsController.instance.YStart = Mathf.Clamp(startY.text == "" ? OptionsController.instance.defaultYStart : int.Parse(startY.text), 0, OptionsController.instance.MapSize - 1); OptionsController.instance.XEnd = Mathf.Clamp(endX.text == "" ? OptionsController.instance.defaultXEnd : int.Parse(endX.text), 0, OptionsController.instance.MapSize - 1); OptionsController.instance.YEnd = Mathf.Clamp(endY.text == "" ? OptionsController.instance.defaultYEnd : int.Parse(endY.text), 0, OptionsController.instance.MapSize - 1); int distanceFromStartToEnd = PathfinderHelper.ManhattanDistance(OptionsController.instance.XStart, OptionsController.instance.YStart, OptionsController.instance.XEnd, OptionsController.instance.YEnd); OptionsController.instance.NumberOfObstacles = Mathf.Clamp(numberOfObstacles.text == "" ? OptionsController.instance.defaultNumberOfObstacles : int.Parse(numberOfObstacles.text), 0, MapSizeLocal * MapSizeLocal - distanceFromStartToEnd + 1); //load the simulation scene SceneManager.LoadScene("SimulationScene"); }
private void GenerateMap() { //Generate map filled with blockers List <Vector2Int> blockers = new List <Vector2Int>(); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { map[i, j] = TileType.Blocked; blockers.Add(new Vector2Int(i, j)); } } //Here we "dig" through blocked, generating a random path that is always guided towards the end. //This effectivelly removes minimum number of blockers to ensure the path exists int StartEndDistance = PathfinderHelper.ManhattanDistance(StartX, StartY, EndX, EndY); int xOffset = EndX - StartX; int yOffset = EndY - StartY; int DigX = 0; int DigY = 0; Random.InitState(System.DateTime.Now.Second); map[StartX, StartY] = TileType.Free; blockers.Remove(new Vector2Int(StartX, StartY)); for (int i = 0; i < StartEndDistance; i++) { if (Random.value < 0.5) { if (xOffset == 0) { if (yOffset > 0) { DigY++; yOffset--; } if (yOffset < 0) { DigY--; yOffset++; } } else { if (xOffset > 0) { DigX++; xOffset--; } if (xOffset < 0) { DigX--; xOffset++; } } } else { if (yOffset == 0) { if (xOffset > 0) { DigX++; xOffset--; } if (xOffset < 0) { DigX--; xOffset++; } } else { if (yOffset > 0) { DigY++; yOffset--; } if (yOffset < 0) { DigY--; yOffset++; } } } map[StartX + DigX, StartY + DigY] = TileType.Free; blockers.Remove(new Vector2Int(StartX + DigX, StartY + DigY)); } //Randomly remove blockers so that only specified amount is left int numBlockersToRemove = n * n - OptionsController.instance.NumberOfObstacles - StartEndDistance - 1; for (int i = 0; i < numBlockersToRemove; i++) { int indexToRemove = Random.Range(0, blockers.Count - 1); Vector2Int elementToRemove = blockers[indexToRemove]; map[elementToRemove.x, elementToRemove.y] = TileType.Free; blockers.RemoveAt(indexToRemove); } }
public void GreedyManhattanAlgorithm(Vector2Int start, Vector2Int end) { Queue <Vector2Int> frontier = new Queue <Vector2Int>(); frontier.Enqueue(start); Dictionary <Vector2Int, Vector2Int> cameFrom = new Dictionary <Vector2Int, Vector2Int>(); cameFrom.Add(start, start); List <Vector2Int> visited = new List <Vector2Int>(); while (frontier.Count != 0) { Vector2Int current = frontier.Dequeue(); visited.Add(current); pathFollowed.Add(current); List <Vector2Int> neighbours = GetNeighbours(current); Vector2Int cameFromLocal; cameFrom.TryGetValue(current, out cameFromLocal); neighbours.Remove(cameFromLocal); //Remove visited neighbours List <Vector2Int> neighboursToRemove = new List <Vector2Int>(); foreach (Vector2Int neighbour in neighbours) { if (visited.Contains(neighbour)) { neighboursToRemove.Add(neighbour); } } foreach (Vector2Int neighbour in neighboursToRemove) { neighbours.Remove(neighbour); FoundPath.Remove(current); } //Sort neighbours so the element closest to the end (Using Manhattan distance) is first neighbours.Sort(delegate(Vector2Int a, Vector2Int b) { int aManhattan = PathfinderHelper.ManhattanDistance(a.x, a.y, end.x, end.y); int bManhattan = PathfinderHelper.ManhattanDistance(b.x, b.y, end.x, end.y); if (aManhattan > bManhattan) { return(1); } if (aManhattan < bManhattan) { return(-1); } return(0); }); //If there is a neighbour, check him. Otherwise, backtrack if (neighbours.Count > 0) { Vector2Int nextNeighbour = neighbours[0]; FoundPath.Add(current); if (nextNeighbour == end) { pathFollowed.Add(nextNeighbour); return; } else { frontier.Enqueue(nextNeighbour); cameFrom.Add(nextNeighbour, current); visited.Add(current); } } else { frontier.Enqueue(cameFromLocal); FoundPath.Remove(current); } } }