public static void RemoveDeadEnds(Dungeon dungeon, int deadEndRemovalModifier) { foreach (Point deadEndLocation in dungeon.FindDeadEnds) { if (ShouldRemoveDeadend(deadEndRemovalModifier)) { Point currentLocation = deadEndLocation; do { Direction directionPicker = new Direction((Direction.DirectionType)dungeon.CalculateDeadEndCorridorDirection(currentLocation), 100); Direction.DirectionType direction = directionPicker.GetNextDirection(); while (!dungeon.HasAdjacentCellInDirection(currentLocation, direction)) { if (directionPicker.HasNextDirection) direction = directionPicker.GetNextDirection(); else throw new InvalidOperationException("This should not happen"); } currentLocation = dungeon.CreateCorridor(currentLocation, direction); } while (dungeon[currentLocation].IsDeadEnd); } } }
public bool AdjacentCellInDirectionIsCorridor(Point location, Direction.DirectionType direction, Dungeon dungeon) { if (HasAdjacentCellInDirection(location, direction)) { Point target = GetTargetLocation(location, direction); switch (direction) { case Direction.DirectionType.North: return dungeon[target].IsCorridor; case Direction.DirectionType.West: return dungeon[target].IsCorridor; case Direction.DirectionType.South: return dungeon[target].IsCorridor; case Direction.DirectionType.East: return dungeon[target].IsCorridor; default: throw new InvalidOperationException(); } } else return false; }
public int CalculateRoomPlacementScore(Point location, Room room, Dungeon dungeon) { if (dungeon.bounds.Contains(new Rectangle(location, new Size(room.Width + 1, room.Height + 1)))) { int roomPlacementScore = 0; for (int x = 0; x < room.Width; x++) { for (int y = 0; y < room.Height; y++) { Point dungeonLocation = new Point(location.X + x, location.Y + y); if ((room.HasAdjacentCellInDirection(dungeonLocation, Direction.DirectionType.North) && dungeon.AdjacentCellInDirectionIsCorridor(dungeonLocation, Direction.DirectionType.North, dungeon))) roomPlacementScore++; if ((room.HasAdjacentCellInDirection(dungeonLocation, Direction.DirectionType.South) && dungeon.AdjacentCellInDirectionIsCorridor(dungeonLocation, Direction.DirectionType.South, dungeon))) roomPlacementScore++; if ((room.HasAdjacentCellInDirection(dungeonLocation, Direction.DirectionType.East) && dungeon.AdjacentCellInDirectionIsCorridor(dungeonLocation, Direction.DirectionType.East, dungeon))) roomPlacementScore++; if ((room.HasAdjacentCellInDirection(dungeonLocation, Direction.DirectionType.West) && dungeon.AdjacentCellInDirectionIsCorridor(dungeonLocation, Direction.DirectionType.West, dungeon))) roomPlacementScore++; if (dungeon[dungeonLocation].IsCorridor) roomPlacementScore += 3; foreach (Room dungeonRoom in dungeon.Rooms) if (dungeonRoom.bounds.Contains(dungeonLocation)) roomPlacementScore += 100; } } return roomPlacementScore; } else { return int.MaxValue; } }
public void PlaceRoom(Point location, Room room, Dungeon dungeon) { room.SetLocation(location); for (int x = 0; x < room.Width; x++) { for (int y = 0; y < room.Height; y++) { Point dungeonLocation = new Point(location.X + x, location.Y + y); dungeon[dungeonLocation].NorthSide = room[x, y].NorthSide; dungeon[dungeonLocation].SouthSide = room[x, y].SouthSide; dungeon[dungeonLocation].EastSide = room[x, y].EastSide; dungeon[dungeonLocation].WestSide = room[x, y].WestSide; if ((x == 0) && (dungeon.HasAdjacentCellInDirection(dungeonLocation, Direction.DirectionType.West))) dungeon.CreateSide(dungeonLocation, Direction.DirectionType.West, Cell.Sidetype.Wall); if ((x == room.Width - 1) && (dungeon.HasAdjacentCellInDirection(dungeonLocation, Direction.DirectionType.East))) dungeon.CreateSide(dungeonLocation, Direction.DirectionType.East, Cell.Sidetype.Wall); if ((y == 0) && (dungeon.HasAdjacentCellInDirection(dungeonLocation, Direction.DirectionType.North))) dungeon.CreateSide(dungeonLocation, Direction.DirectionType.North, Cell.Sidetype.Wall); if ((y == room.Height - 1) && (dungeon.HasAdjacentCellInDirection(dungeonLocation, Direction.DirectionType.South))) dungeon.CreateSide(dungeonLocation, Direction.DirectionType.South, Cell.Sidetype.Wall); } } dungeon.rooms.Add(room); }
public Dungeon Generate(int width, int height, int changeDirectionModifier, int sparesnessModifier) { Dungeon dungeon = new Dungeon(width, height); Point location = dungeon.PickRandomCellMarkVisited(); Direction.DirectionType previousDirection = Direction.DirectionType.North; while (dungeon.visitedCells < dungeon.Height * dungeon.Width) { Direction DirectionPicker = new Direction(previousDirection, changeDirectionModifier); Direction.DirectionType direction = DirectionPicker.GetNextDirection(); while (!dungeon.HasAdjacentCellInDirection(location, direction) || dungeon.AdjacentCellInDirectionVisited(location, direction)) { if (DirectionPicker.HasNextDirection) { direction = DirectionPicker.GetNextDirection(); } else { location = dungeon.PickRandomVisitedCell(location); DirectionPicker = new Direction(previousDirection, changeDirectionModifier); direction = DirectionPicker.GetNextDirection(); } } location = dungeon.CreateCorridor(location, direction); dungeon.MarkCellsAsVisited(location); previousDirection = direction; } SparsifyMaze(dungeon, sparesnessModifier); RemoveDeadEnds(dungeon, 70); roomGenerator.GenerateRooms(dungeon); PlaceDoors(dungeon); return dungeon; }
public DungeonFeatures[,] ExpandToTiles(Dungeon dungeon) { tiles = new DungeonFeatures[dungeon.Width * 2 + 1, dungeon.Height * 2 + 1]; for (int x = 0; x < dungeon.Width * 2 + 1; x++) { for (int y = 0; y < dungeon.Height * 2 + 1; y++) { Point tilePoint = new Point(x, y); tiles[x, y] = new DungeonFeatures(tilePoint); tiles[x, y].KindOfTile = DungeonFeatures.TileType.Rock; } } foreach (Room room in dungeon.Rooms) { Point minPoint = new Point(room.bounds.Location.X * 2 + 1, room.bounds.Location.Y * 2 + 1); Point maxPoint = new Point(room.bounds.Right * 2, room.bounds.Bottom * 2); for (int i = minPoint.X; i < maxPoint.X; i++) { for (int j = minPoint.Y; j < maxPoint.Y; j++) { tiles[i, j].KindOfTile = DungeonFeatures.TileType.Floor; } } } foreach (Point cellLocation in dungeon.CorridorCellLocations) { Point tileLocation = new Point(cellLocation.X * 2 + 1, cellLocation.Y * 2 + 1); tiles[tileLocation.X, tileLocation.Y].KindOfTile = DungeonFeatures.TileType.Floor; if (dungeon[cellLocation].NorthSide == Cell.Sidetype.Empty) tiles[tileLocation.X, tileLocation.Y - 1].KindOfTile = DungeonFeatures.TileType.Floor; if (dungeon[cellLocation].NorthSide == Cell.Sidetype.Door) tiles[tileLocation.X, tileLocation.Y - 1].KindOfTile = DungeonFeatures.TileType.Door; if (dungeon[cellLocation].SouthSide == Cell.Sidetype.Empty) tiles[tileLocation.X, tileLocation.Y + 1].KindOfTile = DungeonFeatures.TileType.Floor; if (dungeon[cellLocation].SouthSide == Cell.Sidetype.Door) tiles[tileLocation.X, tileLocation.Y + 1].KindOfTile = DungeonFeatures.TileType.Door; if (dungeon[cellLocation].WestSide == Cell.Sidetype.Empty) tiles[tileLocation.X - 1, tileLocation.Y].KindOfTile = DungeonFeatures.TileType.Floor; if (dungeon[cellLocation].WestSide == Cell.Sidetype.Door) tiles[tileLocation.X - 1, tileLocation.Y].KindOfTile = DungeonFeatures.TileType.Door; if (dungeon[cellLocation].EastSide == Cell.Sidetype.Empty) tiles[tileLocation.X + 1, tileLocation.Y].KindOfTile = DungeonFeatures.TileType.Floor; if (dungeon[cellLocation].EastSide == Cell.Sidetype.Door) tiles[tileLocation.X + 1, tileLocation.Y].KindOfTile = DungeonFeatures.TileType.Door; } GetImageCharacters(); //tiles[player.X, player.Y].ImageCharacter = Constants.PlayerImage; return tiles; }
public void PlaceDoors(Dungeon dungeon) { foreach (Room room in dungeon.Rooms) { } }
public void GenerateRooms(Dungeon dungeon) { PlaceRooms(7, 3, 8, 3, 8, dungeon); }
public void PlaceRooms(int noOfRoomsToPlace, int minRoomWidth, int maxRoomWidth, int minRoomHeight, int maxRoomHeight, Dungeon dungeon) { for (int roomCounter = 0; roomCounter < noOfRoomsToPlace; roomCounter++) { Room room = CreateRoom(minRoomWidth, maxRoomWidth, minRoomHeight, maxRoomHeight); int bestRoomPlacementScore = int.MaxValue; Point? bestRoomPlacementLocation = null; foreach (Point currentRoomPlacementLocation in dungeon.CorridorCellLocations) { int currentRoomPlacementScore = CalculateRoomPlacementScore(currentRoomPlacementLocation, room, dungeon); if (currentRoomPlacementScore < bestRoomPlacementScore) { bestRoomPlacementScore = currentRoomPlacementScore; bestRoomPlacementLocation = currentRoomPlacementLocation; } } if (bestRoomPlacementLocation != null) PlaceRoom(bestRoomPlacementLocation.Value, room, dungeon); } }
//a public void PlaceDoors(Dungeon dungeon) { foreach (Room room in dungeon.Rooms) { bool hasNorthDoor = false; bool hasSouthDoor = false; bool hasWestDoor = false; bool hasEastDoor = false; foreach (Point cellLocation in room.CellLocations) { Point dungeonLocation = new Point(room.bounds.X + cellLocation.X, room.bounds.Y + cellLocation.Y); if ((cellLocation.X == 0) && (dungeon.AdjacentCellInDirectionIsCorridor(dungeonLocation, Direction.DirectionType.West, dungeon)) && (!hasWestDoor)) { dungeon.CreateDoor(dungeonLocation, Direction.DirectionType.West); hasWestDoor = true; } if ((cellLocation.X == room.Width - 1) && (dungeon.AdjacentCellInDirectionIsCorridor(dungeonLocation, Direction.DirectionType.East, dungeon)) && (!hasEastDoor)) { dungeon.CreateDoor(dungeonLocation, Direction.DirectionType.East); hasEastDoor = true; } if ((cellLocation.Y == 0) && (dungeon.AdjacentCellInDirectionIsCorridor(dungeonLocation, Direction.DirectionType.North, dungeon)) && (!hasNorthDoor)) { dungeon.CreateDoor(dungeonLocation, Direction.DirectionType.North); hasNorthDoor = true; } if ((cellLocation.Y == room.Height - 1) && (dungeon.AdjacentCellInDirectionIsCorridor(dungeonLocation, Direction.DirectionType.South, dungeon)) && (!hasSouthDoor)) { dungeon.CreateDoor(dungeonLocation, Direction.DirectionType.South); hasSouthDoor = true; } } } }
public void SparsifyMaze(Dungeon dungeon, int sparsenessModifier) { int noOfDeadEndCellsToRemove = (int)Math.Ceiling((decimal)sparsenessModifier / 100 * (dungeon.Width * dungeon.Height)); IEnumerator<Point> enumerator = dungeon.FindDeadEnds.GetEnumerator(); for (int i = 0; i < noOfDeadEndCellsToRemove; i++) { if (!enumerator.MoveNext()) { enumerator = dungeon.FindDeadEnds.GetEnumerator(); if (!enumerator.MoveNext()) break; } Point point = enumerator.Current; dungeon.CreateSide(point, (Direction.DirectionType)dungeon.CalculateDeadEndCorridorDirection(point), Cell.Sidetype.Wall); } }