From 2a53a3c4c61312c924d7eb56e4b230114e236697 Mon Sep 17 00:00:00 2001 From: Jack O'Sullivan Date: Tue, 16 Jan 2024 23:35:57 +0000 Subject: [PATCH] Make sure pathfinding doesn't go through bedrock --- mine.lua | 80 +++++++++++++++++++------------------------------------- 1 file changed, 27 insertions(+), 53 deletions(-) diff --git a/mine.lua b/mine.lua index 4c30432..427fe06 100644 --- a/mine.lua +++ b/mine.lua @@ -44,19 +44,16 @@ end function findDistances(points) local dist = arr2(#points, #points, math.huge) - -- local prev = arr2(#points, #points) for i = 1, #points do for j = 1, #points do if i ~= j then dist[i][j] = (points[i] - points[j]):length() - -- prev[i][j] = i end end end for i = 1, #points do dist[i][i] = 0 - -- prev[i][i] = i end return dist @@ -119,35 +116,8 @@ function groupOres(ores, dist, offset) return retGroups end +-- nearest neighbour function pathThrough(points, dist, s, e) - -- local n = #points - - -- dist[s][n] = 0 - -- dist[n][s] = 0 - -- dist[e][n] = 0 - -- dist[n][e] = 0 - - -- for k = 1, #points do - -- for i = 1, #points do - -- for j = 1, #points do - -- if dist[i][j] > dist[i][k] + dist[k][j] then - -- dist[i][j] = dist[i][k] + dist[k][j] - -- prev[i][j] = prev[k][j] - -- end - -- end - -- yield() - -- end - -- end - - -- local path = {e} - -- while s ~= e do - -- e = prev[s][e] - -- table.insert(path, 1, e) - -- end - - -- return path - - -- nearest neighbour local unvisited = {} local ui = nil for i = 1, #points do @@ -188,7 +158,7 @@ function pathThrough(points, dist, s, e) end -- A* -function findPath(s, e) +function findPath(s, e, neighbors) local points = {} function addPoint(p) local k = p:tostring() @@ -204,23 +174,6 @@ function findPath(s, e) return (points[e] - points[i]):length() end - function neighbors(k) - local p = points[k] - local ns = { - p + vector.new( 1, 0, 0), - p + vector.new( 0, 1, 0), - p + vector.new( 0, 0, 1), - p + vector.new(-1, 0, 0), - p + vector.new( 0, -1, 0), - p + vector.new( 0, 0, -1), - } - - for i, n in ipairs(ns) do - ns[i] = addPoint(n) - end - return ns - end - local gScoreT = {} gScoreT[s] = 0 function gScore(i) @@ -255,7 +208,11 @@ function findPath(s, e) break end - local ns = neighbors(current) + local ns = neighbors(points[current]) + for i, n in ipairs(ns) do + ns[i] = addPoint(n) + end + for _, n in ipairs(ns) do tentativeG = gScore(current) + 1 if tentativeG < gScore(n) then @@ -452,6 +409,22 @@ function Miner:xchgItems() end end +function Miner:safeNeighbors(p) + local ns = { + p + vector.new( 1, 0, 0), + p + vector.new( 0, 1, 0), + p + vector.new( 0, 0, 1), + p + vector.new(-1, 0, 0), + p + vector.new( 0, 0, -1), + } + -- only allow downwards if above bedrock + if (self.absolutePos + p).y - 1 > -60 then + table.insert(ns, p + vector.new(0, -1, 0)) + end + + return ns +end + function Miner:safeMove(dir) if dir == "up" then while turtle.detectUp() do @@ -493,7 +466,7 @@ function Miner:findOres(radius) local found = {} for _, b in ipairs(info) do -- only ores and avoid bedrock - if ORES[b.name] and self.absolutePos.y + b.y >= -58 then + if ORES[b.name] and self.absolutePos.y + b.y > -60 then table.insert(found, b) end end @@ -527,7 +500,7 @@ function Miner:navigateThrough(path) -- print("doing", delta) if delta:length() ~= 1 then -- print("path finding between points") - local path = findPath(self.pos, p) + local path = findPath(self.pos, p, function(v) return self:safeNeighbors(v) end) table.remove(path, 1) table.remove(path, #path) assert(#path ~= 0) @@ -626,7 +599,8 @@ function Miner:mineOres(radius) end assert(closest) - local pathToStart = findPath(self.pos, closest) + -- Find path here so we can strip out the actual ore itself + local pathToStart = findPath(self.pos, closest, function(v) return self:safeNeighbors(v) end) table.remove(pathToStart, 1) table.remove(pathToStart, #pathToStart)