Kulgan_Starkk

new 'go' utility

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