/// <summary> /// Creates a maze by linking cells using Eller's algorithm /// </summary> /// <param name="service"></param> public override void CreateMaze(MazeGenerationService service) { //create data structures necessary for algorithm to work MazeCell[,] gridcells = service.Cells; MazeCell[] cells = gridcells.Cast <MazeCell>().ToArray(); //assign maze cells their set numbers AssignSetNumbers(gridcells, service.DebugMode); for (int y = 0; y < gridcells.GetLength(1); y++) { for (int x = 0; x < gridcells.GetLength(0); x++) { //mark cell as visited MazeCell cell = gridcells[x, y]; cell.MarkAsVisited(); List <MazeCell> neighbours = service.GetNeighboursNotPartOfSet(cell); if (neighbours.Count > 0) { //pick a random neighbour not part of the cells set and create passage between cell and neighbour MazeCell randomNeighbour = neighbours[Random.Range(0, neighbours.Count)]; randomNeighbour.CreatePassage(cell); cell.CreatePassage(randomNeighbour); //all the cells belonging to the set the random neighbour belongs to are overtaken by the cell's set MazeCell[] set = cells.Where(c => c.NumberValue == randomNeighbour.NumberValue).ToArray(); foreach (MazeCell overtakableCell in set) { overtakableCell.SetNumberValue(cell.NumberValue); } } } } }
/// <summary> /// Returns an enumerator that creates a maze by linking cells using Kruskal's algorithm /// </summary> /// <param name="service"></param> /// <returns></returns> public override IEnumerator CreateMazeRoutine(MazeGenerationService service) { //assign each maze cell a number indicating which set it belongs to AssignSetNumbers(service.Cells, service.DebugMode); //create data structures necessary for algorithm to work MazeCell[] cells = service.Cells.Cast <MazeCell>().ToArray(); List <MazeCell> bag = new List <MazeCell>(cells); //loop while bag is not not empty while (bag.Count != 0) { //pick a random cell and mark it as visited MazeCell randomCell = bag[Random.Range(0, bag.Count)]; randomCell.MarkAsVisited(); //fetch the neigbours of this cell that are not part of the same set List <MazeCell> neighbours = service.GetNeighboursNotPartOfSet(randomCell); if (neighbours.Count > 0) { //pick a random neighbour and mark it as visited MazeCell randomNeighbour = neighbours[Random.Range(0, neighbours.Count)]; randomNeighbour.MarkAsVisited(); //link the random neighbour with the random cell randomNeighbour.CreatePassage(randomCell); randomCell.CreatePassage(randomNeighbour); //all the cells belonging to the set the random neighbour belongs to are overtaken by the random cell's set MazeCell[] set = cells.Where(c => c.NumberValue == randomNeighbour.NumberValue).ToArray(); foreach (MazeCell overtakableCell in set) { overtakableCell.SetNumberValue(randomCell.NumberValue); } } else { //if all neighbours of the cel are part of the same set, remove the cell from the bag bag.Remove(randomCell); } yield return(null); } CompletedRoutine(); }