Лидеры
Популярный контент
Показан контент с высокой репутацией 21.02.2019 в Записи блога
-
1 баллДля настройки работы программы, надо узнать плотность добываемых блоков и плотность мусора, чтобы сделать предварительный фильтр на этапе сканирования. Плотность одной руды в разных модах отличается, но она близка к ванильной т. к. механика работы инструментов одна. Сделал шпаргалку с информацией о плотностях из разных модов. Плотность, уровень инструмента, название. Minecraft 3 2 Алмазная руда 3 2 Изумрудная руда 3 2 Золотая руда 3 2 Красная руда 3 1 Железная руда 3 1 Лазуритовая руда 3 0 Угольная руда 3 0 Кварцевая руда 0.3 -1 Светокамень -1 -1 Бедрок 50 3 Обсидиан 3 -1 Эндерняк 2.5 0 Сундук 2 0 Булыжник 2 -1 Адский кирпич 2 0 Доски 1.5 0 Камень 1.5 -1 Каменный кирпич 1.25 -1 Терракота 0.8 0 Песчаник 0.6 0 Трава 0.6 0 Гравий 0.6 0 Глина 0.5 0 Земля 0.5 0 Песок 0.4 0 Адский камень 0.5 0 Песок душ -------------------------------------------- IC2 4 2 Урановая руда 3 1 Медная руда 3 1 Оловянная руда 2 1 Свинцовая руда -------------------------------------------- AE2 50 3 Небесный камень 50 0 Сундук из небесного камня 3 0 Кварцевая руда -------------------------------------------- Mekanism 3 -1 Осмиевая руда 3 -1 Медная руда 3 -1 Оловянная руда -------------------------------------------- Forestry 3 1 Апатитовая руда 3 1 Медная руда 3 1 Оловянная руда -------------------------------------------- TConstruct 10 4 Кобальтовая руда 10 4 Ардитовая руда -------------------------------------------- ThermalFoundation 3 1 Медная руда 3 1 Оловянная руда 3 2 Серебряная руда 3 2 Свинцовая руда 3 1 Алюминиевая руда 3 2 Никелевая руда 3 3 Платиновая руда 3 3 Иридиевая руда 3 3 Мифриловая руда -------------------------------------------- Galacticraft 6 1 Алюминиевая руда 5 1 Оловянная руда 5 1 Медная руда 3 2 Кремниевая руда Moon 5 1 Медная руда 5 1 Оловянная руда 5 -1 Сапфировая руда 3 1 Сырная руда 1.5 0 Лунный камень 0.5 0 Лунный грунт 0.5 -1 Лунный дерн Mars 2.2 3 Деш руда 2.2 1 Железная руда 2.2 1 Оловянная руда 2.2 1 Медная руда 2.2 0 Булыжник 2.2 0 Реголит Asteroids 3 2 Алюминиевая руда 3 3 Ильменитовая руда 3 2 Железная руда 3 0 Камень Venus 5 -1 Алюминиевая руда 5 -1 Медная руда 5 -1 Свинцовая руда 5 -1 Кварцевая руда 5 -1 Кремниевая руда 5 -1 Оловянная руда 5 -1 Солнечная пыль 2.2 1 Магма 2.2 1 Пемза 1.5 1 Твердый камень 0.9 1 Мягкий камень 0.9 -1 Выжженный камень
-
1 баллДобытые ресурсы надобно рассортировать. Для этого дела задействуем контроллер инвентаря. Надобно пройти по всем слотам, получить информацию о содержимом и сравнить название со списком ненужных предметов (который предварительно составим), при совпадении опустошать. Но это не вся функция. У нас есть еще верстак, который может помочь, очень сильно ужать, некоторые ресурсы (уголь, редстоун, алмазы, изумруды, лазурит). Верстак занимает в инвентаре 9 слотов, еще 1 слот добавим на результат, если не все влезет в блок. Поэтому, пока робот ищет мусор, пусть считает пустые слоты, для верстака. В начале уберем блоки сверху и снизу, чтобы случайно не перемешать мусор с излишками добра. для удобоваримости сократил некоторые имена: inventory - размер инвентаря, получим в начале работы программы, controller - контроллер инвентаря, tails - список названий лишних предметов (без префикса "minecraft:", можно добавлять названия из любого мода) robot.swing(0) -- освободить место для мусора robot.swing(1) -- освободить место для буфера ------- сброс мусора ------- local empty = 0 -- создать счетчик пустых слотов for slot = 1, inventory do -- пройти по слотам инвентаря local item = controller.getStackInInternalSlot(slot) -- получить информацию о предмете if item then -- если есть предмет for name = 1, #tails do -- пройти по таблице хвостов if item.name:gsub('%g+:', '') == tails[name] then -- проверить на совпадение robot.select(slot) -- выбрать слот robot.drop(0) -- выбросить к отходам empty = empty + 1 -- обновить счетчик break -- прервать цикл сравнения end end else empty = empty + 1 -- обновить счетчик end end Далее следует проверить и выкинуть наверх предметы, которые будут мешать при крафте. Подсчитанные пустые слоты отнимем от требуемого количества для крафта, пройдем по инвентарю уберем их. -- упаковка предметов в блоки -- if crafting then -- если есть верстак -- перенос лишних предметов в буфер -- if empty < 10 then -- если пустых слотов меньше 10 empty = 10-empty -- увеличить количество пустых слотов для обратного отсчета for slot = 1, inventory do -- просканировать инвентарь if robot.count(slot) > 0 then -- если слот не пуст robot.select(slot) -- выбрать слот robot.drop(1) -- выбросить в буфер empty = empty - 1 -- обновить счетчик end if empty == 0 then -- если место освободилось break -- прервать цикл end end end Предварительно создадим таблицу fragments, в которой будут храниться названия предметов, которые можно сложить в блоки. Теперь создадим таблицу, в которой будут счетчики для каждого типа фрагментов. Пройдем по инвентарю, получим информацию о слоте, сравним, прибавим - все как в первом цикле, можно было бы даже их объединить, но на предыдущем шаге мы выкинули какие-то предметы. Чтобы узнать какие именно - придется городить еще один цикл, оставим как есть. -- подсчет предметов доступных для упаковки -- local available = {} -- создать таблицу счетчиков for slot = 1, inventory do -- пройти по слотам инвентаря local item = controller.getStackInInternalSlot(slot) -- получить информацию о предмете if item then -- если есть предмет for n = 1, #fragments do -- пройти по списку названий фрагментов if item.name:gsub('%g+:', '') == fragments[n] then -- сравнить по имени if available[n] then -- если есть подобные фрагменты available[n] = available[n] + item.size -- обновить else -- иначе available[n] = item.size -- создать end break end end end end Наконец-то можно крафтить. Хотя, нет. Надо расчистить слоты верстака, чтобы в него сложить рецепт. Будем перебирать слоты от 1 до 9, но в роботе верстак занимает слоты с другими номерами, а именно 1 2 3 5 6 7 9 10 11, можно было бы составить условие от 1 до 11, с исключением целых по модулю 4. Сделаем проще - номера слотов занесем в таблицу "workbench", которая будет служить списком ссылок с системы 1-9 на 1-11. Вынесем ее подальше, чтобы она не создавалась при каждом запуске. В цикле проверяем количество предметов в слоте, если оно не нулевое - ищем в инвентаре пустой слот, исключая слоты верстака. Переносим предметы в найденный слот. Если перенести не удалось - что-то попало в верстак после крафта. Забираем предметы из буфера и завершаем функцию, возвращая true, что будет сообщать о перегрузе и времени выдвигаться домой. for c_slot = 1, 9 do -- цикл чистки зоны верстака if robot.count(workbench[c_slot]) > 0 then -- если слот не пуст robot.select(workbench[c_slot]) -- выбрать слот верстака for slot = 4, inventory do -- обойти весь инвентарь, кроме рабочей зоны if robot.count(slot) == 0 and (slot == 4 or slot == 8 or slot > 11) then -- если есть свободный robot.transferTo(slot) -- освободить слот break -- выйти из цикла end end if robot.count() > 0 then -- проверить на перегрузку robot.suck(1) -- забрать из буфера return true -- остановить упаковку end end end Верстак расчищен, пора заняться упаковкой. Перебираем слоты инвентаря, исключая верстак, сравниваем названия со списком. При совпадении, делим содержимое на 9, заполняем верстак И крафтим блок. ------- основной цикл крафта ------- for slot = 4, inventory do -- цикл поиска фрагментов local item = controller.getStackInInternalSlot(slot) -- получить информацию о предмете if item and (slot == 4 or slot == 8 or slot > 11) then -- если есть предмет вне рабочей зоны if item.name:gsub('%g+:', '') == fragments[i] then -- сравнить по названию фрагмента robot.select(slot) -- при совпадении выбрать слот for n = 1, 9 do -- цикл заполнения рабочей зоны robot.transferTo(workbench[n], item.size/9) -- разделить текущий стак на 9 частей и перенести в верстак end if robot.count(1) == 64 then -- сброс при заполнении верстака break end end end end crafting.craft() -- создание блока Можно заметить fragments, откуда i? Об этом позже. После крафта могли остаться какие-то остатки, если не все слоты поделились на 9. Проверяем содержимое в слотах, если предметов меньше 64 - перебираем слоты после текущего и сравниваем, при совпадении содержимого пробуем перенести. При опустошении текущего слота - прерываем перебор со сравнением. -- цикл сортировки остатков for A = 1, inventory do -- основной проход local size = robot.count(A) -- получить количество предметов if size > 0 and size < 64 then -- если слот не пуст и не полон robot.select(A) -- выбрать слот for B = A+1, inventory do -- проход сравнения if robot.compareTo(B) then -- если предметы одинаковые robot.transferTo(B, 64-robot.count(B)) -- перенести до заполнения end if robot.count() == 0 then -- если слот освободился break -- прервать сравнение end end end end Последние три цикла заворачиваем в такую конструкцию: for i = 1, #fragments do -- перебор всех названий if available[i] then -- если в инвентаре такой есть for j = 1, math.ceil(available[i]/576) do -- разделить результат на стаки ... end end end Первый цикл перебирает названия фрагментов. Условный оператор проверяет наличие такого типа в инвентаре. Внутренний цикл повторяет чистку, крафт и сортировку, если в результате будет больше стака блоков. Новые используемые переменные: 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'} local workbench = {1,2,3,5,6,7,9,10,11} local fragments = {'redstone','coal','dye','diamond','emerald'} local controller = add_component('inventory_controller') local crafting = add_component('crafting') local inventory = robot.inventorySize() Полный текст функции, с более рациональным вызовом robot.count(): local function sorter() -- сортировка лута robot.swing(0) -- освободить место для мусора robot.swing(1) -- освободить место для буфера ------- сброс мусора ------- local empty = 0 -- создать счетчик пустых слотов for slot = 1, inventory do -- пройти по слотам инвентаря local item = controller.getStackInInternalSlot(slot) -- получить информацию о предмете if item then -- если есть предмет for name = 1, #tails do -- пройти по таблице хвостов if item.name:gsub('%g+:', '') == tails[name] then -- проверить на совпадение robot.select(slot) -- выбрать слот robot.drop(0) -- выбросить к отходам empty = empty + 1 -- обновить счетчик break -- прервать цикл сравнения end end else empty = empty + 1 -- обновить счетчик end end -- упаковка предметов в блоки -- if crafting and empty < 12 then -- если есть верстак и переполнение -- перенос лишних предметов в буфер -- if empty < 10 then -- если пустых слотов меньше 10 empty = 10-empty -- увеличить количество пустых слотов для обратного отсчета for slot = 1, inventory do -- просканировать инвентарь if robot.count(slot) > 0 then -- если слот не пуст robot.select(slot) -- выбрать слот robot.drop(1) -- выбросить в буфер empty = empty - 1 -- обновить счетчик end if empty == 0 then -- если место освободилось break -- прервать цикл end end end -- подсчет предметов доступных для упаковки -- local available = {} -- создать таблицу счетчиков for slot = 1, inventory do -- пройти по слотам инвентаря local item = controller.getStackInInternalSlot(slot) -- получить информацию о предмете if item then -- если есть предмет for n = 1, #fragments do -- пройти по списку названий фрагментов if item.name:gsub('%g+:', '') == fragments[n] then -- сравнить по имени if available[n] then -- если есть подобные фрагменты available[n] = available[n] + item.size -- обновить else -- иначе available[n] = item.size -- создать end break end end end end ------- основной цикл крафта ------- for i = 1, #fragments do -- перебор всех названий if available[i] then -- если в инвентаре такой есть for j = 1, math.ceil(available[i]/576) do -- разделить результат на стаки for c_slot = 1, 9 do -- цикл чистки зоны верстака if robot.count(workbench[c_slot]) > 0 then -- если слот не пуст for slot = 4, inventory do -- обойти весь инвентарь, кроме рабочей зоны if robot.count(slot) == 0 and (slot == 4 or slot == 8 or slot > 11) then -- если есть свободный robot.select(workbench[c_slot]) -- выбрать слот верстака robot.transferTo(slot) -- освободить слот break -- выйти из цикла end end if robot.count() > 0 then -- проверить на перегрузку robot.suck(1) -- забрать из буфера return true -- остановить упаковку end end end ------- основной цикл крафта ------- for slot = 4, inventory do -- цикл поиска фрагментов local item = controller.getStackInInternalSlot(slot) -- получить информацию о предмете if item and (slot == 4 or slot == 8 or slot > 11) then -- если есть предмет вне рабочей зоны if item.name:gsub('%g+:', '') == fragments[i] then -- сравнить по названию фрагмента robot.select(slot) -- при совпадении выбрать слот for n = 1, 9 do -- цикл заполнения рабочей зоны robot.transferTo(workbench[n], item.size/9) -- разделить текущий стак на 9 частей и перенести в верстак end if robot.count(1) == 64 then -- сброс при заполнении верстака break end end end end crafting.craft() -- создание блока -- цикл сортировки остатков for A = 1, inventory do -- основной проход local size = robot.count(A) -- получить количество предметов if size > 0 and size < 64 then -- если слот не пуст и не полон for B = A+1, inventory do -- проход сравнения if robot.compareTo(B) then -- если предметы одинаковые robot.select(A) -- выбрать слот robot.transferTo(B, 64-robot.count(B)) -- перенести до заполнения end if robot.count() == 0 then -- если слот освободился break -- прервать сравнение end end end end end end end end robot.suck(1) --- забрать предметы из буфера end
Эта таблица лидеров рассчитана в Москва/GMT+03:00
