internal override IEnumerable <MazeTransformationStep> InternalGenerateMazeFullSize() { InitializeMaze(); entrance = new MazeCoordinate(upperleft.X + 1 + Random.Next(this.CurrentMaze.GetWidth() - 2), upperleft.Y); pointStack.Push(entrance); Nullable <MazeCoordinate> newCorridor; while (pointStack.Count() != 0) { newCorridor = FindWay(); if (newCorridor == null) { newCorridor = pointStack.Pop(); // One step back if (newCorridor != null && CurrentMaze.WouldChangeMazeFieldType(newCorridor.Value, MazeFieldType.Corridor)) { yield return(CurrentMaze.SetMazeTypeOnPos(newCorridor.Value, MazeFieldType.Corridor)); } } else { pointStack.Push(newCorridor.Value); yield return(CurrentMaze.SetMazeTypeOnPos(newCorridor.Value, MazeFieldType.Corridor)); } } yield return(TryPlaceEntrance()); yield return(TryPlaceExit()); }
internal override MazeTransformationStep TryPlaceExit() { List <MazeCoordinate> possibleExits = new List <MazeCoordinate>(); // collect all possible exits for (int i = CurrentMaze.GetWidth() - 2; i >= 1; i--) { possibleExits.Add(new MazeCoordinate(i, downright.Y)); } // check in random order if exit is valid while (possibleExits.Count > 0) { var possibleExit = possibleExits.ElementAt(Random.Next(possibleExits.Count)); if (CurrentMaze.GetMazeTypeOnPos(possibleExit.X, possibleExit.Y + 1) == MazeFieldType.Corridor) { return(CurrentMaze.SetMazeTypeOnPos(possibleExit, MazeFieldType.Exit)); } else { possibleExits.Remove(possibleExit); } } // TODO Maybe not the best way to handle this, but the maze is useless without valid exit. throw new Exception("Could not find a suitable exit position."); }
private IEnumerable <MazeTransformationStep> RekursiveDiv(MazeCoordinate recUpperleft, MazeCoordinate recDownright, bool horizontal) { int width = recDownright.X - recUpperleft.X; int height = recUpperleft.Y - recDownright.Y; int minSize = 0; Strategy currentStrategy = CheckWhichStrategyToUse(width, height); if (!(width < minSize && height < minSize)) { // Override the random decision for horizontal/vertical wall placement, this reduces long stretched corridors if (width > height) { horizontal = false; } else { horizontal = true; } if (horizontal) {// Horizontal int newWallY = TryPlaceWallHorizontal(recUpperleft, recDownright, currentStrategy); if (newWallY > 0) { for (int i = 1; i < width; i++) { // Create wall yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(recUpperleft.X + i, newWallY), MazeFieldType.Wall)); } // Place corridor int randX = FindHorizontalCorridor(ref recUpperleft, ref recDownright); yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(randX, newWallY), MazeFieldType.Corridor)); // up MazeCoordinate upperleftNew = new MazeCoordinate(recUpperleft.X, recUpperleft.Y); MazeCoordinate downrightNew = new MazeCoordinate(recDownright.X, newWallY); foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0)) { yield return(recursiveResult); } // down upperleftNew = new MazeCoordinate(recUpperleft.X, newWallY); downrightNew = new MazeCoordinate(recDownright.X, recDownright.Y); foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0)) { yield return(recursiveResult); } } } else {// Vertical int newWallX = TryPlaceWallVertical(recUpperleft, recDownright, currentStrategy); if (newWallX > 0) { for (int i = 1; i < height; i++) { // Create Wall yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(newWallX, recDownright.Y + i), MazeFieldType.Wall)); } // Place corridor int randY = FindVerticalCorridor(ref recUpperleft, ref recDownright); yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(newWallX, randY), MazeFieldType.Corridor)); //left MazeCoordinate upperleftNew = new MazeCoordinate(recUpperleft.X, recUpperleft.Y); MazeCoordinate downrightNew = new MazeCoordinate(newWallX, recDownright.Y); foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0)) { yield return(recursiveResult); } //right upperleftNew = new MazeCoordinate(newWallX, recUpperleft.Y); downrightNew = new MazeCoordinate(recDownright.X, recDownright.Y); foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0)) { yield return(recursiveResult); } } } } }