Guest User

Untitled

a guest
May 19th, 2025
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.22 KB | None | 0 0
  1. public abstract class LevelGraph : IGraph<(int x, int y), AtomicReference<Direction>>, IDisjointSetUnion<(int x, int y)>
  2.     {
  3.  
  4.         private readonly Dictionary<(int x, int y), AtomicReference<Direction>> nodes;
  5.         private readonly Dictionary<(int x, int y), HashSet<(int x, int y)>> connections;
  6.  
  7.         private readonly Dictionary<(int x, int y), (int x, int y)> parents;
  8.  
  9.         public LevelGraph()
  10.         {
  11.             this.nodes = new();
  12.             this.connections = new();
  13.  
  14.             this.parents = new();
  15.         }
  16.  
  17.         protected virtual void Clear()
  18.         {
  19.             nodes.Clear();
  20.             connections.Clear();
  21.  
  22.             parents.Clear();
  23.         }
  24.  
  25.         // #################### IGraph ####################
  26.  
  27.         public bool AddNode((int x, int y) key, AtomicReference<Direction> node)
  28.         {
  29.             if (IsNode(key))
  30.                 return false;
  31.  
  32.             nodes[key] = node;
  33.             connections[key] = new HashSet<(int x, int y)>();
  34.  
  35.             return true;
  36.         }
  37.  
  38.         public bool AddConnection((int x, int y) key1, (int x, int y) key2)
  39.         {
  40.             if (!IsNode(key1) || !IsNode(key2))
  41.                 return false;
  42.  
  43.             if (IsConnectedDirectly(key1, key2))
  44.                 return false;
  45.  
  46.             connections[key1].Add(key2);
  47.             connections[key2].Add(key1);
  48.  
  49.             return true;
  50.         }
  51.  
  52.  
  53.         public bool TryGetNode((int x, int y) key, out AtomicReference<Direction> node) => nodes.TryGetValue(key, out node);
  54.  
  55.         public bool IsNode((int x, int y) key) => TryGetNode(key, out var _);
  56.  
  57.  
  58.         public bool IsConnectedDirectly((int x, int y) k1, (int x, int y) k2) => connections[k1].Contains(k2);
  59.  
  60.         public bool IsConnectedIndirectly((int x, int y) k1, (int x, int y) k2) => GraphDistance(k1, k2) != -1;
  61.  
  62.  
  63.         public IEnumerable<(int x, int y)> GetConnectedNodes((int x, int y) key)
  64.         {
  65.             if (connections.TryGetValue(key, out var neighbors))
  66.                 return neighbors;
  67.  
  68.             return Enumerable.Empty<(int, int)>();
  69.         }
  70.  
  71.         // #################### IDisjointSetUnion ####################
  72.  
  73.         public (int x, int y) GetRoot((int x, int y) key)
  74.         {
  75.             if (!parents.ContainsKey(key))
  76.                 parents[key] = key;
  77.  
  78.             if (!parents[key].Equals(key))
  79.                 parents[key] = GetRoot(parents[key]);
  80.  
  81.             return parents[key];
  82.         }
  83.  
  84.  
  85.         public bool IsUnioned((int x, int y) k1, (int x, int y) k2) => GetRoot(k1).Equals(GetRoot(k2));
  86.  
  87.         public void Union((int x, int y) k1, (int x, int y) k2)
  88.         {
  89.             var root1 = GetRoot(k1);
  90.             var root2 = GetRoot(k2);
  91.  
  92.             if (!IsUnioned(root1, root2))
  93.                 parents[root2] = root1;
  94.         }
  95.  
  96.         // #################### Extend IGraph ####################
  97.  
  98.         public bool AddConnection((int x, int y) key1, Direction direction)
  99.         {
  100.             if (!direction.IsValid())
  101.                 return false;
  102.  
  103.             (int x, int y) key2 = direction.Move(key1.x, key1.y);
  104.             if (AddConnection(key1, key2))
  105.             {
  106.                 nodes[key1].Value |= direction;
  107.                 nodes[key2].Value |= direction.Opposite();
  108.  
  109.                 return true;
  110.             }
  111.  
  112.             return false;
  113.         }
  114.  
  115.         public int GraphDistance((int x, int y) k1, (int x, int y) k2)
  116.         {
  117.             if (!IsNode(k1) || !IsNode(k2))
  118.                 return -1;
  119.  
  120.             var visited = new HashSet<(int x, int y)>();
  121.  
  122.             var queue = new Queue<((int x, int y), int distance)>();
  123.             queue.Enqueue((k1, 0));
  124.  
  125.             while (queue.Count > 0)
  126.             {
  127.                 var (current, distance) = queue.Dequeue();
  128.                 if (current.Equals(k2))
  129.                     return distance;
  130.  
  131.                 if (!visited.Add(current))
  132.                     continue;
  133.  
  134.                 foreach (var neighbor in GetConnectedNodes(current))
  135.                 {
  136.                     if (!visited.Contains(neighbor))
  137.                         queue.Enqueue((neighbor, distance + 1));
  138.                 }
  139.             }
  140.  
  141.             return -1;
  142.         }
  143.  
  144.     }
Advertisement
Add Comment
Please, Sign In to add comment