// Solve the maze using a depth-first traversal algorithm public void SolveMaze() { //System.Random rand2 = new System.Random((int)DateTime.Now.Ticks); if (!gen) return; // Check if the maze has been solved if (solutionPath != null) solutionPath = null; Stack<Cell> PathStack = new Stack<Cell>(); int r, c; Cell EndCell, CurrentCell, SelectedCell; EndCell.row = endR; EndCell.col = nC - 1; EndCell.visited = false; CurrentCell.row = startR; CurrentCell.col = 0; CurrentCell.visited = false; visited[startR, 0] = true; for (r = 0; r < nR; r++) for (c = 0; c < nC; c++) visited[r, c] = false; visited[startR, 0] = true; int nvisited = 0; // for search performance measure int visitedIndex; Cell[] T = new Cell[4]; r = CurrentCell.row; c = CurrentCell.col; while ((CurrentCell.row != EndCell.row) || (CurrentCell.col != EndCell.col)) { visitedIndex = 0; for (int i = 0; i < 4; i++) { T[i].visited = true; } //check north cell if (r != (nR - 1)) { if ((!northWall[r, c]) && (!visited[r + 1, c])) { T[visitedIndex].row = r + 1; T[visitedIndex].col = c; T[visitedIndex].visited = false; visitedIndex++; } } if (c != (nC - 1)) { //check east cell if ((!eastWall[r, c]) && (!visited[r, c + 1])) { T[visitedIndex].row = r; T[visitedIndex].col = c + 1; T[visitedIndex].visited = false; visitedIndex++; } } if (c != 0) { //check west cell if ((!eastWall[r, c - 1]) && (!visited[r, c - 1])) { T[visitedIndex].row = r; T[visitedIndex].col = c - 1; T[visitedIndex].visited = false; visitedIndex++; } } if (r != 0) { //check south cell if ((!northWall[r - 1, c]) && (!visited[r - 1, c])) { T[visitedIndex].row = r - 1; T[visitedIndex].col = c; T[visitedIndex].visited = false; visitedIndex++; } } if (visitedIndex > 0) { //If there is at least one cell unvisited, randomly select one SelectedCell = T[rand.Next() % visitedIndex]; //push the current cell onto the stack PathStack.Push(CurrentCell); //choose the selected cell as current cell CurrentCell = SelectedCell; r = CurrentCell.row; c = CurrentCell.col; CurrentCell.visited = true; visited[r, c] = true; nvisited++; } else { // If there is no cell unvisited, pop cell from the stack; // The poped cell is not part of the solution path. CurrentCell = PathStack.Pop(); r = CurrentCell.row; c = CurrentCell.col; CurrentCell.visited = true; visited[r, c] = true; nvisited++; } } if (PathStack.Count > 0) { solutionPath = new Cell[PathStack.Count]; PathStack.CopyTo(solutionPath, 0); // Solution path is in reversed order } Debug.Log("SolotuonPath : Number of nodes visited = " + nvisited.ToString()); Debug.Log("SolutionPath : Path length = " + solutionPath.Length.ToString()); }
// Generate a maze using a depth-first search algorithm with more horizontal influence public void GenerateMaze2() { //System.Random rand2 = new System.Random((int)DateTime.Now.Ticks); Stack<Cell> CellStack = new Stack<Cell>(); int TotalCells = nR * nC; Cell CurrentCell, SelectedCell; int VisitedCells; // Randomly select one cell as current cell //setBarrierCell(); int r = rand.Next() % nR; int c = rand.Next() % nC; CurrentCell.row = r; CurrentCell.col = c; CurrentCell.visited = false; visited[r, c] = true; VisitedCells = 1; int visitedIndex; Cell[] T = new Cell[4]; bool isEast = false; int indexEast = 0; bool isWest = false; int indexWest = 0; while (VisitedCells < TotalCells) { visitedIndex = 0; isEast = false; isWest = false; for (int i = 0; i < 4; i++) { T[i].visited = true; } // Check north cell if (r != (nR - 1)) { if (!visited[r + 1, c]) { T[visitedIndex].row = r + 1; T[visitedIndex].col = c; T[visitedIndex].visited = false; visitedIndex++; } } // Check west cell if (c != 0) { if (!visited[r, c - 1]) { isWest = true; indexWest = visitedIndex; T[visitedIndex].row = r; T[visitedIndex].col = c - 1; T[visitedIndex].visited = false; visitedIndex++; } } // Check south cell if (r != 0) { if (!visited[r - 1, c]) { T[visitedIndex].row = r - 1; T[visitedIndex].col = c; T[visitedIndex].visited = false; visitedIndex++; } } // Check east cell if (c != nC - 1) { if (!visited[r, c + 1]) { isEast = true; indexEast = visitedIndex; T[visitedIndex].row = r; T[visitedIndex].col = c + 1; T[visitedIndex].visited = false; visitedIndex++; } } if (visitedIndex > 0) { // Select East or West unvisited cell first if there is any; // otherwiese randomly select one if (isWest) SelectedCell = T[indexWest]; //else if (isEast) // SelectedCell = T[indexEast]; else // If there is at least one cell unvisited, randomly select one. SelectedCell = T[rand.Next() % visitedIndex]; // Knock down the wall between these two cells. // Note: (r,c) is the CurrentCell. if ((SelectedCell.row == (r + 1)) && (SelectedCell.col == c)) northWall[r, c] = false; if ((SelectedCell.row == r) && (SelectedCell.col == (c - 1))) eastWall[r, c - 1] = false; if ((SelectedCell.row == (r - 1)) && (SelectedCell.col == c)) northWall[r - 1, c] = false; if ((SelectedCell.row == r) && (SelectedCell.col == (c + 1))) eastWall[r, c] = false; CellStack.Push(CurrentCell); // Choose the selected cell as the current cell CurrentCell = SelectedCell; r = CurrentCell.row; c = CurrentCell.col; visited[r, c] = true; VisitedCells++; } else { //If there is no cell unvisited, pop cell from the stack CurrentCell = CellStack.Pop(); r = CurrentCell.row; c = CurrentCell.col; visited[r, c] = true; } } CellStack.Clear(); // Randomly select the start and end cell startR = rand.Next() % nR; endR = rand.Next() % (nR - 1) + 1; //endR = rand.Next() % nR; eastWall[endR, (nC - 1)] = false; //removeWalls(30); // Set the gen flag and clear the solution path gen = true; solutionPath = null; path = null; }