View difference between Paste ID: m2QNx7Le and Rrjp2E40
SHOW: | | - or go back to the newest paste.
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])