· 4 years ago · Mar 28, 2021, 04:36 PM
1-- Mysplit borrowed kindly from the interwebs
2
3function mysplit (inputstr, sep)
4 if sep == nil then
5 sep = "%s"
6 end
7 local t={}
8 for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
9 table.insert(t, str)
10 end
11 return t
12end
13
14
15-- Remove trailing and prefixing whitespaces
16function tail(string)
17 return string.sub(2)
18end
19
20function head(string)
21 return string.sub(1, -1)
22end
23
24function removeTW(string)
25 if string.sub(1, 1) == " " then
26 return removeTW(tail(string))
27 elseif string.sub(-1, -1) == " " then
28 return removeTW(head(string))
29 else
30 return string
31 end
32end
33
34-- Should return a dictionary:
35-- Origin co-ordinates
36-- Chest co-ordinates
37
38
39function ParseConfiguration()
40 local tableT = {}
41
42
43 local fileHandler = fs.open("./Configuration.config", "r")
44 print("hi")
45 local data = fileHandler.readAll()
46 print(data)
47 local data_array = mysplit(data, "\n")
48
49 for i,item in ipairs(data_array) do
50 if item.sub(1, 2) ~= "//" then
51 local seperation = mysplit(item, ":")
52
53 seperation[1] = removeTW(seperation[1])
54 seperation[2] = removeTW(seperation[2])
55
56 local coordinates = mysplit(seperation[2], ',')
57 coordinates[1] = tonumber(removeTW(coordinates[1]))
58 coordinates[2] = tonumber(removeTW(coordinates[2]))
59 coordinates[3] = tonumber(removeTW(coordinates[3]))
60
61 tableT[seperation[1]] = coordinates
62 end
63 end
64
65 return tableT
66end
67
68
69function taxicabDistance(vecA, vecB)
70 return math.abs((vecB[1] - vecA[1]) + (vecB[2] - vecA[2]) + (vecB[3] - vecA[3]))
71end
72
73-- -------------------------- Meta Class for Turtle ------------------------- --
74-- I can get away with defining it as 'Turtle' due to the fact that the turtle
75-- API is lowercase
76-- -------------------------------------------------------------------------- --
77
78Turtle = {
79 origin = {0, 0, 0}, -- To be constant
80 savedPositionBuffer = {}, -- To be a dictionary. Key = Tag, Value = Position Coords
81 state = {},
82 selectedSlot = 1,
83 time = 0
84}
85
86function Turtle:new()
87 o = {}
88
89 setmetatable(o, self)
90 self.__index = self
91 self.savedPositionBuffer = ParseConfiguration()
92
93 self.state["Orientation"] = 0
94 self.state["Stuck"] = false
95 self.state["Current Position"] = {}
96 self.state["Current Position"][1] = self.savedPositionBuffer["Start Position"][1]
97 self.state["Current Position"][2] = self.savedPositionBuffer["Start Position"][2]
98 self.state["Current Position"][3] = self.savedPositionBuffer["Start Position"][3]
99 self.state["Blocks to move"] = turtle.getFuelLevel()
100 self.savedPositionBuffer["oldPos"] = {}
101 return o
102end
103
104
105-- ----------- Some data on directions and alterations to position ---------- --
106
107directionalLookupTable = {
108 [0] = {0, 1},
109 [1] = {1, 0},
110 [2] = {0, -1},
111 [3] = {-1, 0},
112}
113
114
115
116-- -------------------------------- Movement! ------------------------------- --
117
118function Turtle:attemptPathFix(direction)
119 local actions = {}
120 actions["forward"] = {turtle.attack, turtle.dig, turtle.forward}
121 actions["up"] = {turtle.attackUp, turtle.digUp, turtle.up}
122 actions["down"] = {turtle.attackDown, turtle.digDown, turtle.down}
123 actions["back"] = {turtle.attackBack, turtle.digBack, turtle.back}
124
125
126
127 local incidentCounter = 0
128
129 while incidentCounter < 50 do
130 local result = false
131
132 for i,action in ipairs(actions[direction]) do
133 result = action()
134 end
135
136 if not result then
137 incidentCounter = incidentCounter + 1
138 else
139 return
140 end
141 end
142 save = {}
143 save[1] = self.state["Current Position"][1]
144 save[2] = self.state["Current Position"][2]
145 save[3] = self.state["Current Position"][3]
146 print(save[1])
147 print("hi")
148 self:Goto(self.savedPositionBuffer["Fuel Chest Position"])
149 self:Halt("Error 1: Persistent impediment detected in quarry. Returned to home and awaiting instructions.", true)
150 self:Goto(save, {3, 1, 2})
151 print("Exited!")
152end
153
154function Turtle:forward()
155 local result = turtle.forward()
156 if not result then
157 self:attemptPathFix("forward")
158 end
159
160
161 -- Alter current position dependent on direction
162 local o = self.state["Orientation"]
163
164 self.state["Current Position"][1] = self.state["Current Position"][1] + directionalLookupTable[o][1]
165 self.state["Current Position"][2] = self.state["Current Position"][2] + directionalLookupTable[o][2]
166
167 self.state["Blocks to move"] = self.state["Blocks to move"] - 1
168end
169
170function Turtle:backward()
171 local result = turtle.back()
172
173 if not result then
174 self:attemptPathFix("back")
175 end
176
177 self.state["Current Position"][1] = self.state["Current Position"][1] - directionalLookupTable[self.state["Orientation"]][1]
178 self.state["Current Position"][2] = self.state["Current Position"][2] - directionalLookupTable[self.state["Orientation"]][2]
179
180 self.state["Blocks to move"] = self.state["Blocks to move"] - 1
181
182end
183
184function Turtle:left()
185 print("this is bad")
186 local result = turtle.turnLeft()
187 self.state["Orientation"] = (self.state["Orientation"] + 1) % 4
188end
189
190function Turtle:right()
191 local result = turtle.turnRight()
192
193 self.state["Orientation"] = (self.state["Orientation"] - 1) % 4
194end
195
196function Turtle:up()
197 local result = turtle.up()
198 if not result then
199 self:attemptPathFix("up")
200 end
201
202 self.state["Current Position"][3] = self.state["Current Position"][3] + 1
203 self.state["Blocks to move"] = self.state["Blocks to move"] - 1
204
205end
206
207function Turtle:down()
208 local result = turtle.down()
209
210 if not result then
211 self:attemptPathFix("down")
212 end
213
214 self.state["Current Position"][3] = self.state["Current Position"][3] - 1
215 self.state["Blocks to move"] = self.state["Blocks to move"] - 1
216end
217
218function Turtle:dig()
219 turtle.dig()
220end
221
222function Turtle:Orient(direction)
223 while (self.state["Orientation"] ~= direction) do
224 self:left()
225 end
226end
227
228function Turtle:Goto(position, order)
229 print("Going to: ["..position[1]..", "..position[2]..", "..position[3].."]")
230 order = order or {1, 2, 3}
231 if position[1] == self.state["Current Position"][1] and position[2] == self.state["Current Position"][2] and position[3] == self.state["Current Position"][3] then
232 return
233 end
234
235 for i, item in ipairs(order) do
236 if item == 1 or item == 2 then
237 if self.state["Current Position"][item] < position[item] then
238 if item == 1 then
239 self:Orient(1)
240 else
241 self:Orient(0)
242 end
243 for i = 1, position[item] - self.state["Current Position"][item] do
244 self:forward()
245 end
246 else
247 if item == 1 then
248 self:Orient(3)
249
250 else
251 self:Orient(2)
252 end
253
254 print(self.state["Current Position"][item] - position[item])
255
256 for i = 1, self.state["Current Position"][item] - position[item] do
257 self:forward()
258 end
259 end
260
261
262 else
263 if self.state["Current Position"][item] < position[item] then
264 for i = 1, position[item] - self.state["Current Position"][item] do
265 self:up()
266 end
267 else
268 for i = 1, self.state["Current Position"][item] - position[item] do
269 self:down()
270 end
271 end
272 end
273 end
274end
275
276function Turtle:CheckNeedToReturn()
277 local d = self.state["Orientation"]
278
279 count = 1
280 if self.time == 32 then
281 repeat
282 turtle.select(count)
283 turtle.refuel()
284 count = count + 1
285 until count == 17
286 end
287
288 self.time = self.time + 1
289 self.time = self.time % 33
290
291 self.state["Blocks to move"] = turtle.getFuelLevel()
292 if taxicabDistance(self.state["Current Position"], self.savedPositionBuffer["Refuel Chest Position"]) + 1>= self.state["Blocks to move"] then
293
294
295 self:Halt("Error 2: Fuel levels are low (<500) even after local and global refuel attempt. Please add fuel into slot 1 and continue.", true)
296 end
297
298
299end
300
301function Turtle:CheckNeedToDeposit()
302 print("hello")
303 local d = self.state["Orientation"]
304
305 local counter = 0
306
307 while turtle.getItemCount(self.selectedSlot) > 0 do
308 self.selectedSlot = (self.selectedSlot%16)+1
309
310
311 counter = counter + 1
312
313 if (counter == 16) then
314 self.state["Save"] = {}
315 self.state["Save"][1] = self.state["Current Position"][1]
316 self.state["Save"][2] = self.state["Current Position"][2]
317 self.state["Save"][3] = self.state["Current Position"][3]
318 print(self.state["Save"][2])
319 print(self.state["Current Position"][2])
320 print("we here?")
321 self:Goto(self.savedPositionBuffer["Item Chest Position"], {3, 1, 2})
322
323
324 counter = 0
325 while true do
326 print(counter)
327 self.selectedSlot = (self.selectedSlot%16)+1
328
329 if self.selectedSlot ~= 1 then
330 turtle.select(self.selectedSlot)
331 turtle.drop()
332 end
333 sleep(1)
334
335 counter = counter + 1
336
337 if (counter == 16) then
338 break
339 end
340 end
341 print(self.state["Current Position"][1])
342 print(self.state["Save"][1])
343 self:Goto(self.state["Save"], {1, 2, 3})
344 self:Orient(d)
345 return
346
347 end
348 end
349
350
351end
352
353function Turtle:chunk()
354
355 local x = 16
356 local y = 16
357
358
359 for z = 1, self.savedPositionBuffer["Start Position"][3] - 2 do
360 self:CheckNeedToReturn()
361 turtle.digDown()
362 self:down()
363 self:Orient(2)
364 self.savedPositionBuffer["oldPos"][1] = self.state["Current Position"][1]
365 self.savedPositionBuffer["oldPos"][2] = self.state["Current Position"][2]
366 self.savedPositionBuffer["oldPos"][3] = self.state["Current Position"][3]
367
368 for i = 1, x do
369 for j = 2, y do
370 self:CheckNeedToReturn()
371 self:CheckNeedToDeposit()
372
373
374
375 self:dig()
376 self:forward()
377 end
378
379 if self.state["Orientation"] == 0 then
380
381 self:right()
382 self:dig()
383
384 self:CheckNeedToReturn()
385 self:CheckNeedToDeposit()
386
387
388
389 self:forward()
390
391
392 self:right()
393 else
394 self:left()
395 self:dig()
396
397 self:CheckNeedToReturn()
398 self:CheckNeedToDeposit()
399
400
401 self:forward()
402
403
404 self:left()
405 end
406
407 end
408 self:Goto(self.savedPositionBuffer["oldPos"], {1, 2, 3})
409
410
411 end
412
413 self:Goto(self.savedPositionBuffer["Start Position"], {3, 2, 1})
414 self:Halt("[Log] The turtle has finished operations.")
415end
416
417function Turtle:Halt(message, isError)
418 print("Halted. Given message: "..message)
419
420 if isError then
421 print("You are advised to correct the current error")
422 print("or refer to Mila if you are unsure on what to do.")
423 print("Once you have corrected the error, please press enter.")
424 else
425 print("The system determines that this is not an error. Instead, it is")
426 print("likely a log that requires your attention. Please act on the message")
427 print("or refer to Mila if you are unsure on what to do.")
428
429 end
430 io.read()
431end
432
433t = Turtle:new()
434t:chunk()