Advertisement
Akuukis

Pathfinding #1

Apr 29th, 2014
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[ Header
  2. ColorWars algorithm for LUA
  3. Authors: Akuukis, Hugo, LatvianModder, TomsG
  4. Started: May 1, 2014
  5. First Beta release: -
  6. First Alpha release: -
  7. Github address: https://github.com/Akuukis/TurtleColorWars
  8. --]]
  9. --[[Structure
  10. Main - Starts Init. and afterwards runs Job,Supp,Comm in paralel. Subclasses Nav,Debug,Stats are present.
  11. Init.## Initiation - Initiates the turtle so it could operate
  12. Job.### Decision Making - Turtle weights alternatives, chooses his next AIM (strategy level) and does it (tactical level)
  13. Supp.## Maintance - Turtle's AIM can be interrupted by inside events, like low on fuel, full backpack or afraid of night. Overrides AIM & does it.
  14. Comm.## Communication - Turtle's AIM can be interrupted by outside events, like call for help or direct command. Sets AIM & does Job##.
  15. Nav.### Navigation - Turtle goes to point XYZ (sub-tactical level) and constantly updates internal map.
  16. Debug.# Debug - (sub-tactical level)
  17. Stats.# Statistics - Turtle collents & stores individual statistics for fun purposes only.
  18. --]]
  19.  
  20. Supp = {
  21.   Refuel = function(self)
  22.     if turtle.refuel()then
  23.       write("Refueled!\n")
  24.       else
  25.       write("Fuel me!\n")
  26.       end
  27.     end
  28.   }
  29. Nav = {
  30.   SurfaceMove = function(self)
  31.     Debug:Hugo(x,y)
  32.     if turtle.forward() then
  33.       while turtle.detectDown()~=true do
  34.         if turtle.down() then z=z-1 end
  35.         end
  36.       Stats:Step()
  37.       if dir%4==0 then x=x+1 end
  38.       if dir%4==1 then y=y+1 end
  39.       if dir%4==2 then x=x-1 end
  40.       if dir%4==3 then y=y-1 end
  41.       else
  42.       while turtle.detect() do
  43.         if turtle.up() then z=z+1 end
  44.         end
  45.       end
  46.     end,
  47.   GetLost1 = function(self)
  48.     for i=0,math.random(3,5) do
  49.       write("GetLost No." .. i .. ": ")
  50.       for j=0,math.random(0,3) do
  51.         turtle.turnRight()
  52.         dir=dir+1
  53.         end
  54.       write("Turned to " .. dir%4 .. ", ")  
  55.       for j=0,math.random(5,10) do
  56.         Nav:SurfaceMove()
  57.         end
  58.       write("Went " .. Stats:GetCountedSteps() .. "sq\n")
  59.       Stats:ResetCountedSteps()
  60.       end
  61.     end,
  62.   GoToStupid = function(self)
  63.     write("I am at (" .. x .. "," .. y .. "). Going home!\n")
  64.     turtle.up()
  65.     turtle.down()
  66.     if y<0 then
  67.       while dir%4~=1 do
  68.         turtle.turnRight()
  69.         dir=dir+1
  70.         end
  71.       while y<0 do Nav:SurfaceMove() end
  72.       end
  73.     if y>0 then
  74.       while dir%4~=3 do
  75.         turtle.turnRight()
  76.         dir=dir+1
  77.         end
  78.       while y>0 do Nav:SurfaceMove() end
  79.       end
  80.     if x<0 then
  81.       while dir%4~=0 do
  82.         turtle.turnRight()
  83.         dir=dir+1
  84.         end
  85.       while x<0 do Nav:SurfaceMove() end
  86.       end
  87.     if x>0 then
  88.       while dir%4~=2 do
  89.         turtle.turnRight()
  90.         dir=dir+1
  91.         end
  92.       while x>0 do Nav:SurfaceMove() end
  93.       end
  94.     write("I am home!\n")
  95.     end,
  96.   CalcMoves = function(mapmat, px, py, tx, ty)  -- Based on some code of LMelior but made it work and improved way beyond his code.
  97.   --[[
  98.   A* algorithm for LUA
  99.   Ported to LUA by Altair
  100.   21 septembre 2006
  101.   --]]
  102.   --[[ PRE:
  103.   mapmat is a 2d array
  104.   px is the player's current x
  105.   py is the player's current y
  106.   tx is the target x
  107.   ty is the target y
  108.  
  109.   Note: all the x and y are the x and y to be used in the table.
  110.   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.
  111.   --]]
  112.  
  113.   --[[ POST:
  114.   closedlist is a list with the checked nodes.
  115.   It will return nil if all the available nodes have been checked but the target hasn't been found.
  116.   --]]
  117.  
  118.     -- variables
  119.     local openlist={}                               -- Initialize table to store possible moves
  120.     local closedlist={}                     -- Initialize table to store checked gridsquares
  121.     local listk=1                                   -- List counter
  122.           local closedk=0                                   -- Closedlist counter
  123.     local tempH=math.abs(px-tx)+math.abs(py-ty)
  124.     local tempG=0
  125.     openlist[1]={x=px, y=py, g=0, h=tempH, f=0+tempH ,par=1}    -- Make starting point in list
  126.     local xsize=table.getn(mapmat[1])               -- horizontal map size
  127.     local ysize=table.getn(mapmat)                  -- vertical map size
  128.     local curbase={}                        -- Current square from which to check possible moves
  129.     local basis=1                           -- Index of current base
  130.  
  131.     -- Growing loop
  132.     while listk>0 do
  133.  
  134.             -- Get the lowest f of the openlist
  135.             local lowestF=openlist[listk].f
  136.             basis=listk
  137.       for k=listk,1,-1 do
  138.             if openlist[k].f<lowestF then
  139.                lowestF=openlist[k].f
  140.                          basis=k
  141.                 end
  142.       end
  143.  
  144.       closedk=closedk+1
  145.       table.insert(closedlist,closedk,openlist[basis])
  146.  
  147.       curbase=closedlist[closedk]                -- define current base from which to grow list
  148.  
  149.       local rightOK=true
  150.       local leftOK=true                          -- Booleans defining if they're OK to add
  151.       local downOK=true                              -- (must be reset for each while loop)
  152.       local upOK=true
  153.  
  154.       -- Look through closedlist
  155.       if closedk>0 then
  156.           for k=1,closedk do
  157.         if closedlist[k].x==curbase.x+1 and closedlist[k].y==curbase.y then
  158.           rightOK=false
  159.         end
  160.         if closedlist[k].x==curbase.x-1 and closedlist[k].y==curbase.y then
  161.           leftOK=false
  162.         end
  163.         if closedlist[k].x==curbase.x and closedlist[k].y==curbase.y+1 then
  164.           downOK=false
  165.         end
  166.         if closedlist[k].x==curbase.x and closedlist[k].y==curbase.y-1 then
  167.           upOK=false
  168.         end
  169.           end
  170.       end
  171.      
  172.       -- Check if next points are on the map and within moving distance
  173.       if curbase.x+1>xsize then
  174.         rightOK=false
  175.       end
  176.       if curbase.x-1<1 then
  177.         leftOK=false
  178.       end
  179.       if curbase.y+1>ysize then
  180.         downOK=false
  181.       end
  182.       if curbase.y-1<1 then
  183.         upOK=false
  184.       end
  185.  
  186.       -- If it IS on the map, check map for obstacles
  187.       --(Lua returns an error if you try to access a table position that doesn't exist, so you can't combine it with above)
  188.       if curbase.x+1<=xsize and mapmat[curbase.y][curbase.x+1]~=0 then
  189.         rightOK=false
  190.       end
  191.       if curbase.x-1>=1 and mapmat[curbase.y][curbase.x-1]~=0 then
  192.         leftOK=false
  193.       end
  194.       if curbase.y+1<=ysize and mapmat[curbase.y+1][curbase.x]~=0 then
  195.         downOK=false
  196.       end
  197.       if curbase.y-1>=1 and mapmat[curbase.y-1][curbase.x]~=0 then
  198.         upOK=false
  199.       end
  200.      
  201.       -- check if the move from the current base is shorter then from the former parrent
  202.       tempG=curbase.g+1
  203.       for k=1,listk do
  204.           if rightOK and openlist[k].x==curbase.x+1 and openlist[k].y==curbase.y and openlist[k].g>tempG then
  205.         tempH=math.abs((curbase.x+1)-tx)+math.abs(curbase.y-ty)
  206.         table.insert(openlist,k,{x=curbase.x+1, y=curbase.y, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  207.         rightOK=false
  208.           end
  209.      
  210.           if leftOK and openlist[k].x==curbase.x-1 and openlist[k].y==curbase.y and openlist[k].g>tempG then
  211.         tempH=math.abs((curbase.x-1)-tx)+math.abs(curbase.y-ty)
  212.         table.insert(openlist,k,{x=curbase.x-1, y=curbase.y, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  213.         leftOK=false
  214.           end
  215.  
  216.           if downOK and openlist[k].x==curbase.x and openlist[k].y==curbase.y+1 and openlist[k].g>tempG then
  217.         tempH=math.abs((curbase.x)-tx)+math.abs(curbase.y+1-ty)
  218.         table.insert(openlist,k,{x=curbase.x, y=curbase.y+1, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  219.         downOK=false
  220.           end
  221.  
  222.           if upOK and openlist[k].x==curbase.x and openlist[k].y==curbase.y-1 and openlist[k].g>tempG then
  223.         tempH=math.abs((curbase.x)-tx)+math.abs(curbase.y-1-ty)
  224.         table.insert(openlist,k,{x=curbase.x, y=curbase.y-1, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  225.         upOK=false
  226.           end
  227.         end
  228.  
  229.       -- Add points to openlist
  230.       -- Add point to the right of current base point
  231.       if rightOK then
  232.         listk=listk+1
  233.         tempH=math.abs((curbase.x+1)-tx)+math.abs(curbase.y-ty)
  234.         table.insert(openlist,listk,{x=curbase.x+1, y=curbase.y, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  235.       end
  236.  
  237.       -- Add point to the left of current base point
  238.       if leftOK then
  239.         listk=listk+1
  240.         tempH=math.abs((curbase.x-1)-tx)+math.abs(curbase.y-ty)
  241.         table.insert(openlist,listk,{x=curbase.x-1, y=curbase.y, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  242.       end
  243.  
  244.       -- Add point on the top of current base point
  245.       if downOK then
  246.         listk=listk+1
  247.         tempH=math.abs(curbase.x-tx)+math.abs((curbase.y+1)-ty)
  248.         table.insert(openlist,listk,{x=curbase.x, y=curbase.y+1, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  249.       end
  250.  
  251.       -- Add point on the bottom of current base point
  252.       if upOK then
  253.         listk=listk+1
  254.         tempH=math.abs(curbase.x-tx)+math.abs((curbase.y-1)-ty)
  255.         table.insert(openlist,listk,{x=curbase.x, y=curbase.y-1, g=tempG, h=tempH, f=tempG+tempH, par=closedk})
  256.       end
  257.  
  258.       table.remove(openlist,basis)
  259.       listk=listk-1
  260.  
  261.                   if closedlist[closedk].x==tx and closedlist[closedk].y==ty then
  262.                      return closedlist
  263.                   end
  264.     end
  265.  
  266.     return nil
  267.   end,
  268.   CalcPath = function(closedlist)
  269.   --[[ PRE:
  270.   closedlist is a list with the checked nodes.
  271.   OR nil if all the available nodes have been checked but the target hasn't been found.
  272.   --]]
  273.  
  274.   --[[ POST:
  275.   path is a list with all the x and y coords of the nodes of the path to the target.
  276.   OR nil if closedlist==nil
  277.   --]]
  278.  
  279.       if closedlist==nil then
  280.          return nil
  281.       end
  282.      local path={}
  283.      local pathIndex={}
  284.      local last=table.getn(closedlist)
  285.      table.insert(pathIndex,1,last)
  286.  
  287.      local i=1
  288.      while pathIndex[i]>1 do
  289.       i=i+1
  290.       table.insert(pathIndex,i,closedlist[pathIndex[i-1]].par)
  291.      end
  292.  
  293.      for n=table.getn(pathIndex),1,-1 do
  294.          table.insert(path,{x=closedlist[pathIndex[n]].x, y=closedlist[pathIndex[n]].y})
  295.        end
  296.  
  297.      closedlist=nil
  298.      return path
  299.   end
  300.   }
  301. Debug = {
  302.   Hugo = function(self, x, y)
  303.     modem.transmit(3, 1337, x.." "..y)
  304.     end
  305.   }
  306. Stats = {
  307.   GlobalSteps = 0,
  308.   CountedSteps = 0,
  309.   Step = function(self, x)
  310.     x = x or 1 -- create object if user does not provide one
  311.     Stats.GlobalSteps = Stats.GlobalSteps + 1
  312.     Stats.CountedSteps = Stats.CountedSteps + 1
  313.     end,
  314.   GetGlobalSteps = function(self)
  315.     return Stats.GlobalSteps
  316.     end,
  317.   GetCountedSteps = function(self)
  318.     return Stats.CountedSteps
  319.     end,
  320.   ResetCountedSteps = function(self)
  321.     Stats.CountedSteps = 0
  322.     end
  323.   }
  324.  
  325. dir=0
  326. x=0
  327. y=0
  328. z=0
  329. modem = peripheral.wrap("left")
  330.  
  331. Supp:Refuel()
  332. Nav:GetLost1()
  333. Nav:GoToStupid()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement