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]) |