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); }
private void PlaceRoom(Vector2I location, LabyrinthDungeon dungeon, Room room) { // Offset the room origin to the new location. room.SetLocation(location); // Loop for each cell in the room for (var row = 0; row < room.Rows; row++) { for (var column = 0; column < room.Columns; column++) { // Translate the room cell location to its location in the dungeon. var dungeonLocation = location + new Vector2I(column, row); dungeon[dungeonLocation].NorthSide = room[row, column].NorthSide; dungeon[dungeonLocation].SouthSide = room[row, column].SouthSide; dungeon[dungeonLocation].WestSide = room[row, column].WestSide; dungeon[dungeonLocation].EastSide = room[row, column].EastSide; // TODO: This part may be unnecessary. // Create room walls on map (either side of the wall) if ((column == 0) && (dungeon.HasAdjacentCellInDirection(dungeonLocation, Direction.West))) { dungeon.CreateWall(dungeonLocation, Direction.West); } if ((column == room.Columns - 1) && (dungeon.HasAdjacentCellInDirection(dungeonLocation, Direction.East))) { dungeon.CreateWall(dungeonLocation, Direction.East); } if ((row == 0) && (dungeon.HasAdjacentCellInDirection(dungeonLocation, Direction.North))) { dungeon.CreateWall(dungeonLocation, Direction.North); } if ((row == room.Rows - 1) && (dungeon.HasAdjacentCellInDirection(dungeonLocation, Direction.South))) { dungeon.CreateWall(dungeonLocation, Direction.South); } } } dungeon.Rooms.Add(room); }
/// <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 } } }