_James

Dijkstra Pathfinding Algorithm

May 10th, 2016
1,810
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.37 KB | None | 0 0
  1. local Nodes = workspace:WaitForChild("Nodes")
  2. local Table = Nodes:GetChildren()
  3.  
  4. local A = workspace:WaitForChild("A")
  5. local B = workspace:WaitForChild("B")
  6.  
  7. function Connect()
  8.     for _,A in ipairs(Table)do
  9.         -- Don't overfill the nodes with neighbors.
  10.         if #A:GetChildren() <= 0 then
  11.             for _,B in ipairs(Table)do
  12.                 -- Make sure the path can be completed.
  13.                 local P = workspace:FindPartOnRay(Ray.new(A.Position, B.Position - A.Position))
  14.                 if P == B then
  15.                     local Neighbor = Instance.new("ObjectValue")
  16.                     Neighbor.Value = B
  17.                     Neighbor.Name = "Neighbor"
  18.                     Neighbor.Parent = A
  19.                 end
  20.             end
  21.         end
  22.     end
  23. end
  24.  
  25. function Length(A, B)
  26.     if not A or not B then return math.huge; end
  27.     return (A.Position - B.Position).Magnitude
  28. end
  29.  
  30. function ClosestNode(Coord)
  31.     local Output = nil;
  32.     local Cap = math.huge;
  33.     for _,v in ipairs(Table)do
  34.         local Distance = (v.Position - Coord).Magnitude
  35.         if Distance < Cap then
  36.             Output = v
  37.             Cap = Distance
  38.         end
  39.     end
  40.    
  41.     return Output
  42. end
  43.  
  44. function Dijkstra(A, B)
  45.     local A = ClosestNode(A);
  46.     local B = ClosestNode(B);
  47.    
  48.     local Q = {}; -- EmptySet
  49.     local D = {}; -- Distance
  50.     local P = {}; -- Parent
  51.     local u;
  52.    
  53.     -- Set all nodes except A to infinity.
  54.     for _,v in ipairs(Table)do
  55.         D[v] = math.huge;
  56.         P[v] = nil;
  57.         table.insert(Q, v)
  58.     end
  59.     D[A] = 0;
  60.    
  61.     repeat wait()
  62.         u = nil;
  63.         local l = -1;
  64.         local H = math.huge;
  65.         -- Find node with lowest distance value.
  66.         for i,v in ipairs(Q)do
  67.             if D[v] < H then
  68.                 H = D[v]
  69.                 u = v
  70.                 l = i
  71.             end
  72.         end
  73.        
  74.         if u then
  75.             if l > 0 then
  76.                 -- Remove u from table Q so it won't be used again.
  77.                 table.remove(Q, l)
  78.             end
  79.            
  80.             for _,v in ipairs(u:GetChildren())do
  81.                 if v:IsA("ObjectValue") then
  82.                     local Alt = D[u] + Length(u, v.Value)
  83.                     if Alt < D[v.Value] then
  84.                         D[v.Value] = Alt
  85.                         P[v.Value] = u
  86.                     end
  87.                 end
  88.             end
  89.         end
  90.         -- Terminate when path found, or no path found.
  91.     until u == B or not u
  92.    
  93.     -- Retrace path.
  94.     local Path = {u};
  95.     local Current = u;
  96.     repeat
  97.         if Current then
  98.             table.insert(Path, Current)
  99.             Current = P[Current]
  100.         end
  101.     until not Current
  102.    
  103.     local Output = {};
  104.     -- Reverse path.
  105.     for i = #Path, 1, -1 do
  106.         table.insert(Output, Path[i])
  107.     end
  108.    
  109.     if u then
  110.         print("Path finished")
  111.         return Output
  112.     else
  113.         print("No path found")
  114.     end
  115. end
  116.  
  117. Connect()
  118. Dijkstra(A.Position, B.Position)
Advertisement
Add Comment
Please, Sign In to add comment