public void ExecuteGeneration(Transform parentObject) { GameObject mazeObject = new GameObject("Maze"); mazeObject.transform.parent = parentObject; if (LevelData.RoomsCount >= (LevelData.MazeSize.x * 2) * (LevelData.MazeSize.y * 2) * 0.75f) { _fixedRoomsCount = Mathf.RoundToInt((LevelData.MazeSize.x * 2) * (LevelData.MazeSize.y * 2) * 0.75f); } else { _fixedRoomsCount = LevelData.RoomsCount; } _gridX = Mathf.RoundToInt(LevelData.MazeSize.x); _gridY = Mathf.RoundToInt(LevelData.MazeSize.y); bool isValid = false; int x = 0; while (!isValid) { x++; GenerateRooms(); isValid = SetExitRoom(); if (x > 10) { return; } } SetRoomDoors(); InstantiateMaze(mazeObject.transform); OnMazeGenerated?.Invoke(_takenPositions); }
// Currently only uses the recursive backtracking algorithm public void BuildFromOrigin(int rowOrigin, int columnOrigin) { ResetMaze(); BuildOrigin = m_Maze[rowOrigin, columnOrigin]; // recursive backtracking var currentCell = BuildOrigin; currentCell.Status = AbstractMazeCellStatuses.Ready; while (currentCell != null) { // neighbor options var neighborOptions = new List <AbstractMazeCell <T> >(); // push north neighbor if (currentCell.Row - 1 > -1) { if (!m_Maze[currentCell.Row - 1, currentCell.Column].Status.Equals(AbstractMazeCellStatuses.Ready)) { neighborOptions.Add(m_Maze[currentCell.Row - 1, currentCell.Column]); } } // push west neighbor if (currentCell.Column - 1 > -1) { if (!m_Maze[currentCell.Row, currentCell.Column - 1].Status.Equals(AbstractMazeCellStatuses.Ready)) { neighborOptions.Add(m_Maze[currentCell.Row, currentCell.Column - 1]); } } // push east neighbor if (currentCell.Column + 1 < Columns) { if (!m_Maze[currentCell.Row, currentCell.Column + 1].Status.Equals(AbstractMazeCellStatuses.Ready)) { neighborOptions.Add(m_Maze[currentCell.Row, currentCell.Column + 1]); } } // push south neighbor if (currentCell.Row + 1 < Rows) { if (!m_Maze[currentCell.Row + 1, currentCell.Column].Status.Equals(AbstractMazeCellStatuses.Ready)) { neighborOptions.Add(m_Maze[currentCell.Row + 1, currentCell.Column]); } } // if there are options, choose one and push currentCell to stack if (neighborOptions.Count > 0) { DeadEnd = false; // choose a neighbor at random var index = Random.Next(0, neighborOptions.Count); var chosenCell = neighborOptions[index]; // push currentCell onto stack BuildStack.Push(currentCell); // whichever neighbor was chosen needs to have a path declared to and from currentCell if (chosenCell.Row == currentCell.Row) { if (chosenCell.Column == currentCell.Column - 1) // west neighbor { currentCell.West_Neighbor = chosenCell; chosenCell.East_Neighbor = currentCell; } else // east neighbor => chosenCell.Column == currentCell.Column + 1 { currentCell.East_Neighbor = chosenCell; chosenCell.West_Neighbor = currentCell; } } else { if (chosenCell.Row == currentCell.Row - 1) // north neighbor { currentCell.North_Neighbor = chosenCell; chosenCell.South_Neighbor = currentCell; } else // south neighbor => chosenCell.Row == currentCell.Row + 1 { currentCell.South_Neighbor = chosenCell; chosenCell.North_Neighbor = currentCell; } } // make chosen into current after processing chosenCell.Status = AbstractMazeCellStatuses.Ready; currentCell = chosenCell; } // there are no neighbor options, pop a cell off the stack and make it current else { OnFinalProcessingCell?.Invoke(currentCell); if (!DeadEnd) { DeadEnd = true; OnDeadEndCreation?.Invoke(currentCell); } if (BuildStack.Count > 0) { currentCell = BuildStack.Pop(); } else { currentCell = null; } } } // the origin is always a dead end, too OnDeadEndCreation?.Invoke(BuildOrigin); // the maze is generated OnMazeGenerated?.Invoke(m_Maze); }