Make sure pathfinding doesn't go through bedrock

This commit is contained in:
Jack O'Sullivan 2024-01-16 23:35:57 +00:00
parent 50027f90b1
commit 2a53a3c4c6

View File

@ -44,19 +44,16 @@ end
function findDistances(points) function findDistances(points)
local dist = arr2(#points, #points, math.huge) local dist = arr2(#points, #points, math.huge)
-- local prev = arr2(#points, #points)
for i = 1, #points do for i = 1, #points do
for j = 1, #points do for j = 1, #points do
if i ~= j then if i ~= j then
dist[i][j] = (points[i] - points[j]):length() dist[i][j] = (points[i] - points[j]):length()
-- prev[i][j] = i
end end
end end
end end
for i = 1, #points do for i = 1, #points do
dist[i][i] = 0 dist[i][i] = 0
-- prev[i][i] = i
end end
return dist return dist
@ -119,35 +116,8 @@ function groupOres(ores, dist, offset)
return retGroups return retGroups
end end
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 -- nearest neighbour
function pathThrough(points, dist, s, e)
local unvisited = {} local unvisited = {}
local ui = nil local ui = nil
for i = 1, #points do for i = 1, #points do
@ -188,7 +158,7 @@ function pathThrough(points, dist, s, e)
end end
-- A* -- A*
function findPath(s, e) function findPath(s, e, neighbors)
local points = {} local points = {}
function addPoint(p) function addPoint(p)
local k = p:tostring() local k = p:tostring()
@ -204,23 +174,6 @@ function findPath(s, e)
return (points[e] - points[i]):length() return (points[e] - points[i]):length()
end 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 = {} local gScoreT = {}
gScoreT[s] = 0 gScoreT[s] = 0
function gScore(i) function gScore(i)
@ -255,7 +208,11 @@ function findPath(s, e)
break break
end 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 for _, n in ipairs(ns) do
tentativeG = gScore(current) + 1 tentativeG = gScore(current) + 1
if tentativeG < gScore(n) then if tentativeG < gScore(n) then
@ -452,6 +409,22 @@ function Miner:xchgItems()
end end
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) function Miner:safeMove(dir)
if dir == "up" then if dir == "up" then
while turtle.detectUp() do while turtle.detectUp() do
@ -493,7 +466,7 @@ function Miner:findOres(radius)
local found = {} local found = {}
for _, b in ipairs(info) do for _, b in ipairs(info) do
-- only ores and avoid bedrock -- 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) table.insert(found, b)
end end
end end
@ -527,7 +500,7 @@ function Miner:navigateThrough(path)
-- print("doing", delta) -- print("doing", delta)
if delta:length() ~= 1 then if delta:length() ~= 1 then
-- print("path finding between points") -- 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, 1)
table.remove(path, #path) table.remove(path, #path)
assert(#path ~= 0) assert(#path ~= 0)
@ -626,7 +599,8 @@ function Miner:mineOres(radius)
end end
assert(closest) 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, 1)
table.remove(pathToStart, #pathToStart) table.remove(pathToStart, #pathToStart)