Advertisement
Doob

pathFinder

Feb 16th, 2017
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.09 KB | None | 0 0
  1. local WORLD, SIDE = {}, {{1,0,0},{-1,0,0},{0,0,1},{0,0,-1},{0,1,0},{0,-1,0}}
  2. local HUGE, UNPK, INSRT = math.huge, table.unpack, table.insert
  3.  
  4. local function hash(x, y, z)
  5.   x, z = x+134217728, z+134217728
  6.   return y|(x<<8)|(z<<36)
  7. end
  8.  
  9. local function unhash(h)
  10.   return ((h&68719476480)>>8)-134217728, h&255, ((h&-68719476736)>>36)-134217728
  11. end
  12.  
  13. local function delta(x1, y1, z1, x2, y2, z2)
  14.   return (x1-x2)^2+(y1-y2)^2+(z1-z2)^2
  15. end
  16.  
  17. local function getPath(sX, sY, sZ, tX, tY, tZ)
  18.   local S, T, d = hash(tX, tY, tZ), hash(sX, sY, sZ), delta(sX, sY, sZ, tX, tY, tZ)
  19.   if not WORLD[S] or not WORLD[T] then return nil end
  20.   local OPEN, CLOSED, PATH = {[S]={d,d}}, {}, {}
  21.   local cur, f, cX, cY, cZ, pX, pY, pZ, a, b, ch
  22.   while true do
  23.     cur, d, f = nil, HUGE, HUGE
  24.     for k, v in pairs(OPEN) do
  25.       if v[1] < d and v[2] < f then
  26.         d, f = v[1], v[2]
  27.         cur = k
  28.       end
  29.     end
  30.     if cur then
  31.       OPEN[cur], CLOSED[cur] = nil, {UNPK(OPEN[cur])}
  32.       cX, cY, cZ = unhash(cur)
  33.       for s = 1, #SIDE do
  34.         pX, pY, pZ = cX+SIDE[s][1], cY+SIDE[s][2], cZ+SIDE[s][3]
  35.         ch = hash(pX, pY, pZ)
  36.         if WORLD[ch] and not CLOSED[ch] then
  37.           a, b = delta(pX, pY, pZ, sX, sY, sZ), delta(pX, pY, pZ, tX, tY, tZ)
  38.           OPEN[ch] = {a, b, cur}
  39.           if ch == T then
  40.             node = ch
  41.             for i, j in pairs(OPEN) do
  42.               CLOSED[i] = {UNPK(j)}
  43.             end
  44.             OPEN = nil
  45.             while node ~= S do
  46.               INSRT(PATH, {unhash(node)})
  47.               if CLOSED[node] then
  48.                 node, CLOSED[node] = CLOSED[node][3], nil
  49.               end
  50.             end
  51.             INSRT(PATH, {tX, tY, tZ})
  52.             return PATH
  53.           end
  54.         end
  55.       end
  56.     else
  57.       return nil
  58.     end
  59.   end
  60.   if os.clock() > 0.5 then
  61.     return nil
  62.   end
  63. end
  64.  
  65. for x = 1, 100 do
  66.   for y = 1, 100 do
  67.     WORLD[hash(x, y, 0)] = true
  68.   end
  69. end
  70. g = getPath(1, 1, 0, 100, 100, 0)
  71. if g then
  72.   for i = 1, #g do
  73.     print(UNPK(g[i]))
  74.   end
  75. end
  76.  
  77. --[[
  78. x500 12.7
  79. x400 7.4
  80. x300 4.3
  81. x200 2.4
  82. x100 0.1
  83. ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement