Чтобы отобразить иконки файлов и папок, а затем использовать их как кнопки, нужно разработать удобную в управлении структуру данных.
При помощи filesystem API можно получить контент текущей директории, что с этим делать?
Для начала разметим экран. В верхней части, на всю ширину экрана будет что-то вроде статус-бара высотой в 4 строки, там будет состояние памяти, батареи, может быть адресная и поисковая строка. Иконки 10x5 символов, с именем снизу, будут распола
Чтобы было куда кликать, надо на экране разметить места для иконок, еще и иконки нарисовать.
Для иконок возьмем формат PPM, а конкретно, цветную бинарную версию P6. Формат ультра-примитивный, иконки можно будет без лишних заморочек рисовать в любом нормальном растровом редакторе, в опенкомпах, а при наличии нужного скрипта - прямо в консоли.
Но в этом формате будем хранить иконки на диске. Внутри программы они будут преобразовываться в таблицу, хранящую цвет каждого пикселя.
Давным-давно делал модный файловый менеджер с графическим интерфейсом для опенкомпов.
Переходы по папкам, запуск файлов, распаковака tarball'ов и просмотр картинок в одной программе, к тому же фичи в виде листания свайпами, экранной клавиатуры и горстки настроек. И все это добро занимало меньше килобайта.
Но развивать идею не стал, код удалил и осталась только одна картинка тестовой версии.
Недавно решил это дело возродить, без зависимостей и лишних свистоплясо
Когда я узнал о JPS, у меня возникла идея упростить A*. Можно выкинуть волновую рекурсию, которая используется во всех алгоритмах поиска пути. Для этого, берем все узлы, которые являются препятствиями, помечаем соседние свободные узлы и строим путь. Из самого описания выходит, что данный алгоритм подойдет не для всех типов графов, но ботам на регулярной сетке в самый раз.
Проблема данного алгоритма в том, что препятствий может быть очень много, а на пути между стартом и финишем очень мало.
В процессе подгонки всех функций программа очень быстро разрослась.
Дам краткий обзор всех новинок.
Минимальная и максимальная плотность были вынесены в начало программы к остальным переменным.
+ переменная port, для модема.
+ переменные steps и turns, вначале для отладки. steps пригодилась для подсчета шагов, чтобы каждые 32 шага проверять состояние инструмента и батареи.
+ функция arr2a_arr() - преобразование списков в ассоциативный массив для быстрого доступа к
Эвристические функции:
Давление - штраф на ход по вертикали. Нужен из-за того, что начало сканирования либо сверху, либо снизу, следовательно, заканчивать добычу надо ближе туда, где начнется следующее сканирование.
Недоход - робот не заходит на позицию метки, чтобы сэкономить лишний шаг (не всегда оптимально, но суммарный эффект - положительный)
Штраф на повороты - добавление шага, при оценке расстояния, если целевой блок находится дальше, чем в одном блоке от текущей оси.
Для настройки работы программы, надо узнать плотность добываемых блоков и плотность мусора, чтобы сделать предварительный фильтр на этапе сканирования.
Плотность одной руды в разных модах отличается, но она близка к ванильной т. к. механика работы инструментов одна.
Сделал шпаргалку с информацией о плотностях из разных модов.
Плотность, уровень инструмента, название.
Minecraft
3 2 Алмазная руда
3 2 Изумрудная руда
3 2 Золотая руда
3 2 Красная руда
3 1 Желез
Все-таки добывать руду слоями дольше, чем свободным обходом всех доступных блоков.
На тестовом стенде свободный - 2 минуты 50 секунд, послойный - 3 минуты 9 секунд.
Тут очень сильно напрашивается дополнительная эвристика на сокращение поворотов и прямых одноблочных ходов.
И упаковку запускать только при нужде.
Добытые ресурсы надобно рассортировать.
Для этого дела задействуем контроллер инвентаря. Надобно пройти по всем слотам, получить информацию о содержимом и сравнить название со списком ненужных предметов (который предварительно составим), при совпадении опустошать.
Но это не вся функция. У нас есть еще верстак, который может помочь, очень сильно ужать, некоторые ресурсы (уголь, редстоун, алмазы, изумруды, лазурит). Верстак занимает в инвентаре 9 слотов, еще 1 слот добавим на резу
При запуске программы надо оценить возможности робота, чтобы в дальнейшем, можно было точно знать количество энергии для перехода на точку старта.
Робот должен измерить уровень энергии, сделать шаг, измерить еще раз и вычислить разницу. Эту разницу будет учитывать при измерении расстояния и принимать решение - идти домой или не идти.
Функция robot.durability() не показывает правильный износ для зачарованных инструментов.
Придется несколько раз ставить и разрушать блок, пока не обнаружится
Геосканер потребляет много энергии, а функция compass() делает по 4 скана, пока не установит направление.
Надо это исправить. Пусть робот сначала проверит наличие блока перед носом, сделает скан всех блоков вокруг себя, затем сломает блок и проверит разницу в полученных данных.
Таким образом, будет производиться всего два сканирования, в прошлой версии их могло быть бесконечно много - если рядом нет блоков, робот бы крутился и молотил инструментом по воздуху, попутно делая по 4 сканиро
Ядро копателя готово, теперь можно и пощупать.
Напишем пробную функцию сканирования и добычи одного слоя.
Сначала откалибруем компас и зададим таблицу с координатами сканируемых квадратов.
Затем, отсканируем квадрат 16 на 16 блоков, выведем количество обнаруженных блоков.
И в цикле обойдем все метки. Вроде бы все просто.
Ах, да... будем искать ближайший блок к текущей позиции, чтобы быстрее закончить работу.
Есть много подходов к определению расстояний.
Робот может двигаться, пора добавить функцию сканирования породы и калибровки компаса.
(Пока тестировал, обнаружил баг работы с зачарованными инструментами, пришлось немного переделать функцию step() - теперь после неудачного свинга, робот дополнительно проверяет наличие блока. Можно будет оставить, даже когда разрабы это исправят)
Чтобы отфильтровать блоки по плотности, надо получить плотность нужных блоков с учетом шумов.
На расстоянии x8 z8 y1 от геосканера, максимальная
Чтобы программа могла контролировать движения робота, добавим систему координат и функционал связанный с ней.
Так как робот будет шахтером, то все движения должны сопровождаться разрушением блоков, он будет ползать сквозь породу, попутно захватывая руду.
Описание основной двигательной деятельности занимает всего четыре функции (можно и три, но в прошлой версии, в процессе борьбы за место, пришлось одну разделить)
Приведу базовый код, затем опишу, что он делает.
local component
И так, наконец-то возвращаюсь к роботу-копателю. Да будут новые баги и новые фичи!
Краткий план внедряемых фич:
Улучшенное сканирование руд.
Робот сканирует под собой квадрат 16x16 блоков, опускаясь блок за блоком.
При обнаружении бедрока запускается функция добычи.
При добыче робот поднимается и в цикле ищет ближайшие по горизонтали блоки руды, захватывая три слоя - Y+1, Y, Y-1
Определение энергопотребления сборки при запуске. На старте, робот запо