Guest User

new 'go' utility

a guest
Mar 17th, 2014
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.94 KB | None | 0 0
  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. -- Enables mob detection capabilities of CAPS move forward for noncaps forward
  20. local function mdForward()
  21. if turtle.detect() == false then
  22. turtle.forward()
  23. end
  24. end
  25.  
  26. -- CAPS-letter commands evaluator, move-only
  27. -- Remove code duplication by encapsulating common pattern in function
  28. local function mdMove(command, detector)
  29. while detector() == false do
  30. command()
  31. end
  32. end
  33.  
  34. -- CAPS-letter commands evaluator, dig-only
  35. -- Remove code duplication by encapsulating common pattern in function
  36. local function mdDig(command, detector)
  37. while detector() do
  38. command()
  39. sleep(0.4)
  40. end
  41. end
  42.  
  43. -- Evaluate prefix commands
  44. local function runPrefixCmd(ch, digCmd, detectCmd, placeCmd)
  45. local chCode = string.byte(ch, 1) - 48
  46. if false then
  47. elseif ch == 'm' then return true, digCmd()
  48. elseif ch == 'M' then mdDig(digCmd, detectCmd); return true, false -- todo: better result return
  49. elseif ch == '0' then return true, placeCmd()
  50. elseif chCode > 0 and chCode < 10 then
  51. turtle.select(chCode)
  52. res = placeCmd()
  53. return true, res
  54. end
  55. return false, false
  56. end
  57.  
  58. -- Lua specific array length
  59. local function lngth(lst)
  60. if lst == nil then return 0 else return #lst end
  61. end
  62.  
  63. local function parseNumber(st)
  64. _, _, num, rest = string.find(st, "^(%d+)(.*)$")
  65. return num, lngth(st) - lngth(rest)
  66. end
  67.  
  68. local function parseLoop(st)
  69. _, _, loop, rest = string.find(st, "^(%b[])(.*)$")
  70. if loop ~= nil and loop ~= '' then
  71. return loop:sub(2,-2), lngth(st) - lngth(rest)
  72. elseif st:sub(1,1) == '[' then return nil, 1
  73. else return nil, 0
  74. end
  75. end
  76.  
  77. function go(command)
  78. local i = 1
  79. local prevCommand = ''
  80. local result = false
  81.  
  82. while i <= #command do
  83. local ch = command:sub(i, i)
  84. local nextCh = i == #command and '' or command:sub(i+1, i+1)
  85.  
  86. local number, nLen = parseNumber(command:sub(i))
  87. local loop, lLen = parseLoop(command:sub(i))
  88.  
  89. -- if we found number, repeat last command number times
  90. if number ~= nil then
  91. number = tonumber(number)
  92. while number > 1 do
  93. go(prevCommand)
  94. number = number - 1
  95. end
  96. i = i + nLen - 1
  97. -- if we found loop, parse possible number and evaluate expression
  98. elseif loop ~= nil then
  99. local number, nLen = parseNumber(command:sub(i + lLen))
  100. if number ~= nil then
  101. number = tonumber(number)
  102. while number > 0 do
  103. go(loop)
  104. number = number - 1
  105. end
  106. i = i + nLen
  107. else
  108. while go(loop) do end
  109. end
  110. i = i + lLen - 1
  111.  
  112. elseif ch == 'f' then result = mdForward()
  113. elseif ch == 'b' then result = turtle.back()
  114. elseif ch == 'u' then result = turtle.up()
  115. elseif ch == 'd' then result = turtle.down()
  116.  
  117. elseif ch == 'F' then mdMove(mdForward, turtle.detect)
  118. elseif ch == 'B' then go("aFa") -- this is not primitive
  119. elseif ch == 'U' then mdMove(turtle.up, turtle.detectUp)
  120. elseif ch == 'D' then mdMove(turtle.down, turtle.detectDown)
  121.  
  122. elseif ch == 'l' then turtle.turnLeft()
  123. elseif ch == 'r' then turtle.turnRight()
  124. elseif ch == 'a' then go("ll")
  125.  
  126. elseif ch == 'm' then result = turtle.dig()
  127. elseif ch == 'M' then mdDig(turtle.dig, turtle.detect)
  128.  
  129. elseif ch == '>' then
  130. local result1,result2 = runPrefixCmd(nextCh, turtle.dig, turtle.detect, turtle.place)
  131. if result1 then
  132. i = i + 1 -- todo: better prefix parsing
  133. end
  134. result = result2
  135. elseif ch == '^' then
  136. local result1,result2 = runPrefixCmd(nextCh, turtle.digUp, turtle.detectUp, turtle.placeUp)
  137. if result1 then
  138. i = i + 1
  139. end
  140. result = result2
  141. elseif ch == '_' then
  142. local result1,result2 = runPrefixCmd(nextCh, turtle.digDown, turtle.detectDown, turtle.placeDown)
  143. if result1 then
  144. i = i + 1
  145. end
  146. result = result2
  147. end
  148.  
  149. prevCommand = ch
  150. i = i + 1
  151. end
  152. return result
  153. end
  154.  
  155. go(tArgs[1])
Advertisement
Add Comment
Please, Sign In to add comment