Guest User

Untitled

a guest
May 19th, 2025
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.15 KB | None | 0 0
  1. public sealed class Level : LevelGraph
  2.     {
  3.  
  4.         private readonly LevelSettings settings;
  5.         private readonly HashSet<LevelRoom> rooms;
  6.  
  7.         public Level(LevelSettings settings) : base()
  8.         {
  9.             this.settings = settings;
  10.             this.rooms = new HashSet<LevelRoom>();
  11.         }
  12.  
  13.         public LevelSettings Settings => settings;
  14.         public IEnumerable<LevelRoom> Rooms => rooms;
  15.  
  16.         protected override void Clear()
  17.         {
  18.             base.Clear();
  19.  
  20.             rooms.Clear();
  21.         }
  22.  
  23.         public void Build()
  24.         {
  25.             Clear();
  26.  
  27.             var random = new RNG(settings.Seed);
  28.  
  29.             GenerateRooms(random);
  30.  
  31.             var failedEdges = GenerateMaze(random);
  32.             GenerateRoomDoors(random);
  33.         }
  34.  
  35.         private void GenerateRooms(RNG random)
  36.         {
  37.             int roomPadding = settings.RoomPadding;
  38.  
  39.             for (int i = 0; i < settings.RoomCount; i++)
  40.             {
  41.                 int attempts = 0;
  42.                 LevelRoom room;
  43.  
  44.                 do
  45.                 {
  46.                     room = new(settings, random);
  47.                     if (rooms.Any((r) => r.AABB.Intersects(room.AABB.OffsetSize(roomPadding))))
  48.                         room = null;
  49.  
  50.                 } while (room == null && attempts++ < 10);
  51.  
  52.                 if (room == null)
  53.                     continue;
  54.  
  55.                 rooms.Add(room);
  56.             }
  57.         }
  58.  
  59.         private LinkedList<((int x, int y) key, bool horizontal)> GenerateMaze(RNG random)
  60.         {
  61.             IEnumerable<AABB> aabbs = rooms.Select(room => room.AABB);
  62.  
  63.             var width = settings.Width;
  64.             var height = settings.Height;
  65.  
  66.             var edges = new LinkedList<((int x, int y) key, bool horizontal)>();
  67.  
  68.             for (int j = 0; j < height; j++)
  69.             {
  70.                 for (int i = 0; i < width; i++)
  71.                 {
  72.                     if (aabbs.Contains(i, j))
  73.                         continue;
  74.  
  75.                     AddNode((i, j), new AtomicReference<Direction>());
  76.  
  77.                     if (i > 0)
  78.                         edges.AddLast(((i, j), true));
  79.                     if (j > 0)
  80.                         edges.AddLast(((i, j), false));
  81.                 }
  82.             }
  83.  
  84.             var shuffledEdges = random.Shuffle(edges);
  85.             var failedEdges = new LinkedList<((int x, int y) key, bool horizontal)>();
  86.  
  87.             foreach (var ((x, y), horizontal) in shuffledEdges)
  88.             {
  89.                 var edgeDirection = horizontal ? Direction.LEFT : Direction.UP;
  90.  
  91.                 var k1 = (x, y);
  92.                 var k2 = edgeDirection.Move(x, y);
  93.  
  94.                 if (!IsUnioned(k1, k2))
  95.                 {
  96.                     if (AddConnection(k1, edgeDirection))
  97.                         Union(k1, k2);
  98.                 }
  99.                 else
  100.                     failedEdges.AddLast((k1, horizontal));
  101.             }
  102.  
  103.             return failedEdges;
  104.         }
  105.  
  106.         private void GenerateRoomDoors(RNG random)
  107.         {
  108.             foreach (var room in rooms)
  109.             {
  110.                 AABB aabb = room.AABB;
  111.                 HashSet<((int x, int y) key, Direction direction)> roomEdges = aabb.OffsetSize(1).Edges();
  112.  
  113.                 var doorEdges = random.ChooseMultipleUnique(roomEdges.Where(edge => IsNode(edge.key)).ToList(), room.EntranceCount);
  114.  
  115.                 foreach (var (key, direction) in doorEdges)
  116.                 {
  117.                     TryGetNode(key, out var node);
  118.                     node.Value |= direction.Opposite();
  119.                 }
  120.             }
  121.         }
  122.  
  123.         public override string ToString()
  124.         {
  125.             var builder = new StringBuilder();
  126.  
  127.             for (int j = 0; j < settings.Height; j++)
  128.             {
  129.                 for (int i = 0; i < settings.Width; i++)
  130.                 {
  131.                     if (!TryGetNode((i, j), out var node))
  132.                         continue;
  133.  
  134.                     builder.Append(node.Value.GetDirectionChar());
  135.                 }
  136.  
  137.                 builder.Append('\n');
  138.             }
  139.  
  140.             return builder.ToString();
  141.         }
  142.  
  143.     }
Advertisement
Add Comment
Please, Sign In to add comment