Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public sealed class Level : LevelGraph
- {
- private readonly LevelSettings settings;
- private readonly HashSet<LevelRoom> rooms;
- public Level(LevelSettings settings) : base()
- {
- this.settings = settings;
- this.rooms = new HashSet<LevelRoom>();
- }
- public LevelSettings Settings => settings;
- public IEnumerable<LevelRoom> Rooms => rooms;
- protected override void Clear()
- {
- base.Clear();
- rooms.Clear();
- }
- public void Build()
- {
- Clear();
- var random = new RNG(settings.Seed);
- GenerateRooms(random);
- var failedEdges = GenerateMaze(random);
- GenerateRoomDoors(random);
- }
- private void GenerateRooms(RNG random)
- {
- int roomPadding = settings.RoomPadding;
- for (int i = 0; i < settings.RoomCount; i++)
- {
- int attempts = 0;
- LevelRoom room;
- do
- {
- room = new(settings, random);
- if (rooms.Any((r) => r.AABB.Intersects(room.AABB.OffsetSize(roomPadding))))
- room = null;
- } while (room == null && attempts++ < 10);
- if (room == null)
- continue;
- rooms.Add(room);
- }
- }
- private LinkedList<((int x, int y) key, bool horizontal)> GenerateMaze(RNG random)
- {
- IEnumerable<AABB> aabbs = rooms.Select(room => room.AABB);
- var width = settings.Width;
- var height = settings.Height;
- var edges = new LinkedList<((int x, int y) key, bool horizontal)>();
- for (int j = 0; j < height; j++)
- {
- for (int i = 0; i < width; i++)
- {
- if (aabbs.Contains(i, j))
- continue;
- AddNode((i, j), new AtomicReference<Direction>());
- if (i > 0)
- edges.AddLast(((i, j), true));
- if (j > 0)
- edges.AddLast(((i, j), false));
- }
- }
- var shuffledEdges = random.Shuffle(edges);
- var failedEdges = new LinkedList<((int x, int y) key, bool horizontal)>();
- foreach (var ((x, y), horizontal) in shuffledEdges)
- {
- var edgeDirection = horizontal ? Direction.LEFT : Direction.UP;
- var k1 = (x, y);
- var k2 = edgeDirection.Move(x, y);
- if (!IsUnioned(k1, k2))
- {
- if (AddConnection(k1, edgeDirection))
- Union(k1, k2);
- }
- else
- failedEdges.AddLast((k1, horizontal));
- }
- return failedEdges;
- }
- private void GenerateRoomDoors(RNG random)
- {
- foreach (var room in rooms)
- {
- AABB aabb = room.AABB;
- HashSet<((int x, int y) key, Direction direction)> roomEdges = aabb.OffsetSize(1).Edges();
- var doorEdges = random.ChooseMultipleUnique(roomEdges.Where(edge => IsNode(edge.key)).ToList(), room.EntranceCount);
- foreach (var (key, direction) in doorEdges)
- {
- TryGetNode(key, out var node);
- node.Value |= direction.Opposite();
- }
- }
- }
- public override string ToString()
- {
- var builder = new StringBuilder();
- for (int j = 0; j < settings.Height; j++)
- {
- for (int i = 0; i < settings.Width; i++)
- {
- if (!TryGetNode((i, j), out var node))
- continue;
- builder.Append(node.Value.GetDirectionChar());
- }
- builder.Append('\n');
- }
- return builder.ToString();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment