Advertisement
Guest User

ComputerCraft "go" utility alternative v1

a guest
Aug 2nd, 2012
589
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --   Block actions combinators v1 (go)
  2. --
  3. -- f b u d l r   -- Move forward, backward, up, down, turn left, turn right
  4. -- F B U D       -- same moves, but move until block detected
  5. -- m M   --  mine block, mine blocks while block present (usefull for gravel mining)
  6. -- [commands lastcommand]   --  loop while lastcommand returns success
  7. -- commandNUMBER   -- loop command NUMBER times
  8. -- [commands]NUMBER -- loop commands list NUMBER times
  9. -- >DIGIT   --   place block from DIGIT slot. When DIGIT == 0, place first available
  10. -- ^DIGIT   --   place block up
  11. -- _DIGIT   --   place block down
  12.  
  13. local tArgs = { ... }
  14. if #tArgs ~= 1 then
  15.   print("Usage: go <list of commands>")
  16.   return
  17. end
  18.  
  19. -- CAPS-letter commands evaluator, move-only
  20. -- Remove code duplication by encapsulating common pattern in function
  21. local function mdMove(command, detector)
  22.   while detector() == false do
  23.     command()
  24.   end
  25. end
  26.  
  27. -- CAPS-letter commands evaluator, dig-only
  28. -- Remove code duplication by encapsulating common pattern in function
  29. local function mdDig(command, detector)
  30.   while detector() do
  31.     command()
  32.     sleep(0.4)
  33.   end
  34. end
  35.  
  36. -- Evaluate prefix commands
  37. local function runPrefixCmd(ch, digCmd, detectCmd, placeCmd)
  38.   local chCode = string.byte(ch, 1) - 48
  39.   if false then
  40.   elseif ch == 'm' then return true, digCmd()
  41.   elseif ch == 'M' then mdDig(digCmd, detectCmd); return true, false -- todo: better result return
  42.   elseif ch == '0' then return true, placeCmd()
  43.   elseif chCode > 0 and chCode < 10 then
  44.     turtle.select(chCode)
  45.     res = placeCmd()
  46.     return true, res
  47.   end
  48.   return false, false
  49. end
  50.  
  51. -- Lua specific array length
  52. local function lngth(lst)
  53.   if lst == nil then return 0 else return #lst end
  54. end
  55.  
  56. local function parseNumber(st)
  57.   _, _, num, rest = string.find(st, "^(%d+)(.*)$")
  58.   return num, lngth(st) - lngth(rest)
  59. end
  60.  
  61. local function parseLoop(st)
  62.   _, _, loop, rest = string.find(st, "^(%b[])(.*)$")
  63.   if loop ~= nil and loop ~= '' then
  64.     return loop:sub(2,-2), lngth(st) - lngth(rest)
  65.   elseif st:sub(1,1) == '[' then return nil, 1
  66.   else return nil, 0
  67.   end
  68. end
  69.  
  70. function go(command)
  71.   local i = 1
  72.   local prevCommand = ''
  73.   local result = false
  74.  
  75.   while i <= #command do
  76.     local ch = command:sub(i, i)
  77.     local nextCh = i == #command and '' or command:sub(i+1, i+1)
  78.    
  79.     local number, nLen = parseNumber(command:sub(i))
  80.     local loop, lLen   = parseLoop(command:sub(i))
  81.    
  82.     -- if we found number, repeat last command number times
  83.     if number ~= nil then
  84.       number = tonumber(number)
  85.       while number > 1 do
  86.         go(prevCommand)
  87.         number = number - 1
  88.       end
  89.       i = i + nLen - 1
  90.     -- if we found loop, parse possible number and evaluate expression
  91.     elseif loop ~= nil then
  92.       local number, nLen = parseNumber(command:sub(i + lLen))
  93.       if number ~= nil then
  94.         number = tonumber(number)
  95.         while number > 0 do
  96.           go(loop)
  97.           number = number - 1
  98.         end
  99.         i = i + nLen
  100.       else
  101.         while go(loop) do end
  102.       end
  103.       i = i + lLen - 1
  104.      
  105.     elseif ch == 'f' then result = turtle.forward()
  106.     elseif ch == 'b' then result = turtle.back()
  107.     elseif ch == 'u' then result = turtle.up()
  108.     elseif ch == 'd' then result = turtle.down()
  109.    
  110.     elseif ch == 'F' then mdMove(turtle.forward, turtle.detect)
  111.     elseif ch == 'B' then go("aFa") -- this is not primitive
  112.     elseif ch == 'U' then mdMove(turtle.up, turtle.detectUp)
  113.     elseif ch == 'D' then mdMove(turtle.down, turtle.detectDown)
  114.    
  115.     elseif ch == 'l' then turtle.turnLeft()
  116.     elseif ch == 'r' then turtle.turnRight()
  117.     elseif ch == 'a' then go("ll")
  118.    
  119.     elseif ch == 'm' then result = turtle.dig()
  120.     elseif ch == 'M' then mdDig(turtle.dig, turtle.detect)
  121.  
  122.     elseif ch == '>' then
  123.       local result1,result2 = runPrefixCmd(nextCh, turtle.dig, turtle.detect, turtle.place)
  124.       if result1 then
  125.         i = i + 1 -- todo: better prefix parsing
  126.       end
  127.       result = result2
  128.     elseif ch == '^' then
  129.       local result1,result2 = runPrefixCmd(nextCh, turtle.digUp, turtle.detectUp, turtle.placeUp)
  130.       if result1 then
  131.         i = i + 1
  132.       end
  133.       result = result2
  134.     elseif ch == '_' then
  135.       local result1,result2 = runPrefixCmd(nextCh, turtle.digDown, turtle.detectDown, turtle.placeDown)
  136.       if result1 then
  137.         i = i + 1
  138.       end
  139.       result = result2
  140.     end
  141.    
  142.     prevCommand = ch
  143.     i = i + 1
  144.   end
  145.   return result
  146. end
  147.  
  148. go(tArgs[1])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement