private LabyrinthDungeon CreateDenseMaze(int rows, int columns, double changeDirectionModifier) { var map = new LabyrinthDungeon(rows, columns); map.MarkCellsUnvisited(); var currentLocation = map.PickRandomCellAndMarkItVisited(_random); var previousDirection = Direction.North; while (!map.AllCellsVisited) { var directionPicker = new DirectionPicker(_random, previousDirection, changeDirectionModifier); var direction = directionPicker.GetNextDirection(); while (!map.HasAdjacentCellInDirection(currentLocation, direction) || map.AdjacentCellInDirectionIsVisited(currentLocation, direction)) { if (directionPicker.HasNextDirection) { direction = directionPicker.GetNextDirection(); } else { currentLocation = map.GetRandomVisitedCell(currentLocation, _random); // get a new previously visited location directionPicker = new DirectionPicker(_random, previousDirection, changeDirectionModifier); // reset the direction picker direction = directionPicker.GetNextDirection(); // get a new direction. } } currentLocation = map.CreateCorridor(currentLocation, direction); map.FlagCellAsVisited(currentLocation); previousDirection = direction; } return(map); }
override public void StartDigging(VirtualMap map, CellLocation starting_location, int directionChangeModifier) { CellLocation currentLocation = starting_location; map.MarkAsVisited(currentLocation); // Pick a starting previous direction VirtualMap.DirectionType previousDirection = VirtualMap.DirectionType.North; List <CellLocation> previousLocations = new List <CellLocation>(); // Repeat until all cells have been visited while (!map.AllCellsVisited) { // Get a starting direction DirectionPicker directionPicker = new DirectionPicker(map, currentLocation, directionChangeModifier, previousDirection); VirtualMap.DirectionType direction = directionPicker.GetNextDirection(map, currentLocation); if (direction != VirtualMap.DirectionType.None) { // Create a corridor in the current cell and flag it as visited previousLocations.Add(currentLocation); previousDirection = direction; currentLocation = map.CreateCorridor(currentLocation, direction); map.FlagCellAsVisited(currentLocation); } else { // Backtrack currentLocation = previousLocations[previousLocations.Count - 1]; previousLocations.RemoveAt(previousLocations.Count - 1); } } }
/// <param name="deadEndRemovalModifier">Percentage value (0.0 - 1.0) of dead ends to convert into loops.</param> private void RemoveDeadEnds(LabyrinthDungeon map, double deadEndRemovalModifier) { var noOfDeadEndCellsToRemove = (int)System.Math.Ceiling(deadEndRemovalModifier * map.Rows * map.Columns); var deadEndLocations = map.DeadEndCellLocations; for (var i = 0; i < noOfDeadEndCellsToRemove; i++) { if (deadEndLocations.Count == 0) { break; } var index = _random.Next(0, deadEndLocations.Count); var deadEndLocation = deadEndLocations[index]; deadEndLocations.RemoveAt(index); if (map[deadEndLocation].IsDeadEnd) { var currentLocation = deadEndLocation; do { // Initialize the direction picker not to select the dead-end corridor direction. var directionPicker = new DirectionPicker(_random, map[currentLocation].CalculateDeadEndCorridorDirection(), 1); var direction = directionPicker.GetNextDirection(); while (!map.HasAdjacentCellInDirection(currentLocation, direction)) { if (directionPicker.HasNextDirection) { direction = directionPicker.GetNextDirection(); } else { throw new InvalidOperationException("This should not happen."); } } // Create a corridor in the selected direction: currentLocation = map.CreateCorridor(currentLocation, direction); }while (map[currentLocation].IsDeadEnd); // stop when you intersect an existing corridor } } }
override public void StartDigging(VirtualMap map, CellLocation starting_location, int directionChangeModifier) { CellLocation currentLocation = starting_location; map.MarkAsVisited(currentLocation); // Pick a previous direction VirtualMap.DirectionType previousDirection = VirtualMap.DirectionType.North; // Repeat until all cells have been visited while (!map.AllCellsVisited) { // Get a starting direction DirectionPicker directionPicker = new DirectionPicker(map, currentLocation, directionChangeModifier, previousDirection); VirtualMap.DirectionType direction = directionPicker.GetNextDirection(map, currentLocation); if (direction != VirtualMap.DirectionType.None) { // Create a corridor in the current cell and flag it as visited currentLocation = map.CreateCorridor(currentLocation, direction); map.FlagCellAsVisited(currentLocation); previousDirection = direction; } // or start from another visited cell // NOTE: This may be less performant! else { currentLocation = map.GetRandomVisitedCell(currentLocation); // No visited cell available: proceed from a random unvisited cell if (currentLocation.x == -1) { currentLocation = map.PickRandomUnvisitedLocation(); map.MarkAsVisited(currentLocation); } } } }
// Open dead ends by linking them to rooms private void OpenDeadEnds(VirtualMap map) { // Console.WriteLine("DEAD END MOD: " + openDeadEndModifier); if (openDeadEndModifier == 0) { return; } IEnumerable <CellLocation> deads = map.DeadEndCellLocations; foreach (CellLocation deadEnd in deads) { if (DungeonGenerator.Random.Instance.Next(1, 99) < openDeadEndModifier) { CellLocation currentLocation = deadEnd; // int count=0; do { // Initialize the direction picker not to select the dead-end corridor direction DirectionPicker directionPicker = new DirectionPicker(map, currentLocation, map.CalculateDeadEndCorridorDirection(currentLocation)); // Debug.Log("We have a dead and " + directionPicker); VirtualMap.DirectionType direction = directionPicker.GetNextDirection(map, currentLocation); // Debug.Log("We choose dir " + direction); if (direction == VirtualMap.DirectionType.None) { throw new InvalidOperationException("Could not remove the dead end!"); } // Debug.Log("Cannot go that way!"); else { // Create a corridor in the selected direction currentLocation = map.CreateCorridor(currentLocation, direction); } // count++; } while (map.IsDeadEnd(currentLocation) && currentLocation != deadEnd); // Stop when you intersect an existing corridor, or when you end back to the starting cell (that means we could not remove the dead end, happens with really small maps // Debug.Log("Dead end removed"); } } }