stoneharry

Untitled

May 24th, 2012
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.45 KB | None | 0 0
  1. -- A* pathing system
  2.  
  3. function CalcMoves(mapmat, px, py, tx, ty)  -- Based on some code of LMelior but made it work and improved way beyond his code, still thx LMelior!
  4. --[[ PRE:
  5. mapmat is a 2d array
  6. px is the player's current x
  7. py is the player's current y
  8. tx is the target x
  9. ty is the target y
  10.  
  11. Note: all the x and y are the x and y to be used in the table.
  12. By this I mean, if the table is 3 by 2, the x can be 1,2,3 and the y can be 1 or 2.
  13. --]]
  14.  
  15. --[[ POST:
  16. closedlist is a list with the checked nodes.
  17. It will return nil if all the available nodes have been checked but the target hasn't been found.
  18. --]]
  19.  
  20.     -- variables
  21.     local openlist={}                               -- Initialize table to store possible moves
  22.     local closedlist={}                     -- Initialize table to store checked gridsquares
  23.     local listk=1                                   -- List counter
  24.     local closedk=0                                 -- Closedlist counter
  25.     local tempH=math.abs(px-tx)+math.abs(py-ty)
  26.     local tempG=0
  27.     openlist[1]={x=px, y=py, g=0, h=tempH, f=0+tempH ,par=1}    -- Make starting point in list
  28.     local xsize=table.getn(mapmat[1])               -- horizontal map size
  29.     local ysize=table.getn(mapmat)                  -- vertical map size
  30.     local curbase={}                        -- Current square from which to check possible moves
  31.     local basis=1                           -- Index of current base
  32.  
  33.     -- Growing loop
  34.     while listk>0 do
  35.  
  36.         -- Get the lowest f of the openlist
  37.         local lowestF=openlist[listk].f
  38.         basis=listk
  39.         for k=listk,1,-1 do
  40.             if openlist[k].f<lowestF then
  41.                 lowestF=openlist[k].f
  42.                 basis=k
  43.             end
  44.         end
  45.  
  46.         closedk=closedk+1
  47.         table.insert(closedlist,closedk,openlist[basis])
  48.  
  49.         curbase=closedlist[closedk]              -- define current base from which to grow list
  50.  
  51.         local rightOK=true
  52.         local leftOK=true                            -- Booleans defining if they're OK to add
  53.         local downOK=true                            -- (must be reset for each while loop)
  54.         local upOK=true
  55.  
  56.         -- Look through closedlist
  57.         if closedk>0 then
  58.             for k=1,closedk do
  59.                 if closedlist[k].x==curbase.x+1 and closedlist[k].y==curbase.y then
  60.                     rightOK=false
  61.                 end
  62.                 if closedlist[k].x==curbase.x-1 and closedlist[k].y==curbase.y then
  63.                     leftOK=false
  64.                 end
  65.                 if closedlist[k].x==curbase.x and closedlist[k].y==curbase.y+1 then
  66.                     downOK=false
  67.                 end
  68.                 if closedlist[k].x==curbase.x and closedlist[k].y==curbase.y-1 then
  69.                     upOK=false
  70.                 end
  71.             end
  72.         end
  73.        
  74.         -- Check if next points are on the map and within moving distance
  75.         if curbase.x+1>xsize then
  76.             rightOK=false
  77.         end
  78.         if curbase.x-1<1 then
  79.             leftOK=false
  80.         end
  81.         if curbase.y+1>ysize then
  82.             downOK=false
  83.         end
  84.         if curbase.y-1<1 then
  85.             upOK=false
  86.         end
  87.  
  88.         -- If it IS on the map, check map for obstacles
  89.         --(Lua returns an error if you try to access a table position that doesn't exist, so you can't combine it with above)
  90.         if curbase.x+1<=xsize and mapmat[curbase.y][curbase.x+1]~=0 then
  91.             rightOK=false
  92.         end
  93.         if curbase.x-1>=1 and mapmat[curbase.y][curbase.x-1]~=0 then
  94.             leftOK=false
  95.         end
  96.         if curbase.y+1<=ysize and mapmat[curbase.y+1][curbase.x]~=0 then
  97.             downOK=false
  98.         end
  99.         if curbase.y-1>=1 and mapmat[curbase.y-1][curbase.x]~=0 then
  100.             upOK=false
  101.         end
  102.        
  103.         -- check if the move from the current base is shorter then from the former parrent
  104.         tempG=curbase.g+1
  105.         for k=1,listk do
  106.             if rightOK and openlist[k].x==curbase.x+1 and openlist[k].y==curbase.y and openlist[k].g>tempG then
  107.             tempH=math.abs((curbase.x+1)-tx)+math.abs(curbase.y-ty)
  108.             table.insert(openlist,k,{x=curbase.x+1, y=curbase.y, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  109.             rightOK=false
  110.             end
  111.        
  112.             if leftOK and openlist[k].x==curbase.x-1 and openlist[k].y==curbase.y and openlist[k].g>tempG then
  113.             tempH=math.abs((curbase.x-1)-tx)+math.abs(curbase.y-ty)
  114.             table.insert(openlist,k,{x=curbase.x-1, y=curbase.y, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  115.             leftOK=false
  116.             end
  117.  
  118.             if downOK and openlist[k].x==curbase.x and openlist[k].y==curbase.y+1 and openlist[k].g>tempG then
  119.             tempH=math.abs((curbase.x)-tx)+math.abs(curbase.y+1-ty)
  120.             table.insert(openlist,k,{x=curbase.x, y=curbase.y+1, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  121.             downOK=false
  122.             end
  123.  
  124.             if upOK and openlist[k].x==curbase.x and openlist[k].y==curbase.y-1 and openlist[k].g>tempG then
  125.             tempH=math.abs((curbase.x)-tx)+math.abs(curbase.y-1-ty)
  126.             table.insert(openlist,k,{x=curbase.x, y=curbase.y-1, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  127.             upOK=false
  128.             end
  129.         end
  130.  
  131.         -- Add points to openlist
  132.         -- Add point to the right of current base point
  133.         if rightOK then
  134.             listk=listk+1
  135.             tempH=math.abs((curbase.x+1)-tx)+math.abs(curbase.y-ty)
  136.             table.insert(openlist,listk,{x=curbase.x+1, y=curbase.y, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  137.         end
  138.  
  139.         -- Add point to the left of current base point
  140.         if leftOK then
  141.             listk=listk+1
  142.             tempH=math.abs((curbase.x-1)-tx)+math.abs(curbase.y-ty)
  143.             table.insert(openlist,listk,{x=curbase.x-1, y=curbase.y, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  144.         end
  145.  
  146.         -- Add point on the top of current base point
  147.         if downOK then
  148.             listk=listk+1
  149.             tempH=math.abs(curbase.x-tx)+math.abs((curbase.y+1)-ty)
  150.             table.insert(openlist,listk,{x=curbase.x, y=curbase.y+1, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  151.         end
  152.  
  153.         -- Add point on the bottom of current base point
  154.         if upOK then
  155.             listk=listk+1
  156.             tempH=math.abs(curbase.x-tx)+math.abs((curbase.y-1)-ty)
  157.             table.insert(openlist,listk,{x=curbase.x, y=curbase.y-1, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  158.         end
  159.  
  160.         table.remove(openlist,basis)
  161.         listk=listk-1
  162.  
  163.         if closedlist[closedk].x==tx and closedlist[closedk].y==ty then
  164.            return closedlist
  165.         end
  166.     end
  167.  
  168.     return nil
  169. end
  170.  
  171. function CalcPath(closedlist)
  172. --[[ PRE:
  173. closedlist is a list with the checked nodes.
  174. OR nil if all the available nodes have been checked but the target hasn't been found.
  175. --]]
  176.  
  177. --[[ POST:
  178. path is a list with all the x and y coords of the nodes of the path to the target.
  179. OR nil if closedlist==nil
  180. --]]
  181.  
  182.     if closedlist==nil then
  183.        return nil
  184.     end
  185.      local path={}
  186.      local pathIndex={}
  187.      local last=table.getn(closedlist)
  188.      table.insert(pathIndex,1,last)
  189.  
  190.      local i=1
  191.      while pathIndex[i]>1 do
  192.         i=i+1
  193.         table.insert(pathIndex,i,closedlist[pathIndex[i-1]].par)
  194.      end
  195.  
  196.      for n=table.getn(pathIndex),1,-1 do
  197.          table.insert(path,{x=closedlist[pathIndex[n]].x, y=closedlist[pathIndex[n]].y})
  198.      end
  199.  
  200.      closedlist=nil
  201.      return path
  202. end
Advertisement
Add Comment
Please, Sign In to add comment