Авто-шахтёр и инвентарь
Ранее мы научили черепашку копать. Теперь сделаем её по-настоящему автономной: она сама следит за инвентарём, возвращается на базу чтобы выгрузить ресурсы, и снова уходит работать.
Инвентарь: полный API
turtle.getItemCount(slot) -- количество предметов в слоте (0 если пусто)
turtle.getItemDetail(slot) -- {name, count, damage} или nil
turtle.select(slot) -- выбрать активный слот
turtle.drop(count) -- выбросить из активного слота (вперёд)
turtle.dropUp(count) -- выбросить вверх (в сундук над черепашкой)
turtle.dropDown(count) -- выбросить вниз
turtle.place() -- поставить блок из активного слота вперёд
turtle.transferTo(slot, n) -- переместить n предметов в другой слот
Архитектура авто-шахтёра
Хороший авто-шахтёр состоит из нескольких независимых модулей:
Менеджер инвентаря
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
-- Предметы которые считаются мусором
local TRASH = {
["minecraft:cobblestone"] = true,
["minecraft:dirt"] = true,
["minecraft:gravel"] = true,
["minecraft:sand"] = true,
["minecraft:flint"] = true,
}
local function isTrash(name)
return TRASH[name] == true
end
local function getFreeSlots()
local free = 0
for slot = 1, 16 do
if turtle.getItemCount(slot) == 0 then
free = free + 1
end
end
return free
end
local function dropTrash()
local dropped = 0
for slot = 1, 16 do
local item = turtle.getItemDetail(slot)
if item and isTrash(item.name) then
turtle.select(slot)
turtle.drop()
dropped = dropped + item.count
end
end
turtle.select(1)
return dropped
end
Выгрузка в сундук
Черепашка возвращается домой и складывает всё в сундук:
-- Предполагаем что сундук находится над точкой старта
local function unloadToChest()
for slot = 1, 16 do
if turtle.getItemCount(slot) > 0 then
turtle.select(slot)
turtle.dropUp() -- в сундук сверху
end
end
turtle.select(1)
print("Выгрузка завершена")
end
Отслеживание позиции для возврата
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
local home = {x = 0, y = 0, z = 0}
local pos = {x = 0, y = 0, z = 0}
local facing = 0 -- 0=север 1=восток 2=юг 3=запад
local dxMap = {[0]=0, [1]=1, [2]=0, [3]=-1}
local dzMap = {[0]=1, [1]=0, [2]=-1, [3]=0}
local function recordForward()
pos.x = pos.x + dxMap[facing]
pos.z = pos.z + dzMap[facing]
end
local function recordUp() pos.y = pos.y + 1 end
local function recordDown() pos.y = pos.y - 1 end
local function recordTurnRight() facing = (facing + 1) % 4 end
local function recordTurnLeft() facing = (facing - 1 + 4) % 4 end
-- Обёртки с записью
local function forward()
if turtle.dig() then sleep(0.4) end
if turtle.forward() then recordForward(); return true end
return false
end
Возврат домой по координатам
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
local function returnHome()
-- сначала выравниваемся по Y
while pos.y > home.y do
turtle.up(); recordUp()
end
while pos.y < home.y do
turtle.down(); recordDown()
end
-- выравниваемся по X
if pos.x > home.x then
while facing ~= 3 do turtle.turnLeft(); recordTurnLeft() end
elseif pos.x < home.x then
while facing ~= 1 do turtle.turnRight(); recordTurnRight() end
end
while pos.x ~= home.x do
turtle.forward(); recordForward()
end
-- выравниваемся по Z
if pos.z > home.z then
while facing ~= 2 do turtle.turnLeft(); recordTurnLeft() end
elseif pos.z < home.z then
while facing ~= 0 do turtle.turnRight(); recordTurnRight() end
end
while pos.z ~= home.z do
turtle.forward(); recordForward()
end
print("Дома! Позиция: " .. pos.x .. ", " .. pos.y .. ", " .. pos.z)
end
Главный цикл шахтёра
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
local RETURN_THRESHOLD = 3 -- минимум свободных слотов
local FUEL_THRESHOLD = 200 -- минимум топлива для работы
local TARGET_DEPTH = 50
local function needsReturn()
return getFreeSlots() < RETURN_THRESHOLD
or turtle.getFuelLevel() < FUEL_THRESHOLD
end
local function mainLoop()
for depth = 1, TARGET_DEPTH do
-- проверяем нужен ли возврат
if needsReturn() then
print("Возврат на базу (глубина " .. depth .. ")")
returnHome()
unloadToChest()
-- TODO: заправиться
print("Продолжаю работу")
end
-- копаем шаг вниз
turtle.digDown()
turtle.down()
recordDown()
-- боковое сканирование
for turn = 1, 4 do
local ok, data = turtle.inspect()
if ok then
local label = data.name:match(":(.+)$") or data.name
if data.name:find("_ore") then
print("Руда: " .. label)
end
end
turtle.turnRight(); recordTurnRight()
end
end
returnHome()
unloadToChest()
print("Задание выполнено!")
end
mainLoop()
🚀 Задания
Задание 1
Добавь к авто-шахтёру автозаправку: после возврата домой черепашка проверяет слот 16. Если там уголь — заправляется. Если топлива не хватит на ещё один рейс — останавливается с сообщением.
Задание 2
Добавь статистику: считай количество добытых блоков каждого типа руды. В конце работы выводи таблицу: "Алмаз: 5, Железо: 32, Золото: 3".
Задание 3
Напиши функцию sortInventory(): сортирует инвентарь так чтобы все предметы одного типа были в соседних слотах. Используй turtle.transferTo().
Задание 4
Улучши dropTrash(): не выбрасывай мусор если в инвентаре меньше 8 свободных слотов — сначала посчитай стоит ли тратить время. Если выбросить меньше 5 предметов — не стоит.
Задание 5
Реализуй систему "чёрного ящика": перед каждым значимым действием (движение, копание, возврат) записывай в таблицу log запись с действием и временем (os.time()). В конце работы выводи последние 20 записей.