Advertisement
Doob

Doob's digger

Feb 28th, 2019
333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 27.75 KB | None | 0 0
  1. local component = require('component') -- подгрузить обертку из OpenOS
  2. local computer = require('computer')
  3. local chunks = 9 -- количество чанков для добычи
  4. local min, max = 2.2, 40 -- минимальная и максимальная плотность
  5. local port = 1 -- порт для взаимодействия с роботом
  6. local X, Y, Z, D, border = 0, 0, 0, 0 -- переменные локальной системы координат
  7. local steps, turns = 0, 0 -- debug
  8. local WORLD = {x = {}, y = {}, z = {}} -- таблица меток
  9. local E_C, W_R = 0, 0 -- энергозатраты на один шаг и скорость износа
  10.  
  11. local function arr2a_arr(tbl) -- преобразование списка в ассоциативный массив
  12.   for i = #tbl, 1, -1 do
  13.    tbl[tbl[i]], tbl[i] = true, nil
  14.   end
  15. end
  16.  
  17. local quads = {{-7, -7}, {-7, 1}, {1, -7}, {1, 1}}
  18. local workbench = {1,2,3,5,6,7,9,10,11}
  19. local wlist = {'enderstorage:ender_storage'}
  20. local fragments = {'redstone','coal','dye','diamond','emerald'}
  21. local tails = {'cobblestone','dirt','gravel','sand','stained_hardened_clay','sandstone','stone','grass','end_stone','hardened_clay','mossy_cobblestone','planks','fence','torch','nether_brick','nether_brick_fence','nether_brick_stairs','netherrack','soul_sand'}
  22. arr2a_arr(wlist)
  23. arr2a_arr(fragments)
  24. arr2a_arr(tails)
  25.  
  26. local function add_component(name) -- получение прокси компонента
  27.   name = component.list(name)() -- получить адрес по имени
  28.   if name then -- если есть адрес
  29.     return component.proxy(name) -- вернуть прокси
  30.   end
  31. end
  32.  
  33. -- загрузка компонентов --
  34. local controller = add_component('inventory_controller')
  35. local chunkloader = add_component('chunkloader')
  36. local generator = add_component('generator')
  37. local crafting = add_component('crafting')
  38. local geolyzer = add_component('geolyzer')
  39. local tunnel = add_component('tunnel')
  40. local modem = add_component('modem')
  41. local robot = add_component('robot')
  42. local inventory = robot.inventorySize()
  43. local report, remove_point, check, step, turn, smart_turn, go, scan, calibration, sorter, home, main
  44.  
  45. report = function(message, stop) -- рапорт о состоянии
  46.   message = '|'..X..' '..Y..' '..Z..'|\n'..message -- добавить к сообщению координаты
  47.   if modem then -- если есть модем
  48.     modem.broadcast(port, message) -- послать сообщение через модем
  49.   elseif tunnel then -- если есть связанная карта
  50.     tunnel.send(message) -- послать сообщение через нее
  51.   end
  52.   print(message)
  53.   computer.beep('...........') -- пикнуть
  54.   if stop then -- если есть флаг завершения
  55.     if chunkloader then
  56.       chunkloader.setActive(false)
  57.     end
  58.     os.exit()--error(nil,0) -- остановить работу программы
  59.   end
  60. end
  61.  
  62. remove_point = function(point) -- удаление меток
  63.   table.remove(WORLD.x, point) -- удалить метку из таблицы
  64.   table.remove(WORLD.y, point)
  65.   table.remove(WORLD.z, point)
  66. end
  67.  
  68. check = function(forcibly) -- проверка инструмента, батареи, удаление меток
  69.   if steps%32 == 0 or forcibly then -- если пройдено 32 шага или включен принудительный режим
  70.     local delta = math.abs(X)+math.abs(Y)+math.abs(Z)+64 -- определить расстояние
  71.     local cx, cy, cz = X, Y, Z -- сохранить текущие координаты
  72.     if robot.durability()/W_R < delta then -- если инструмент изношен
  73.       report('tool is worn')
  74.       home(true) -- отправиться домой
  75.     end
  76.     if delta*E_C > computer.energy() then -- проверка уровня энергии
  77.       report('battery is low')
  78.       home(true) -- отправиться домой
  79.     end
  80.     go(cx, cy, cz) -- вернуться на место
  81.     if computer.energy()/computer.maxEnergy() < 0.5 then -- если энергии меньше 50%
  82.       if generator and generator.count() == 0 and not forcibly then -- если есть генератор
  83.         for slot = 1, inventory do -- обойти инвентарь
  84.           robot.select(slot) -- выбрать слот
  85.           generator.insert() -- попробовать заправиться
  86.         end
  87.       --[[elseif solar and geolyzer.isSunVisible() then -- проверить видимость солнца
  88.         while not geolyzer.canSeeSky() do -- пока не видно неба
  89.           step(1) -- сделать шаг вверх
  90.         end
  91.         os.sleep(60)]]
  92.       end
  93.     end
  94.   end
  95.   if #WORLD.x ~= 0 then -- если таблица меток не пуста
  96.     for i = 1, #WORLD.x do -- пройти по всем позициям
  97.       if WORLD.y[i] == Y and ((WORLD.x[i] == X and ((WORLD.z[i] == Z+1 and D == 0) or (WORLD.z[i] == Z-1 and D == 2))) or (WORLD.z[i] == Z and ((WORLD.x[i] == X+1 and D == 3) or (WORLD.x[i] == X-1 and D == 1)))) then
  98.         robot.swing(3)
  99.         remove_point(i)
  100.       end
  101.       if X == WORLD.x[i] and (Y-1 <= WORLD.y[i] and Y+1 >= WORLD.y[i]) and Z == WORLD.z[i] then
  102.         if WORLD.y[i] == Y+1 then -- добыть блок сверху, если есть
  103.           robot.swing(1)
  104.         elseif WORLD.y[i] == Y-1 then -- добыть блок снизу
  105.           robot.swing(0)
  106.         end
  107.         remove_point(i)
  108.       end
  109.     end
  110.   end
  111. end
  112.  
  113. step = function(side) -- функция движения на 1 блок
  114.   if not robot.swing(side) and robot.detect(side) then -- если блок нельзя разрушить
  115.     home(true) -- запустить завершающую функцию
  116.     report('insurmountable obstacle', true) -- послать сообщение
  117.   else
  118.     while robot.swing(side) do end -- копать пока возможно
  119.   end
  120.   if robot.move(side) then -- если робот сдвинулся, обновить координаты
  121.     steps = steps + 1 -- debug
  122.     if side == 0 then
  123.       Y = Y-1
  124.     elseif side == 1 then
  125.       Y = Y+1
  126.     elseif side == 3 then
  127.       if D == 0 then
  128.         Z = Z+1
  129.       elseif D == 1 then
  130.         X = X-1
  131.       elseif D == 2 then
  132.         Z = Z-1
  133.       else
  134.         X = X+1
  135.       end
  136.     end
  137.   end
  138.   check()
  139. end
  140.  
  141. turn = function(side) -- поворот в сторону
  142.   side = side or false
  143.   if robot.turn(side) and D then -- если робот повернулся, обновить переменную  направления
  144.     turns = turns+1 -- debug
  145.     if side then
  146.       D = (D+1)%4
  147.     else
  148.       D = (D-1)%4
  149.     end
  150.     check()
  151.   end
  152. end
  153.  
  154. smart_turn = function(side) -- поворот в определенную сторону света
  155.   while D ~= side do
  156.     turn((side-D)%4==1)
  157.   end
  158. end
  159.  
  160. go = function(x, y, z) -- переход по указанным координатам
  161.   if border and y < border then
  162.     y = border
  163.   end
  164.   while Y ~= y do
  165.     if Y < y then
  166.       step(1)
  167.     elseif Y > y then
  168.       step(0)
  169.     end
  170.   end
  171.   if X < x then
  172.     smart_turn(3)
  173.   elseif X > x then
  174.     smart_turn(1)
  175.   end
  176.   while X ~= x do
  177.     step(3)
  178.   end
  179.   if Z < z then
  180.     smart_turn(0)
  181.   elseif Z > z then
  182.     smart_turn(2)
  183.   end
  184.   while Z ~= z do
  185.     step(3)
  186.   end
  187. end
  188.  
  189. scan = function(xx, zz) -- сканирование квадрата x8 относительно робота
  190.   local raw, index = geolyzer.scan(xx, zz, -1, 8, 8, 1), 1 -- получить сырые данные, установить индекс в начало таблицы
  191.   for z = zz, zz+7 do -- развертка данных по z
  192.     for x = xx, xx+7 do -- развертка данных по х
  193.       if raw[index] >= min and raw[index] <= max then -- если обнаружен блок с подходящей плотностью
  194.         table.insert(WORLD.x, X+x) --| записать метку в список
  195.         table.insert(WORLD.y, Y-1) --| с коррекцией локальных
  196.         table.insert(WORLD.z, Z+z) --| координат геосканера
  197.       elseif raw[index] < -0.31 then -- если обнаружен блок с отрицательной плотностью
  198.         border = Y -- сделать отметку
  199.       end
  200.       index = index + 1 -- переход к следующему индексу сырых даннх
  201.     end
  202.   end
  203. end
  204.  
  205. calibration = function() -- калибровка при запуске
  206.   if not controller then -- проверить наличие контроллера инвентаря
  207.     report('inventory controller not detected', true)
  208.   elseif not geolyzer then -- проверить наличие геосканера
  209.     report('geolyzer not detected', true)
  210.   elseif not robot.detect(0) then
  211.     report('bottom solid block is not detected', true)
  212.   elseif not robot.durability() then
  213.     report('there is no suitable tool in the manipulator', true)
  214.   end
  215.   if chunkloader then -- если есть чанклоадер
  216.     chunkloader.setActive(true) -- включить
  217.   end
  218.   if modem then -- если есть модем
  219.     --modem.open(port)
  220.     modem.setWakeMessage('') -- установить сообщение пробуждения
  221.     modem.setStrength(400) -- установить силу сигнала
  222.   elseif tunnel then -- если есть туннель
  223.     tunnel.setWakeMessage('') -- установить сообщение пробуждения
  224.   end
  225.   for slot = 1, inventory do -- пройти по слотам инвентаря
  226.     if robot.count(slot) == 0 then -- если слот пуст
  227.       robot.select(slot) -- выбрать слот
  228.       break
  229.     end
  230.   end
  231.   local energy = computer.energy() -- получить уровень энергии
  232.   step(0) -- сделать шаг
  233.   E_C = math.ceil(energy-computer.energy()) -- записать уровень потребления
  234.   energy = robot.durability() -- получить уровень износа/разряда инструмента
  235.   while energy == robot.durability() do -- пока не обнаружена разница
  236.     robot.place(3) -- установить блок
  237.     robot.swing(3) -- разрушить блок
  238.   end
  239.   W_R = energy-robot.durability() -- записать результат
  240.   local sides = {2, 1, 3, 0} -- линки сторон света, для сырых данных
  241.   D = nil -- обнуление направления
  242.   for s = 1, #sides do -- проверка всех направлений
  243.     if robot.detect(3) or robot.place(3) then -- проверить наличие блока перед носом
  244.       local A = geolyzer.scan(-1, -1, 0, 3, 3, 1) -- сделать первый скан
  245.       robot.swing(3) -- сломать блок
  246.       local B = geolyzer.scan(-1, -1, 0, 3, 3, 1) -- сделать второй скан
  247.       for n = 2, 8, 2 do -- обойти смежные блоки в таблице
  248.         if math.ceil(B[n])-math.ceil(A[n])<0 then -- если блок исчез
  249.           D = sides[n/2] -- установить новое направление
  250.           break -- выйти из цикла
  251.         end
  252.       end
  253.     else
  254.       turn() -- задействовать простой поворот
  255.     end
  256.   end
  257.   if not D then
  258.     report('calibration error', true)
  259.   end
  260. end
  261.  
  262. sorter = function(pack) -- сортировка лута
  263.   robot.swing(0) -- освободить место для мусора
  264.   robot.swing(1) -- освободить место для буфера
  265.   ------- сброс мусора -------
  266.   local empty, available = 0, {} -- создать счетчик пустых слотов и доступных для упаковки
  267.   for slot = 1, inventory do -- пройти по слотам инвентаря
  268.     local item = controller.getStackInInternalSlot(slot) -- получить информацию о предмете
  269.     if item then -- если есть предмет
  270.       local name = item.name:gsub('%g+:', '')
  271.       if tails[name] then -- проверить на совпадение в списке отходов
  272.         robot.select(slot) -- выбрать слот
  273.         robot.drop(0) -- выбросить к отходам
  274.         empty = empty + 1 -- обновить счетчик
  275.       elseif fragments[name] then -- если есть совпадение в списке фрагментов
  276.         if available[name] then -- если уже создан счетчик
  277.           available[name] = available[name] + item.size -- обновить количество
  278.         else -- иначе
  279.           available[name] = item.size -- задать счетчик для имени
  280.         end
  281.       end
  282.     else -- обнаружен пустой слот
  283.       empty = empty + 1 -- обновить счетчик
  284.     end
  285.   end
  286.   -- упаковка предметов в блоки --
  287.   if crafting and (empty < 12 or pack) then -- если есть верстак и меньше 12 свободных слотов или задана принудительная упаковка
  288.     -- перенос лишних предметов в буфер --
  289.     if empty < 10 then -- если пустых слотов меньше 10
  290.       empty = 10-empty -- увеличить количество пустых слотов для обратного отсчета
  291.       for slot = 1, inventory do -- просканировать инвентарь
  292.         local item = controller.getStackInInternalSlot(slot)
  293.         if item then -- если слот не пуст
  294.           if not wlist[item.name] then -- проверка имени, чтобы не выкинуть важный предмет в лаву
  295.             local name = item.name:gsub('%g+:', '') -- отформатировать имя
  296.             if available[name] then -- если есть в счетчике
  297.               available[name] = available[name] - item.size -- обновить счетчик
  298.             end
  299.             robot.select(slot) -- выбрать слот
  300.             robot.drop(1) -- выбросить в буфер
  301.             empty = empty - 1 -- обновить счетчик
  302.           end
  303.         end
  304.         if empty == 0 then -- если место освободилось
  305.           break -- прервать цикл
  306.         end
  307.       end
  308.     end
  309.     ------- основной цикл крафта -------
  310.     for o, m in pairs(available) do
  311.       if m > 8 then
  312.         for l = 1, math.ceil(m/576) do
  313.           -- очистка рабочей зоны --
  314.           for i = 1, 9 do -- пройти по слотам верстака
  315.             if robot.count(workbench[i]) > 0 then -- если слот не пуст
  316.               robot.select(workbench[i]) -- выбрать слот
  317.               for slot = 4, inventory do -- перебор слотов инвентаря
  318.                 if slot == 4 or slot == 8 or slot > 11 then -- исключить слоты верстака
  319.                   robot.transferTo(slot) -- попробовать переместить предметы
  320.                   if robot.count(slot) == 0 then -- если слот освободился
  321.                     break -- прервать цикл
  322.                   end
  323.                 end
  324.               end
  325.               if robot.count() > 0 then -- если обнаружена перегрузка
  326.                 while robot.suck(1) do end -- забрать предметы из буфера
  327.                 return -- прекратить упаковку
  328.               end
  329.             end
  330.           end
  331.           for slot = 4, inventory do -- цикл поиска фрагментов
  332.             local item = controller.getStackInInternalSlot(slot) -- получить информацию о предмете
  333.             if item and (slot == 4 or slot == 8 or slot > 11) then -- если есть предмет вне рабочей зоны
  334.               if o == item.name:gsub('%g+:', '') then -- если предмет совпадает
  335.                 robot.select(slot) -- при совпадении выбрать слот
  336.                 for n = 1, 10 do -- цикл заполнения рабочей зоны
  337.                   robot.transferTo(workbench[n%9+1], item.size/9) -- разделить текущий стак на 9 частей и перенести в верстак
  338.                 end
  339.                 if robot.count(1) == 64 then -- сброс при заполнении верстака
  340.                   break
  341.                 end
  342.               end
  343.             end
  344.           end
  345.           robot.select(inventory) -- выбор последнего слота
  346.           crafting.craft() -- создание блока
  347.           -- цикл сортировки остатков
  348.           for A = 1, inventory do -- основной проход
  349.             local size = robot.count(A) -- получить количество предметов
  350.             if size > 0 and size < 64 then -- если слот не пуст и не полон
  351.               for B = A+1, inventory do -- проход сравнения
  352.                 if robot.compareTo(B) then -- если предметы одинаковые
  353.                   robot.select(A) -- выбрать слот
  354.                   robot.transferTo(B, 64-robot.count(B)) -- перенести до заполнения
  355.                 end
  356.                 if robot.count() == 0 then -- если слот освободился
  357.                   break -- прервать сравнение
  358.                 end
  359.               end
  360.             end
  361.           end
  362.         end
  363.       end
  364.     end
  365.   end
  366.   while robot.suck(1) do end --- забрать предметы из буфера
  367. end
  368.  
  369. home = function(forcibly) -- переход к начальной точке и сброс лута
  370.   report('ore unloading')
  371.   local enderchest -- обнулить слот с эндерсундуком
  372.   for slot = 1, inventory do -- просканировать инвентарь
  373.     local item = controller.getStackInInternalSlot(slot) -- получить информацию о слоте
  374.     if item then -- если есть предмет
  375.       if item.name == 'enderstorage:ender_storage' then -- если есть эндерсундук
  376.         enderchest = slot -- задать слот
  377.         break -- прервать поиск
  378.       end
  379.     end
  380.   end
  381.   if enderchest and not forcibly then -- если есть сундук и нет принудительного возвращения домой
  382.     step(1) -- подняться на 1 блок
  383.     robot.swing(3) -- освободить место для сундука
  384.     robot.select(enderchest) -- выбрать сундук
  385.     robot.place(3) -- поставить сундук
  386.   else
  387.     go(0, -2, 0)
  388.     go(0, 0, 0)
  389.   end
  390.   sorter() -- сортировка инвентаря
  391.   local size = nil -- обнулить размер контейнера
  392.   while true do -- войти в бесконечный цикл
  393.     for side = 1, 4 do -- поиск контейнера
  394.       size = controller.getInventorySize(3) -- получение размера инвентаря
  395.       if size and size>26 then -- если контейнер найден
  396.         break -- прервать поиск
  397.       end
  398.       turn() -- повернуться
  399.     end
  400.     if not size or size<26 then -- если контейнер не найден
  401.       report('container not found') -- послать сообщение
  402.       os.sleep(30)
  403.     else
  404.       break -- продолжить работу
  405.     end
  406.   end
  407.   for slot = 1, inventory do -- обойти весь инвентарь
  408.     local item = controller.getStackInInternalSlot(slot)
  409.     if item then -- если слот не пуст
  410.       if not wlist[item.name] then -- если предмет не в белом списке
  411.         robot.select(slot) -- выбрать слот
  412.         local a, b = robot.drop(3) -- сбросить в контейнер
  413.         if not a and b == 'inventory full' then -- если контейнер заполнен
  414.           while not robot.drop(3) do -- ждать, пока не освободится
  415.             report(b) -- послать сообщение
  416.             os.sleep(30) -- подождать
  417.           end
  418.         end
  419.       end
  420.     end
  421.   end
  422.   if crafting then -- если есть верстак, забрать предметы из сундука и упаковать
  423.     for slot = 1, size do -- обход слотов контейнера
  424.       local item = controller.getStackInSlot(3, slot) -- получить информацию о пердмете
  425.       if item then -- если есть предмет
  426.         if fragments[item.name:gsub('%g+:', '')] then -- если есть совпадение
  427.           controller.suckFromSlot(3, slot) -- забрать предметы
  428.         end
  429.       end
  430.     end
  431.     sorter(true) -- упаковать
  432.     for slot = 1, inventory do -- обойти весь инвентарь
  433.       local item = controller.getStackInInternalSlot(slot)
  434.       if item then -- если слот не пуст
  435.         if not wlist[item.name] then -- если предмет не в белом списке
  436.           robot.select(slot) -- выбрать слот
  437.           robot.drop(3) -- сбрость в контейнер
  438.         end
  439.       end
  440.     end
  441.   end
  442.   if generator and not forcibly then -- если есть генератор
  443.     for slot = 1, size do -- просканировать контейнер
  444.       local item = controller.getStackInSlot(3, slot) -- получить информацию о пердмете
  445.       if item then -- если есть предмет
  446.         if item.name:sub(11, 15) == 'coal' then -- если в слоте уголь
  447.           controller.suckFromSlot(3, slot) -- взять
  448.           break -- выйти из цикла
  449.         end
  450.       end
  451.     end
  452.   end
  453.   if forcibly then
  454.     report('tool search in container')
  455.     if robot.durability() < 0.3 then -- если прочность инструмента меньше 30%
  456.       local container = controller.getAllStacks(3) -- получить информацию о всех предметах
  457.       if container then -- если контейнер никуда не ушел
  458.         robot.select(1) -- выбрать первый слот
  459.         controller.equip() -- поместить инструмент в инвентарь
  460.         local tool = controller.getStackInInternalSlot(1) -- получить данные инструмента
  461.         local size = container.count() -- получить размер инвентаря
  462.         local item = container.getAll() -- получить информацию о всех предметах
  463.         for slot = 1, size do -- просканировать массив
  464.           if item[slot].name == tool.name and item[slot].damage < tool.damage then
  465.             robot.drop(3) -- выбросить старый инструмент
  466.             controller.suckFromSlot(3, slot) -- взять новый
  467.           end
  468.         end
  469.         controller.equip() -- экипировать
  470.       end    
  471.     end
  472.     report('attempt to repair tool')
  473.     if robot.durability() < 0.3 then -- если инструмент не заменился на лучший
  474.       for side = 1, 3 do -- перебрать все стороны
  475.         local name = controller.getInventoryName(3) -- получить имя инвенторя
  476.         if name == 'opencomputers:charger' then -- сравнить имя
  477.           robot.select(1) -- выбрать слот
  478.           controller.equip() -- достать инструмент
  479.           if robot.drop(3) then -- если получилось засунуть инструмент в зарядник
  480.             local damage = controller.getStackInInternalSlot(1).damage
  481.             while true do
  482.               os.sleep(30)
  483.               robot.suck(3)
  484.               local n_damage = controller.getStackInInternalSlot(1).damage
  485.               if damage > n_damage and n_damage ~= 0 then -- если инструмент починился
  486.                 controller.equip() -- экипировать
  487.                 break -- остановить зарядку
  488.               elseif damage == n_damage then -- если инструмент не чинится
  489.                 report('tool could not be repaired', true) -- остановить работу
  490.               end
  491.             end
  492.           else
  493.             report('tool could not be repaired', true) -- остановить работу
  494.           end
  495.         else
  496.           turn() -- повернуться
  497.         end
  498.       end
  499.     end
  500.   end
  501.   if enderchest and not forcibly then
  502.     robot.swing(3) -- забрать сундук
  503.   else
  504.     while computer.energy()/computer.maxEnergy() < 0.98 do -- ждать полного заряда батареи
  505.       report('charging: '..math.floor((computer.energy()/computer.maxEnergy())*100)..'%')
  506.       os.sleep(30)
  507.     end
  508.   end
  509.   report('return to work')
  510. end
  511.  
  512. main = function()
  513.   border = nil
  514.   while not border do
  515.     step(0)
  516.     for q = 1, 4 do
  517.       scan(table.unpack(quads[q]))
  518.     end
  519.     check(true)
  520.   end
  521.   while #WORLD.x ~= 0 do
  522.     local n_delta, c_delta, current = math.huge, math.huge
  523.     for index = 1, #WORLD.x do
  524.       n_delta = math.abs(X-WORLD.x[index])+math.abs(Y-WORLD.y[index])+math.abs(Z-WORLD.z[index])-border+WORLD.y[index]
  525.       if (WORLD.x[index] > X and D ~= 3) or
  526.       (WORLD.x[index] < X and D ~= 1) or
  527.       (WORLD.z[index] > Z and D ~= 0) or
  528.       (WORLD.z[index] < Z and D ~= 2) then
  529.         n_delta = n_delta + 1
  530.       end
  531.       if n_delta < c_delta then
  532.         c_delta, current = n_delta, index
  533.       end
  534.     end
  535.     if WORLD.x[current] == X and WORLD.y[current] == Y and WORLD.z[current] == Z then
  536.       remove_point(current)
  537.     else
  538.       local yc = WORLD.y[current]
  539.       if yc-1 > Y then
  540.         yc = yc-1
  541.       elseif yc+1 < Y then
  542.         yc = yc+1
  543.       end
  544.       go(WORLD.x[current], yc, WORLD.z[current])
  545.     end
  546.   end
  547.   sorter()
  548. end
  549.  
  550. calibration() -- запустить калибровку
  551. calibration = nil -- освободить память от функции калибровки
  552. local Tau = computer.uptime() -- записать текущее время
  553. local pos = {0, 0, 0, [0] = 1} -- таблица для хранения координат чанков
  554. for o = 1, 10 do -- цикл ограничения спирали
  555.   for i = 1, 2 do -- цикл обновления координат
  556.     for a = 1, o do -- цикл перехода по линии спирали
  557.       main() -- запуск функции сканирования и добычи
  558.       report('chunk #'..pos[3]+1 ..' processed') -- сообщить о завершении работы в чанке
  559.       pos[i], pos[3] = pos[i] + pos[0], pos[3] + 1 -- обновить координаты
  560.       if pos[3] == chunks then -- если достигнут последний чанк
  561.         home(true) -- возврат домой
  562.         report(computer.uptime()-Tau..' seconds\npath length: '..steps..'\nmade turns: '..turns, true) -- сообщить о завершении работы
  563.       else -- иначе
  564.         go(pos[1]*16, -2, pos[2]*16) -- перейти к следующему чанку
  565.         go(X, 0, Z) -- перейти в стартовую точку сканирования
  566.       end
  567.     end
  568.   end
  569.   pos[0] = 0-pos[0] -- обновить направление спирали
  570. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement