Advertisement
theinsekt

poz3a

Sep 5th, 2014
384
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.33 KB | None | 0 0
  1. --experimental untested
  2. -- The experiments with simulate are failed and should be removed,
  3. -- or replaced with poz3 experiment
  4. --theinsektAPIs/poz3a
  5. --updated version of poz2a
  6. --it uses poz3, it's a movement api that keeps track of your position
  7.  
  8. os.loadAPI("theinsektAPIs/poz3")
  9.  
  10. --if simulate is true then returns iters, without doing anything
  11. function digLoop(direction,iters,refuel,simulate)
  12.  if simulate then return iters end
  13.  direction=poz3.getAbsoluteDirection(direction)
  14.  if(direction==nil) then
  15.   print(
  16.   debug.traceback()
  17.   )
  18.   error("Error: direction is not valid (valid: n,s,w,e,u,d,r,l,f,b)")
  19.  end
  20.  return doLoop(direction,iters,detectDigGo2,refuel)
  21. end
  22.  
  23. --doLoop takes a doFunction as input and runs it iters times
  24. --doFunction should return true on success and false on fail
  25. --it takes the direction parameter and an optional parameter as input
  26. --(the optional parameter could be a table if you want)
  27. --doLoop turns n,s,w,e,u,d,r,l,f,b into n,s,w,e,u,d
  28. --doLoop exits immediately if doFunction returns false, and returns the number
  29. --of successful iterations
  30. --Use doLoop or use it as an inspiration
  31. function doLoop(direction,iters,doFunction,optional)
  32.  --check input
  33.  if direction==nil then error("Error: direction is nil") end
  34.  direction=poz3.getAbsoluteDirection(direction)--turn into n,e,s,w,u,d
  35.  if direction==nil then error("Error: unrecognised direction") end
  36.  if doFunction==nil then error("Error: called doLoop with doFunction==nil") end
  37.  if iters<0 then error("Error: iters is negative") end
  38.  --the doLoop
  39.  local i=0
  40.  poz3.turn(direction)--so that it will turn if iters==0
  41.  while( i<iters) do
  42.   if not doFunction(direction,optional) then
  43.    break
  44.   end
  45.   i=i+1
  46.  end
  47.  return i
  48. end
  49.  
  50. function callDigCube(dir1,len1,dir2,len2,dir3,len3,refuel,returnToOrigin)
  51.  --dir1 should not be nil
  52.  if dir1==nil then error("Error: dir1 is nil") end
  53.  dir1=poz3.getAbsoluteDirection(dir1)
  54.  if dir2 ~= nil then
  55.    dir2=poz3.getAbsoluteDirection(dir2)
  56.  end
  57.  if dir3 ~= nil then
  58.    --dir3 should be nil if dir2 is nil
  59.    if(dir2==nil) then error("Error: dir2 can't be nil when dir3 isn't nil") end
  60.    --get absolute direction
  61.    dir3=poz3.getAbsoluteDirection(dir3)
  62.  end
  63.  if not checkNormal(dir1,dir2,dir3) then
  64.    Error("Error: Two direction are on the same line")
  65.  end
  66.  
  67.  --if a dir is nil then the length should be nil
  68.  if dir2==nil and len2~=nil then error("Error: if dir2 is nil then len2 must be nil") end
  69.  if dir3==nil and len3~=nil then error("Error: if dir3 is nil then len2 must be nil") end
  70.  
  71.  --nil means default value, and default is 1
  72.  if len1==nil then len1=1 end
  73.  if len2==nil then len2=1 end
  74.  if len3==nil then len3=1 end
  75.  
  76.  
  77.  --check that lengths aren't 0 or negative
  78.  if len1<1 then error("Error: all lengths must be larger than 0, len1 isn't") end
  79.  if len2<1 then error("Error: all lengths must be larger than 0, len2 isn't") end
  80.  if len3<1 then error("Error: all lengths must be larger than 0, len3 isn't") end
  81.  
  82.  --save the origin
  83.  local origin=poz3.getPos2()
  84.  
  85.  --todo: simulate digCubeHorz and digCubeVert and choose the
  86.  -- fastest with the given values.
  87.  local succes=digCubeHorz(dir1,len1,dir2,len2,dir3,len3,refuel)
  88.  
  89.   --try to return to origin
  90.  if returnToOrigin then
  91.   if not digToCoords2(origin,refuel) then
  92.    return false
  93.   end
  94.  end
  95.  return succes
  96. end
  97.  
  98.  
  99.  
  100.  
  101.  
  102. function digCubeHorz(dir1,len1,dir2,len2,dir3,len3,refuel)
  103.  --after optimizing order, dir1 and dir2 will be horizontal and dir3 vertical
  104.  dir1,len1,dir2,len2,dir3,len3=optimizeForHorz(dir1,len1,dir2,len2,dir3,len3)
  105.  --the turtle is inside the cube so need to remove 1 distance
  106.  len1=len1-1
  107.  len2=len2-1
  108.  len3=len3-1
  109.  
  110.  local ceilingHeight=nil
  111.  local floorHeight=nil
  112.  
  113.  if dir3=="u" then
  114.   ceilingHeight=poz3.getPosField("y")+len3
  115.   floorHeight=poz3.getPosField("y")
  116.  else
  117.   ceilingHeight=poz3.getPosField("y")
  118.   floorHeight=poz3.getPosField("y")-len3
  119.  end
  120.  
  121.  --if thicker than 3 then move to more optimal position
  122.  if len3 >= 2 then
  123.   if digLoop(dir3,1,refuel)~=1 then return false end
  124.   len3=len3-1
  125.  end
  126.  
  127. local len2backup=len2
  128.  
  129.  --do the digging
  130.  while(true) do
  131.    while(true) do
  132.     --print("cubeHorz1: ",dir1,":",dir2,":",dir3)
  133.     local height=poz3.getPosField("y")
  134.     local succes1,_=digLoopExtraHorz(dir1,len1,refuel,height~=ceilingHeight,height~=floorHeight)
  135.     if not succes1 then return false end
  136.     dir1=poz3.getReverse(dir1)
  137.     if(len2==0) then break end
  138.     if digLoop(dir2,1,refuel)~=1 then return false end
  139.     len2=len2-1
  140.   end
  141.   len2=len2backup
  142.   dir2=poz3.getReverse(dir2)
  143.   if(len3<=1) then break end --last layer have already been mined
  144.   if(len3-3<0) then
  145.    if digLoop(dir3,2,refuel)~=2 then return false end
  146.    len3=len3-2
  147.   else
  148.    if digLoop(dir3,3,refuel)~=3 then return false end
  149.    len3=len3-3
  150.   end
  151.  end
  152.  return true
  153. end
  154.  
  155.  
  156.  
  157.  
  158. function optimizeForHorz(dir1,len1,dir2,len2,dir3,len3)
  159.  local dirTable={dir1,dir2,dir3}
  160.  local lenTable={len1,len2,len3}
  161.  
  162.  local verticalDir=3
  163.  local longDir=3
  164.  local shortDir=3
  165.  local longLen=-1
  166.  
  167.  for index,dir in ipairs(dirTable) do
  168.   if(dir~=nil) then
  169.    if poz3.isVertical(dir) then
  170.     verticalDir=index
  171.    else
  172.     local len=lenTable[index]
  173.     if(len>longLen) then
  174.      if(longLen>-1) then
  175.       --had previous longdir
  176.       --so that should now be shortdir
  177.       shortDir=longDir
  178.      end
  179.      longDir=index
  180.      longLen=len
  181.     else
  182.      shortDir=index
  183.     end
  184.    end
  185.   end
  186.  end--for
  187.  return dirTable[longDir],lenTable[longDir],
  188.   dirTable[shortDir],lenTable[shortDir],
  189.   dirTable[verticalDir],lenTable[verticalDir]
  190. end
  191.  
  192.  
  193.  
  194. function detectDig(direction)
  195.  if(poz3.detect(direction)) then
  196.   if(not poz3.dig(direction)) then
  197.    return false
  198.   end
  199.  end
  200.  return true
  201. end
  202.  
  203.  
  204.  
  205. function digLoopExtraHorz(direction,length,refuel,up,down)
  206.  if up then up="u" else up=nil end
  207.  if down then down="d" else down=nil end
  208.  --print("loopExtraHorz: ",direction,":",dir1,":",dir2,":",dir3)
  209.  return digLoopExtra(direction,length,refuel,up,down,nil)
  210. end
  211.  
  212. --first return, returns if successful or not
  213. --second return, returns the number of steps taken
  214. function digLoopExtra(direction,length,refuel,dir1,dir2,dir3)
  215.  --print("loopExtra: ",direction,":",dir1,":",dir2,":",dir3)
  216.  local i=0
  217.  while(i<length) do
  218.   local succes,len=detectDigGoExtra(direction,refuel,dir1,dir2,dir3,true)
  219.   if not succes then
  220.    return false, i+len
  221.   end
  222.   i=i+1
  223.  end
  224.  return true,i
  225. end
  226.  
  227. --digs and goes in the given direction
  228. --then in the additional directions
  229. --have two return values
  230. --the first is if successful, the second is the number of steps taken
  231. function detectDigGoExtra(direction,refuel,dir1,dir2,dir3,preDig)
  232.  --print("digExtra: ",direction,":",dir1,":",dir2,":",dir3)
  233.  if preDig then
  234.    if dir1 and not detectDig(dir1) then return false,0 end
  235.    if dir2 and not detectDig(dir2) then return false,0 end
  236.    if dir3 and not detectDig(dir3) then return false,0 end
  237.  end
  238.  if detectDigGo2(direction,refuel) then
  239.    if dir1 and not detectDig(dir1) then return false,1 end
  240.    if dir2 and not detectDig(dir2) then return false,1 end
  241.    if dir3 and not detectDig(dir3) then return false,1 end
  242.    return true,1
  243.  end
  244.  return false,0
  245. end
  246.  
  247. function checkNormal(dir1,dir2,dir3)
  248.  local tmp={}
  249.  return checkNormalHelp(tmp,dir1) and
  250.   checkNormalHelp(tmp,dir2) and
  251.   checkNormalHelp(tmp,dir3)
  252. end
  253.  
  254. function checkNormalHelp(tmp,adir)
  255.  if adir==nil then return true end
  256.  if tmp[adir] or tmp[poz3.getReverse(adir)] then
  257.   return false
  258.  end
  259.  tmp[adir]=adir
  260.  tmp[poz3.getReverse(adir)]=adir
  261.  return true
  262. end
  263.  
  264. function detectDigGo2(direction,refuel)
  265.  --loop so that it won't be stopped by gravel
  266.  while(true) do
  267.   --try to dig if it detects a block
  268.   if(poz3.detect(direction)) then
  269.    if(not poz3.dig(direction)) then
  270.     return false
  271.    end
  272.   end
  273.   --try to go
  274.   if poz3.go(direction) then
  275.    return true
  276.   else
  277.    --if failed because of fuel
  278.    --then refuel if refuel is true
  279.    if turtle.getFuelLevel() == 0 then
  280.     if not refuel or not doRefuel() then
  281.      --refuel was false or had no fuel in inventory
  282.      return false
  283.     end
  284.    end
  285.    os.sleep(0.5)--changed to 0.5 from 1
  286.   end
  287.  end --while
  288. end
  289.  
  290.  
  291.  
  292. function digToCoordsHelp(fieldName,targetCoord,refuel)
  293.  local direction, length=poz3.coordToGoValues(fieldName,targetCoord)
  294.  if length==0 then return true,0 end
  295.  local length2=digLoop(direction,length,refuel)
  296.  return length2==length, length2
  297. end
  298.  
  299. function digToCoords(x,y,z,f,refuel)
  300.  local succes=true
  301.  if x~=nil then
  302.   succes = digToCoordsHelp("x",x,refuel) and succes
  303.  end
  304.  if y~=nil then
  305.   succes = digToCoordsHelp("y",y,refuel) and succes
  306.  end
  307.  if z~=nil then
  308.   succes = digToCoordsHelp("z",z,refuel) and succes
  309.  end
  310.  if f~=nil then
  311.   succes = poz3.turn(f) and succes
  312.  end
  313.  return succes
  314. end
  315.  
  316. function digToCoords2(aPosT)
  317.  return digToCoords(aPosT["x"],aPosT["y"],aPosT["z"],aPosT["f"],refuel)
  318. end
  319.  
  320. function doRefuel(amount)
  321.  if amount==nil then
  322.   os.run({},"rom/programs/turtle/refuel")
  323.   --shell.run("refuel")
  324.  else
  325.   --shell.run("refuel",tostring(amount))
  326.   os.run({},"rom/programs/turtle/refuel",tostring(amount))
  327.  end
  328.  return turtle.getFuelLevel()>0
  329. end
  330.  
  331. function refuelToLevel(level)
  332.  local fuelLevel=turtle.getFuelLevel()
  333.  while(fuelLevel<level) do
  334.   doRefuel()
  335.   if(fuelLevel==turtle.getFuelLevel()) then
  336.    return false
  337.   end
  338.   fuelLevel=turtle.getFuelLevel()
  339.  end
  340.  return true
  341. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement