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)
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
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
function pathThrough(points, dist, s, e)
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)