Перейти к содержимому
KleptoMMT5

Подпрограмма объединения предметов в хранилище робота

Рекомендуемые сообщения

Есть задача - сделать для строительного робота сортировку предметов в хранилище.

Данная подпрограмма только объединяет предметы в пачки и укладывает пачки друг за другом.

 

Мне нужно чтобы пачки шли паровозиком - друг за другом, и имели один и тот же тип материала: сначала ряд пачек одного материала, потом ряд пачек другого материала. Кроме того, начало и конец этих рядов должен быть записан в константы, для последующего вызова. Есть идея как это сделать.

 

Но было бы интересно узнать как это сделать для бесконечного количества типов материалов, а не для 1-6 типов; без использования констант.

 

Если вы знаете как сделать сортировку и маркировку для бесконечного количества типов материалов при помощи массивов или еще как-то, без определения локальных переменных вручную, то буду рад увидеть ваше решение.

 

А пока что есть подпрограмма, выполняющая предварительные действия перед началом строительства:

http://pastebin.com/cq60v1tB

  • программа объединяет материал, разбросанный по хранилищу робота, в полновесные пачки (64 шт. в пачке максимум);
  • и упорядочивает местоположение пачек так, чтобы они шли друг за другом, начиная с первой ячейки хранилища робота;
  • нет сортировки по типу материалов - пачки материалов идут вразнобой, случайным образом;
  • программа является частью другой программы, необходимой строительному роботу для начала бесперебойного строительства;
  • комментарии в программе предназначены для новичков и не программистов (типа меня); они помогают понять происходящее;
  • по этой же причине не убран неиспользуемый код из программы.

Понятия не имею как работать с массивами. Понятных, рабочих примеров их использования не нашел и не понял суть их работы и применения.

 

 

Используемые термины:

Ячейка == slot
Хранилище == inventory
Пачка == stack

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Все довольно просто, мне неоднократно приходилось решать подобную задачу.

Для умной сортировки надо использовать апгрейд-контроллер инвентаря.

 

Допустим, в инвентаре лежит неизвестное количество типов предметов, которые надо отсортировать.

Создаем пустую таблицу для названий предметов.

Сканируем инвентарь и заносим новые предметы в таблицу:

Берем название предмета из таблицы, раскладываем стаки этого предмета последовательно и переходим к следующему названию в таблице.

 

Но если робот имеет контроллер инвентаря, то так заморачиваться не надо, достаточно просто найти с его помощью нужный предмет по названию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Интересная возможность, Doob!
Не знал что есть такая функция с подтягиванием в таблицы.
И спасибо за свой вариант отбора материалов при помощи таблиц!

Единственное, что - не достаточно разложить пачки в таблице последовательно, необходимо еще отслеживать текущее число каждого типа материала.
Хорошим вариантом будет сделать две таблицы: одна для упорядочивания по типам, другая для управления направлением работой робота.
Возможно функцию обращения во внутрь робота удастся применить, если найду как создавать и работать с таблицами.

Я тут подумал... Оказывается, моя программа может работать на более дешевом роботе, без проблем )
можно поставить еще одно улучшение на 16 ячеек и спокойно выравнивать поверхность, строить дороги.

Но с таблицами по-интереснее будет. Т.к. полновесные пачки по 64 шт. можно запихать в робота вручную, без использования данной программы, а с программой - важно уметь распорядиться результатами её работы, иметь применение и не просто так держать улучшение в разъеме робота.
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если задача сводится к поиску нужного предмета, то это реализуется одной функцией:

local function findItem(name)
  for slot = 1, robot.inventorySize() do -- пройтись по всем слотам
    item = inventory_controller.getStackInInternalSlot(slot) -- получить информацию о предмете
    if item and item.name = name then -- если предмет найден
      return slot -- вернуть слот
    end
  end
end
она принимает системное имя предмета и выдает слот, в котором он находится.

 

Поэтому, с контроллером не приходится все раскладывать строго по порядку.

Конечно, если надо подсчитать количество предметов, то придется их занести в таблицу и при каждом использовании отнимать записанное значение или заново пересчитывать все предметы.

tbl = {} -- создать таблицу
for slot = 1, robot.inventorySize() do -- пройтись по всем слотам
  item = inventory_controller.getStackInInternalSlot(slot)
  if item then
    if tbl[item.name] then -- если есть предмет в таблице
      tbl[item.name] = tbl[item.name]+item.size -- добавить количество в текущем слоте
    else
      tbl[item.name] = item.size -- создать новый элемент со значением
    end
  end
end
Информация по API мода есть на вики

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Doob, в обеих программах выявлены ошибки:

 

1. синтаксические - нужно писать "component.inventory_controller.getStackInInternalSlot(slot)", добавляя "component."

2. смысловые - в 99% случаев новичку не понятен смысл существования второй программы; для новичков необходимо писать результаты работы программы в самой программе, чтобы начать уже разбираться с идеей, а не с механикой неизвестной и непонятной программы.

Я исправил обе явные ошибки и вторая программа выглядит теперь вот так:
 

local component = require("component")
local robot = require("robot")
local term = require("term")

tbl = {} -- создать таблицу
for slot = 1, robot.inventorySize() do -- пройтись по всем слотам
    item = component.inventory_controller.getStackInInternalSlot(slot)
    if item then
        if tbl[item.label] then -- если есть предмет в таблице
            tbl[item.label] = tbl[item.label]+item.size -- добавить количество в текущем слоте
        else
            tbl[item.label] = item.size -- создать новый элемент со значением
        end
    end
end

for key,value in pairs(tbl) do -- распечатать содержимое таблицы tbl и увидеть результаты работы программы
       print("tbl["..key.."] = "..value)
end

Для наглядности результатов "item.name" был заменен на "item.label" - это не ошибка, это для наглядности.

 

Смысл идеи таков: перед стартом строительства на экран робота можно выдать список сверки имеющихся предметов, а реализована идея - великолепно!
Спасибо за хорошую идею!

Изменено пользователем KleptoMMT5

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

В связи с тем, что у робота благодаря улучшению "Контроллер инвентаря"  имеется возможность вытаскивать нужные блоки из любого места хранилища, я решил упростить подпрограмму объединения ячеек хранилища. Она может работать и без данного улучшения, но потом... это улучшение обязательно понадобится(когда робот начнет строить).

local component = require("component")
local robot = require("robot")
local term = require("term")

local vcegoyacheek = robot.inventorySize() -- определение сколько всего ячеек, присвоение постоянной этого значения; кэш значения, постоянная
-- задача подпрограммы: объединить ячейки хранилища для эффективного использования
robot.select(1)                                         -- встать на первую ячейку
for i=1, vcegoyacheek do                                -- идем по всем ячейкам
 if (robot.count(i) > 0) and (robot.space(i) ~= 0) then -- если ячейка имеет предметы (кол-во) и не полная
     robot.select(i)                                    -- встать на текущую ячейку
     for m = (i+1), vcegoyacheek do                     -- ищем совпадающие материалы по всему хранилищу
	if (robot.compareTo(m) == true) and (robot.space(i) ~= 0) then -- если материалы совпадают и найденная ячейка не полная, то её попытаться добавить в исходную
	   robot.select(m)                              -- встать на перебрасываемую ячейку
	   robot.transferTo(i,robot.space(i))           -- передать материалы в допустимом объеме в исходную ячейку из найденной
	   robot.select(i)		                -- встать на исходную ячейку, чтобы продолжить поиски внутри цикла "m"
	elseif robot.space(i) == 0 then                 -- если пачка полная, то перекидываем её поближе и выходим из цикла
	   for k = 1, i do	-- цикл ищет пустую ячейку между первой ячейкой хранилища и обрабатываемой в текущей момент по циклу (i). за пределами (i) - цикл (k) ничего не видит и там могут быть остатки.
		if robot.count(k) == 0 then             -- если пустая ячейка найдена
		    robot.transferTo(k)                 -- тупо перенос в пустую ячейку из текущей по (i). задачи переноса вполнены.
		    break                               -- немедленный выход из цикла (k), чтобы продолжить работу цикла (m)
		end
	   end -- цикл(k) необязателен, его можно удалить и все будет работать. Он просто, для красоты, переносит пачки в незанятые ячейки. Тратит некоторое время на свою работу.
	   break                                        -- немедленный выход из цикла (m)
        end
     end
 end
end

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...