void Expandir(SearchVertex vertice) { next.Remove(vertice); TacarFogo(vertice.down); TacarFogo(vertice.left); TacarFogo(vertice.right); TacarFogo(vertice.up); }
void TacarFogo(SearchVertex vertice) { if (vertice && vertice.areaState == AreaState.normal) { vertice.GetComponent <Renderer>().material.color = Color.red; vertice.areaState = AreaState.fire; next.Add(vertice); } }
bool Check(SearchVertex vertice) { if (vertice && vertice.areaState == AreaState.normal) { return(true); } else { return(false); } }
IEnumerator DFS(SearchVertex vertex) { yield return(new WaitForSeconds(0.5f)); vertex.GetComponent <Renderer>().material.color = Color.red; vertex.areaState = AreaState.fire; if (Check(vertex.down)) { yield return(StartCoroutine(DFS(vertex.down))); } if (Check(vertex.left)) { yield return(StartCoroutine(DFS(vertex.left))); } if (Check(vertex.up)) { yield return(StartCoroutine(DFS(vertex.up))); } if (Check(vertex.right)) { yield return(StartCoroutine(DFS(vertex.right))); } }
protected override void updatePathToTarget() { _currentPath.Clear(); _agenda.Clear(); _closedSet.Clear(); SearchVertex startVertex = new SearchVertex(); startVertex.parent = null; startVertex.numHops = 0; startVertex.gridPos = _targetGridPos; startVertex.costFromStart = 0; Vector2 targetPos = toGridCoord(_tileWereChasing.transform.position); startVertex.estimatedCostToTarget = estimatePathDistance(startVertex.gridPos, targetPos); _agenda.Add(startVertex); // We have a max hops so that we don't spend too long searching in vain. int maxHops = maxSearchDepth; while (_agenda.Count > 0) { float minCost = _agenda[0].estimatedCostToTarget; SearchVertex currentVertex = _agenda[0]; foreach (SearchVertex vertex in _agenda) { if (vertex.estimatedCostToTarget < minCost) { minCost = vertex.estimatedCostToTarget; currentVertex = vertex; } } _agenda.Remove(currentVertex); _closedSet.Add(currentVertex); if (currentVertex.gridPos == targetPos) { // If we made it to our target, reconstruct the path by going back up the parents. do { _currentPath.Add(currentVertex.gridPos); currentVertex = currentVertex.parent; } while (currentVertex != null); // Need to reverse the path before we return it. _currentPath.Reverse(); return; } // First, check to see if we've gone too far. if (currentVertex.numHops >= maxHops) { continue; // Don't expand if we're already too far. } for (int x = (int)currentVertex.gridPos.x - 1; x <= (int)currentVertex.gridPos.x + 1; x++) { for (int y = (int)currentVertex.gridPos.y - 1; y <= (int)currentVertex.gridPos.y + 1; y++) { if (x == (int)currentVertex.gridPos.x && y == (int)currentVertex.gridPos.y) { continue; // Ignore our own coordinate. } Vector2 neighborPos = new Vector2(x, y); // We ignore the neighbor if it's in the closed set if (listContainsPosition(_closedSet, neighborPos)) { continue; } // Now check if we can even move onto that spot. if (!canMoveBetweenPoints(currentVertex.gridPos, neighborPos, pathColliderRadius)) { continue; } // Now we have to see if the vertex is aleady in the agenda. float tentativeCostFromStart = currentVertex.costFromStart + Vector2.Distance(currentVertex.gridPos, neighborPos); SearchVertex neighborVertex = null; foreach (SearchVertex vertex in _agenda) { if (vertex.gridPos == neighborPos) { neighborVertex = vertex; break; } } if (neighborVertex == null) { neighborVertex = new SearchVertex(); neighborVertex.gridPos = neighborPos; neighborVertex.costFromStart = tentativeCostFromStart; neighborVertex.estimatedCostToTarget = tentativeCostFromStart + estimatePathDistance(neighborPos, targetPos); neighborVertex.parent = currentVertex; neighborVertex.numHops = currentVertex.numHops + 1; _agenda.Add(neighborVertex); } else { if (tentativeCostFromStart < neighborVertex.costFromStart) { neighborVertex.costFromStart = tentativeCostFromStart; neighborVertex.estimatedCostToTarget = tentativeCostFromStart + estimatePathDistance(neighborPos, targetPos); neighborVertex.parent = currentVertex; neighborVertex.numHops = currentVertex.numHops + 1; } } } } } // If we never reached the target, use the node from the closed set with the smallest estimated distance to target. if (_closedSet.Count == 0) { return; } SearchVertex closestVertex = _closedSet[0]; float closestVertexDistance = Vector2.Distance(closestVertex.gridPos, targetPos); foreach (SearchVertex vertex in _closedSet) { float vertexDistance = Vector2.Distance(vertex.gridPos, targetPos); if (vertexDistance < closestVertexDistance) { closestVertex = vertex; closestVertexDistance = vertexDistance; } } do { _currentPath.Add(closestVertex.gridPos); closestVertex = closestVertex.parent; } while (closestVertex != null); _currentPath.Reverse(); }
protected virtual void updatePathToTarget() { _currentPath.Clear(); _agenda.Clear(); _closedSet.Clear(); SearchVertex startVertex = new SearchVertex(); startVertex.parent = null; startVertex.numHops = 0; startVertex.gridPos = _targetGridPos; Vector2 targetPos = toGridCoord(_tileWereChasing.transform.position); _agenda.Add(startVertex); // We have a max hops so that we don't spend too long searching in vain. int maxHops = maxSearchDepth; while (_agenda.Count > 0) { SearchVertex currentVertex = _agenda[0]; _agenda.RemoveAt(0); _closedSet.Add(currentVertex); if (currentVertex.gridPos == targetPos) { // If we made it to our target, reconstruct the path by going back up the parents. do { _currentPath.Add(currentVertex.gridPos); currentVertex = currentVertex.parent; } while (currentVertex != null); // Need to reverse the path before we return it. _currentPath.Reverse(); return; } // Otherwise, time to expand all the neighbors of the vertex. // First, check to see if we've gone too far. if (currentVertex.numHops >= maxHops) { continue; // Don't expand if we're already too far. } // We can use a loop to iterate through the neighbor points. for (int x = (int)currentVertex.gridPos.x - 1; x <= (int)currentVertex.gridPos.x + 1; x++) { for (int y = (int)currentVertex.gridPos.y - 1; y <= (int)currentVertex.gridPos.y + 1; y++) { if (x == (int)currentVertex.gridPos.x && y == (int)currentVertex.gridPos.y) { continue; // Ignore our own coordinate. } Vector2 neighborPos = new Vector2(x, y); // We ignore the neighbor if it's in the closed set or Already in the agenda. if (listContainsPosition(_agenda, neighborPos) || listContainsPosition(_closedSet, neighborPos)) { continue; } // Now check if we can even move onto that spot. if (!canMoveBetweenPoints(currentVertex.gridPos, neighborPos, pathColliderRadius)) { continue; } // Otherwise, the neighbor can go in the agenda! SearchVertex neighborVertex = new SearchVertex(); neighborVertex.gridPos = neighborPos; neighborVertex.parent = currentVertex; neighborVertex.numHops = currentVertex.numHops + 1; _agenda.Add(neighborVertex); } } } }
private IEnumerable <IEdge> Backtrack(Dictionary <int, SearchVertex> vertices, SearchVertex end) { if (end.ShortestDistance == 0) { yield break; } var lastLeg = end.Connections .Select(edge => new { Other = vertices[edge.Vertex1ID == end.ID ? edge.Vertex2ID : edge.Vertex1ID], Edge = edge }) .Where(edge => edge.Other.ShortestDistance == end.ShortestDistance - edge.Edge.Weight) .First(); foreach (var edge in Backtrack(vertices, lastLeg.Other)) { yield return(edge); } yield return(lastLeg.Edge); }
public override void fillRoom(LevelGenerator ourGenerator, ExitConstraint requiredExits) { bool[,] wallMap = new bool[LevelGenerator.ROOM_WIDTH, LevelGenerator.ROOM_HEIGHT]; // Start completely filled with walls. for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++) { for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++) { wallMap[x, y] = true; } } bool foundStartPos = false; Vector2 startPos = new Vector2(Random.Range(0, LevelGenerator.ROOM_WIDTH), Random.Range(0, LevelGenerator.ROOM_HEIGHT)); foreach (Vector2Int exitLocation in requiredExits.requiredExitLocations()) { wallMap[exitLocation.x, exitLocation.y] = false; if (!foundStartPos) { startPos = exitLocation; foundStartPos = true; } } _agenda.Clear(); _closed.Clear(); SearchVertex startVertex = new SearchVertex(); startVertex.gridPos = startPos; startVertex.parent = null; _agenda.Add(startVertex); while (_agenda.Count > 0) { SearchVertex currentVertex = _agenda[_agenda.Count - 1]; _agenda.RemoveAt(_agenda.Count - 1); if (listContainsVertex(_closed, currentVertex.gridPos)) { continue; } _closed.Add(currentVertex); _neighbors.Clear(); Vector2 neighborPos = currentVertex.gridPos + Vector2.up * 2; if (inGrid(neighborPos) && !listContainsVertex(_closed, neighborPos)) { _neighbors.Add(neighborPos); } neighborPos = currentVertex.gridPos + Vector2.right * 2; if (inGrid(neighborPos) && !listContainsVertex(_closed, neighborPos)) { _neighbors.Add(neighborPos); } neighborPos = currentVertex.gridPos - Vector2.up * 2; if (inGrid(neighborPos) && !listContainsVertex(_closed, neighborPos)) { _neighbors.Add(neighborPos); } neighborPos = currentVertex.gridPos - Vector2.right * 2; if (inGrid(neighborPos) && !listContainsVertex(_closed, neighborPos)) { _neighbors.Add(neighborPos); } if (_neighbors.Count > 0) { GlobalFuncs.shuffle(_neighbors); } else { currentVertex.isDeadEnd = true; } foreach (Vector2 neighbor in _neighbors) { SearchVertex neighborVertex = new SearchVertex(); neighborVertex.gridPos = neighbor; neighborVertex.parent = currentVertex; _agenda.Add(neighborVertex); } } // Now go through the closed set and carve out space for all of the neighbors. foreach (SearchVertex vertex in _closed) { if (vertex.parent == null) { wallMap[(int)vertex.gridPos.x, (int)vertex.gridPos.y] = false; continue; } int currentX = (int)vertex.gridPos.x; int currentY = (int)vertex.gridPos.y; wallMap[currentX, currentY] = false; Vector2 endPos = vertex.parent.gridPos; int targetX = (int)endPos.x; int targetY = (int)endPos.y; while (currentX != targetX || currentY != targetY) { if (currentX < targetX) { currentX++; } else if (currentX > targetX) { currentX--; } if (currentY < targetY) { currentY++; } else if (currentY > targetY) { currentY--; } wallMap[currentX, currentY] = false; } } // Now we remove some extra walls List <Vector2> wallLocations = new List <Vector2>(); for (int i = 0; i < extraWallsToRemove; i++) { wallLocations.Clear(); for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++) { for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++) { if (wallMap[x, y]) { wallLocations.Add(new Vector2(x, y)); } } } if (wallLocations.Count > 1) { Vector2 wallToRemove = GlobalFuncs.randElem(wallLocations); wallMap[(int)wallToRemove.x, (int)wallToRemove.y] = false; } } for (int x = 0; x < LevelGenerator.ROOM_WIDTH; x++) { for (int y = 0; y < LevelGenerator.ROOM_HEIGHT; y++) { if (wallMap[x, y]) { Tile.spawnTile(ourGenerator.normalWallPrefab, transform, x, y); } } } }