· 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()