public IEnumerator AnimatedGeneration(IEnumerable <GraphVertex> maze, GameObject vertexPrefab, float deltaTime) { // Initialization List <GraphVertex> elementsToProcess = new List <GraphVertex>(); IEnumerator <GraphVertex> enumerator = maze.GetEnumerator(); enumerator.MoveNext(); GraphVertex first = enumerator.Current; first.SetVisited(); foreach (GraphVertex gv in first.GetMarkedNeighbours(MarkType.Unvisited)) { elementsToProcess.Add(gv); } // Process GraphVertex gvToProcess; GraphVertex gvToLinkTo; while (elementsToProcess.Count != 0) { // Get the cells to link gvToProcess = elementsToProcess [Random.Range(0, elementsToProcess.Count)]; gvToLinkTo = gvToProcess.GetRandomMarkedNeighbour(MarkType.Visited); // Link the cells gvToProcess.RemoveBorderBetweenCells(gvToLinkTo); // Setup the next iteration gvToProcess.SetVisited(); elementsToProcess.Remove(gvToProcess); foreach (GraphVertex gv in gvToProcess.GetMarkedNeighbours(MarkType.Unvisited)) { // We add each unmarked adjacent cell as long as it is not already in the list if (!elementsToProcess.Contains(gv)) { elementsToProcess.Add(gv); } } // Visualization Manager.ClearMazeObjects(); MazeViewer.DisplayGrid(maze, vertexPrefab); yield return(new WaitForSecondsRealtime(deltaTime)); } Manager.ClearMazeObjects(); MazeViewer.DisplayGrid(maze, vertexPrefab); }
// Generates the maze according to the current attributes public void GenerateMaze() { // Delete the previous maze (if any) Manager.ClearMazeObjects(); // Construction of the initial maze, with walls everywhere IEnumerable <GraphVertex> maze = UndirectedGraph.GridCellUndirectedGraph(1, this.nbLines, this.nbColumns, this.nbBorders, this.allowTeleporters); // Selection of the right generator MazeGenerator generator = null; switch (this.genType) { case GeneratorType.DFS: { generator = new DFSGenerator(); break; } case GeneratorType.Prim: { generator = new PrimGenerator(); break; } case GeneratorType.Wilson: { generator = new WilsonGenerator(); break; } } // Generation of the maze if (this.animated) { currentCoroutine = generator.AnimatedGeneration(maze, vertexPrefab, 0); StartCoroutine(currentCoroutine); } else { generator.Generate(maze); MazeViewer.DisplayGrid(maze, vertexPrefab); } // Center the camera on the maze SetupCamera(maze); // Add a character to the maze GameObject.Instantiate(character); }
public void init() { // Ensure MazeViewer object is initialized; // Populate notMaze with vectors of all cells. viewer = gameObject.GetComponent <MazeViewer>(); if (!viewer.initFlag) { viewer.init(); } maze = new HashSet <WilsonCell>(); mazeCoords = new HashSet <Vector2Int>(); notMaze = new HashSet <Vector2Int>(); trail = new HashSet <Vector2Int>(); orderedTrail = new List <Vector2Int>(); moves = new List <Vector2Int>(); Random.InitState(seed); mazeCount = maze.Count; iterations = 0; maxCells = sizeX * sizeY; targetCells = (int)(maxCells * cellDensity); for (int x = 0; x < sizeX; x++) { for (int y = 0; y < sizeY; y++) { notMaze.Add(new Vector2Int(x, y)); } } //Initialize maze. if (mazeCount < 1) { Vector2Int initial = new Vector2Int(Random.Range(0, sizeX - 1), Random.Range(0, sizeY - 1)); maze.Add(new WilsonCell(initial)); mazeCoords.Add(initial); notMaze.Remove(initial); } viewer.RefreshEmpty(); viewer.RefreshMaze(); initFlag = true; }
public IEnumerator AnimatedGeneration(IEnumerable <GraphVertex> maze, GameObject vertexPrefab, float deltaTime) { // Initialization Stack <GraphVertex> stack = new Stack <GraphVertex>(); IEnumerator <GraphVertex> enumerator = maze.GetEnumerator(); enumerator.MoveNext(); GraphVertex current = enumerator.Current; stack.Push(current); // Algorithm GraphVertex next; while (!(stack.Count == 0)) { current = stack.Peek(); current.SetVisited(); next = current.GetRandomMarkedNeighbour(MarkType.Unvisited); if (next == null) // dead end, every neighbour of the current cell has been visited { stack.Pop(); } else { current.RemoveBorderBetweenCells(next); stack.Push(next); } // Visualization Manager.ClearMazeObjects(); MazeViewer.DisplayGrid(maze, vertexPrefab); yield return(new WaitForSecondsRealtime(deltaTime)); } }
public IEnumerator AnimatedGeneration(IEnumerable <GraphVertex> maze, GameObject vertexPrefab, float deltaTime) { // Initialization Stack <GraphVertex> currentPath = new Stack <GraphVertex>(); IEnumerator <GraphVertex> enumerator = maze.GetEnumerator(); enumerator.MoveNext(); GraphVertex first = enumerator.Current; first.SetVisited(); List <GraphVertex> processedGV = new List <GraphVertex> (); processedGV.Add(first); // Process GraphVertex previous = first; GraphVertex next = first.GetRandomMarkedNeighbour(MarkType.Unvisited); next.Mark = MarkType.TemporaryVisited; currentPath.Push(next); while (currentPath.Count != 0) { List <GraphVertex> list = currentPath.Peek().Neighbours; list.Remove(previous); // we don't want to go back on our step (yet) previous = next; // Update of the next cell to check int randomIndex = Random.Range(0, list.Count); next = list [randomIndex]; if (next.Mark == MarkType.Visited) { // We have reached the maze so we backtrack the path to process it while (currentPath.Count > 1) { GraphVertex gv = currentPath.Pop(); gv.RemoveBorderBetweenCells(currentPath.Peek()); gv.SetVisited(); processedGV.Add(gv); } GraphVertex lastGv = currentPath.Pop(); lastGv.RemoveBorderBetweenCells(first); lastGv.SetVisited(); processedGV.Add(lastGv); // Setup for the next path, we choose a new starting point foreach (GraphVertex gv in processedGV) { GraphVertex tempSecond = gv.GetRandomMarkedNeighbour(MarkType.Unvisited); if (tempSecond != null) { first = gv; previous = first; next = tempSecond; next.Mark = MarkType.TemporaryVisited; currentPath.Push(next); break; } } // Visualization Manager.ClearMazeObjects(); MazeViewer.DisplayGrid(maze, vertexPrefab); yield return(new WaitForSecondsRealtime(deltaTime)); } else if (currentPath.Contains(next)) { // There is a loop in the path so we restart the path while (currentPath.Count != 0) { currentPath.Pop().Mark = MarkType.Unvisited; } // Setup for the rebooted path previous = first; next = first.GetRandomMarkedNeighbour(MarkType.Unvisited); next.Mark = MarkType.TemporaryVisited; currentPath.Push(next); } else { // We add "next" to the current path next.Mark = MarkType.TemporaryVisited; currentPath.Push(next); } } MazeViewer.DisplayGrid(maze, vertexPrefab); }
private void Awake() { viewer = GetComponent <MazeViewer>(); }