123 lines
3.2 KiB
Lua
123 lines
3.2 KiB
Lua
-- Removes blocks which are not placeable
|
|
local function removeNonBlocks()
|
|
-- Travel to the ground to test if it can place each item
|
|
local traveled = 0
|
|
while not turtle.detectDown() do turtle.down() traveled = traveled + 1 end
|
|
local blocks = {}
|
|
|
|
-- Try placing each item and look at the error message produced
|
|
-- If the message contains 'item' then it is an item
|
|
for i=1, 16 do
|
|
blocks[i] = turtle.getItemDetail(i)
|
|
if blocks[i] then
|
|
turtle.select(i)
|
|
local _, reason = turtle.placeDown()
|
|
if reason:match("item") then
|
|
print(("Found non-block in slot '%s'"):format(i))
|
|
blocks[i] = true
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Travel back up to where the turtle started
|
|
for _=1, traveled do turtle.up() end
|
|
-- Drop all the items marked as non-blocks
|
|
for i, details in pairs(blocks) do
|
|
if type(details) ~= "table" then
|
|
turtle.select(i)
|
|
turtle.drop()
|
|
blocks[i] = nil
|
|
end
|
|
end
|
|
return blocks
|
|
end
|
|
|
|
local function followPath(walk_path)
|
|
local command_lookup = {
|
|
U = turtle.up, D = turtle.down,
|
|
F = turtle.forward, B = turtle.back,
|
|
L = turtle.turnLeft, R = turtle.turnRight
|
|
}
|
|
local count, op = 0, ""
|
|
local pattern_iterator = walk_path:gmatch("(%d+)([UDFBLR])")
|
|
return function()
|
|
while true do
|
|
if count == 0 then
|
|
count, op = pattern_iterator()
|
|
if not (count and op) then return end
|
|
end
|
|
|
|
command_lookup[op]()
|
|
count = count - 1
|
|
if op ~= "L" and op ~= "R" then
|
|
return count, op
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function getTravelCost(walk_path)
|
|
local distance = 0
|
|
for count, op in walk_path:gmatch("(%d+)([UDFBLR])") do
|
|
if op ~= "L" and op ~= "R" then
|
|
distance = distance + count
|
|
end
|
|
end
|
|
return distance
|
|
end
|
|
|
|
-- Main
|
|
math.randomseed(os.epoch())
|
|
local build_path = "6F 1R 20F 1R 14F 1R 20F 1R 5F"
|
|
|
|
local travel_cost = getTravelCost(build_path)
|
|
if travel_cost > turtle.getFuelLevel() then
|
|
print(("- Insufficient fuel level %s, needed %s"):format(turtle.getFuelLevel(), travel_cost))
|
|
return
|
|
end
|
|
print(("- Sufficient fuel level %s, needed %s"):format(turtle.getFuelLevel(), travel_cost))
|
|
|
|
print("- Removing items which are not blocks")
|
|
local blocks_lookup = {}
|
|
local total_blocks = 0
|
|
for i, details in pairs(removeNonBlocks()) do
|
|
local name = ("%s/%s"):format(details.name, details.damage or 0)
|
|
blocks_lookup[name] = blocks_lookup[name] or {}
|
|
blocks_lookup[name][i] = details.count
|
|
blocks_lookup[name].total = (blocks_lookup[name].total or 0) + details.count
|
|
total_blocks = total_blocks + details.count
|
|
end
|
|
turtle.up()
|
|
|
|
if travel_cost > total_blocks then
|
|
print(("- Insufficient block count %s, needed %s"):format(total_blocks, travel_cost))
|
|
return
|
|
end
|
|
print(("- Sufficient block count %s, needed %s"):format(total_blocks, travel_cost))
|
|
|
|
print(("- Following path and building: '%s'"):format(build_path))
|
|
for _ in followPath(build_path) do
|
|
local target_name, target_score
|
|
|
|
for name, details in pairs(blocks_lookup) do
|
|
local score = details.total * math.random()
|
|
if not target_score or score > target_score then
|
|
target_score = score
|
|
target_name = name
|
|
end
|
|
end
|
|
|
|
local target_block = blocks_lookup[target_name]
|
|
for i=1, 16 do
|
|
if target_block[i] and target_block[i] > 0 then
|
|
turtle.select(i)
|
|
target_block[i] = target_block[i] - 1
|
|
target_block.total = target_block.total - 1
|
|
break
|
|
end
|
|
end
|
|
turtle.placeDown()
|
|
end
|
|
|
|
print("- Finished")
|