View difference between Paste ID: 6aFnnJtx and 3LCNQCLT
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
-- 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 act(loop) do end
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 act("aFa") -- this is not primitive
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 act("ll")
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])