sk1zls 0 Опубликовано: 10 октября, 2020 нужен цикл выполнения работы роботом пример поставить блок (алмаз например) сломать блок повторение цикла Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Chebuya 415 Опубликовано: 11 октября, 2020 от Asior'а: https://pastebin.com/3ifphkJi 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Bs0Dd 206 Опубликовано: 8 декабря, 2020 Если нужно сэкономить на производстве роботов, то могу предложить немного переработанную версию (сделанную за пару минут на коленке) на основе той же программы от Asior'а: https://pastebin.com/gdk0by50 Разница (помимо большего размера) в том, что программа может исполняться прямо из EEPROM, что позволяет собирать крайне дешевых роботов (насколько уж это возможно): В данном случае не нужен даже дисплей и видеокарта, достаточно прошить каким-нибудь компьютером чип и собрать с ним робота 3 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 154 Опубликовано: 8 декабря, 2020 1 час назад, Bs0Dd сказал: Если нужно сэкономить на производстве роботов, то могу предложить немного переработанную версию (сделанную за пару минут на коленке) на основе той же программы от Asior'а: https://pastebin.com/gdk0by50 За первую попытку, конечно же, лайк. Но всё же, не стоило так бездумно копировать код из стандартной библиотеки. Там же достаточно было несколько строк всего вытащить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Bs0Dd 206 Опубликовано: 8 декабря, 2020 (изменено) 16 минут назад, eu_tomat сказал: Но всё же, не стоило так бездумно копировать код из стандартной библиотеки. Там же достаточно было несколько строк всего вытащить. Ох, спасибо за замечание, скорая работа делает свое (и малый опыт работы с EEPROM программками). Совсем забыл, что в данном случае будет достаточно computer.pullSignal(), ибо если приостановка собьется ивентом, по идее, ничего страшного быть не должно Убрал нарезки из библиотеки в коде и заменил на него, вроде все работает. Изменено 8 декабря, 2020 пользователем Bs0Dd 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 154 Опубликовано: 8 декабря, 2020 45 минут назад, Bs0Dd сказал: Убрал нарезки из библиотеки в коде и заменил на него, вроде все работает. Каких прекрасных результатов можно достичь, если не спешить, и немного подумать! Но я предлагаю дополнительно поразмыслить. Казалось бы, в таком примитивном роботе попросту отсутствуют компоненты, которые бы могли генерировать сигналы. Тем не менее, генерируются сигналы при появлении или исчезновении предметов в инвентаре робота. При этом никто не забирает их из очереди событий. Теоретически, это могло бы происходить при вызове computer.pullSignal(0), но он выполняется только при неудачных попытках срубить блок, а значит, нечасто. К моменту вызова computer.pullSignal(5) очередь событий окажется, скорее всего, непустой. И попытка взять паузу окажется неудачной. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 154 Опубликовано: 8 декабря, 2020 Я ещё раз посмотрел код. Там после computer.pullSignal(0) следуют вызовы r.drop(0, 64). Соответственно, даже если произошло везение в предыдущей части кода, и очередь сигналов каким-то образом очистилась, то успешное выполнение robot.drop() снова поставит сигнал очистки слота робота в очередь событий. Итог: пауза не будет выполнена почти никогда. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Bs0Dd 206 Опубликовано: 9 декабря, 2020 6 часов назад, eu_tomat сказал: Я ещё раз посмотрел код. Там после computer.pullSignal(0) следуют вызовы r.drop(0, 64). Соответственно, даже если произошло везение в предыдущей части кода, и очередь сигналов каким-то образом очистилась, то успешное выполнение robot.drop() снова поставит сигнал очистки слота робота в очередь событий. Итог: пауза не будет выполнена почти никогда. Пауза в конце тут стоит, сколь я понял, на тот случай, если в сундуке вдруг кончатся ресурсы. Тогда робот будет ждать 5 секунд перед следующей попыткой взять оттуда блок. И если уже есть ивенты и пауза не произойдет, то он опять попытается взять блоки, поймет, что их нет и снова пойдет в ожидание на 5 сек. Можно конечно, как в слипе, через цикл по времени аптайма дергать пуллСигнал, тогда такого не будет. Но вообще в такой конструкции, как я говорил, сбив паузы не критичен. Задержка в 5 сек все равно работает (ибо робот берет блоки не сразу после их закидывания в сундук), проверял перед правкой в паст Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 154 Опубликовано: 9 декабря, 2020 33 минуты назад, Bs0Dd сказал: Пауза в конце тут стоит, сколь я понял, на тот случай, если в сундуке вдруг кончатся ресурсы. Тогда робот будет ждать 5 секунд перед следующей попыткой взять оттуда блок. И если уже есть ивенты и пауза не произойдет, то он опять попытается взять блоки, поймет, что их нет и снова пойдет в ожидание на 5 сек. Да, пауза стоит на тот случай, если кончится ресурсы, и для того, чтобы не создавать бесполезную нагрузку на сервер. Но в текущей реалзиации, прежде чем выполнится пауза, робот попытается взять блоки 255 раз. А это противоречит цели, ради которой в программу добавлена пауза. 41 минуту назад, Bs0Dd сказал: Но вообще в такой конструкции, как я говорил, сбив паузы не критичен. Задержка в 5 сек все равно работает (ибо робот берет блоки не сразу после их закидывания в сундук), проверял перед правкой в паст Это уже зависит от критериев критичности. Для чего именно не критичен сбой паузы? Для нагрузки на сервер? Так нагрузка обычно и складывается из таких мелочей, когда программа продолжает что-то делать, когда делать уже ничего не требуется. Да, задержка в 5 секунд всё равно сработает, рано или поздно. Тут я согласен. Я поспешил со своим категоричным заявлением. Был не прав. Переформулирую. Задержка почти никогда не выполнится сразу после рубки очередного стака блоков. В большинстве случаев задержка в 5 секунд выполнится лишь после 255 неудачных попыток получить блоки из сундука. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Zer0Galaxy 2 187 Опубликовано: 9 декабря, 2020 Почему бы не сделать так? while computer.pullSignal(5) do; В этом случае робот очистит очередь сигналов прежде чем начать отсчет таймаута. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 154 Опубликовано: 9 декабря, 2020 20 минут назад, Zer0Galaxy сказал: Почему бы не сделать так? while computer.pullSignal(5) do; В этом случае робот очистит очередь сигналов прежде чем начать отсчет таймаута. Можно сделать и так, если учесть, что при такой реализации пауза после переработки полного стака предметов будет равна не 5, а 8.2 секунды. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Bs0Dd 206 Опубликовано: 9 декабря, 2020 Мда, наделал я тут блинов комом Сделал паузу по функции из ОС, проверял на роботе с дисплеем, теперь не спамит (вставлял перед слип-циклом принт) И на всякий добавил проверку и на то, поставился ли блок, ибо если поставить блок не вышло, программа уйдет в нулевую паузу пытаясь сломать воздух и после уладки проблемы нужно самому поставить блок перед роботом, дабы он его сломал и вышел из цикла. Возможно я наделал еще чего не так, честно говоря, в роботов полез впервые и не ожидал, что писать под них программы несколько сложнее, чем на обычные компьютеры (особенно если дело касается EEPROM-программ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 154 Опубликовано: 9 декабря, 2020 1 час назад, Bs0Dd сказал: Сделал паузу по функции из ОС Да, так вернее. Но всё равно не надо спешить и тупо копировать код: local ws = computer.uptime() repeat computer.pullSignal(ws - computer.uptime()) until computer.uptime() >= ws Зачем в скопированном куске оставлять код цикла, зная, что тот выполнится ровно один раз? Зачем в скопированном куске оставлять код получения текущего времени, зная, что параметром функции computer.pullSignanl всегда будет ноль? Все эти лишние действия не бесплатны, они повышают нагрузку на игровой сервер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Bs0Dd 206 Опубликовано: 9 декабря, 2020 33 минуты назад, eu_tomat сказал: Зачем в скопированном куске оставлять код цикла, зная, что тот выполнится ровно один раз? Исправил и это упущение (надеюсь правильно). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 154 Опубликовано: 9 декабря, 2020 21 минуту назад, Bs0Dd сказал: Исправил и это упущение (надеюсь правильно). Вроде бы правильно (если я ничего не упустил). Теперь программа стала даже чуть лучше оригинала. Но можно сделать ещё чуть лучше. Например, было бы полезным проверять успешность выгрузки предметов из слота и также впадать в спячку на время, пока игрок не освободит инвентарь. Пауза при неудачной выгрузке предметов не мене важна, чем при загрузке. Также есть три идеи для оптимизации: Здесь можно избавиться от вызова функций count: if r.suck(1, 64) then local rep = r.count(1) В документации сказано, что метод suck() возвращает значение типа boolean, но это не совсем так. В случае неудачи suck() вернёт false, а в случае успеха вернёт количество предметов. В каждой итерации цикла заново считывается размер инвентаря робота: while true do ... for i=1, r.inventorySize() do Это, конечно, экономит одну переменную, но память не экономит всё равно. Зато немного нагружает процесср. Считывание размера инвентаря в каждой итерации цикла имеет смысл только для роботов, оснащённых съёмными апгрейдами инвентаря. А эта строчка, по-моему, вообще лишняя r.select(1) Я не вижу особого смысла загружать предметы именно в первый слот. Может быть, если бы размер инвентаря робота превышал 16 слотов, то игроку было бы удобно визуально контролировать процесс работы программы. Но это, похоже, не тот случай. Только лишняя нагрузка на сервер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Bs0Dd 206 Опубликовано: 9 декабря, 2020 8 часов назад, eu_tomat сказал: Также есть три идеи для оптимизации Учел, добавил проверку на выгружаемость (проверяется также, выгружен ли слот полностью), иначе отдых Бонусом добавлено: -Опциональная возможность использования динамика в качестве индикатора проишествия -Проверка, не исчерпалась ли прочность/заряд инструмента (иначе снова спим) -Если есть возможность вставить в робота контроллер инвентаря, то можнр включить автозарядку инструмента (например Иридиевый бур). По достижению лимита робот прервет работу, повернется в сторону зарядника (кол-во поворотов до него задается в переменной), положит бур, уснет на время его зарядки (задается вручную), проснется, заберет, повернется обратно и продолжит работу Возможно, опять же, можно где-то сделать и лучше 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
serafim 272 Опубликовано: 9 декабря, 2020 форматирование немного съезжает, поправил по 2 пробела Скрытый текст --CycleBlockBreaker for EEPROM --Original OpenOS version by Asior (Asioron) --Expanded EEPROM version by Bs()Dd --[[Minimum requirements: *Robot - 1 tier In robot: *CPU - 1 tier *1x Memory - 1 tier *Inventory Upgrade *EEPROM with flash this code *Mining tool *Computer with OpenOS for flashing EEPROM Place the chest on top and put blocks there Place the chest at the bottom, there will be loot from blocks ]] r = component.proxy(component.list("robot")()) c = component.proxy(component.list("inventory_controller")()) inv = r.inventorySize() speaker = false --Set true for using speaker when something is gone wrong lowcharge = 0.005 --Set there number maximal working charge in durability() format --Needs Inventory Controller autocharge = false --Set there number of turns right to charger (for charging tools) chargesleep = 15 --Set there number of sleep duration while tool is charging function turnNcharge() for i = 1, autocharge do r.turn(true) end c.equip() r.drop(3, 1) local ws = computer.uptime() + chargesleep repeat computer.pullSignal(ws - computer.uptime()) until computer.uptime() >= ws r.suck(3, 1) c.equip() for i = 1, autocharge do r.turn(false) end end while true do local rep = r.suck(1, 64) if rep then for i = 1, rep do while not r.place(3) do if speaker then computer.beep(1100, 0.5) else computer.pullSignal(0) end end while not r.swing(3) do if speaker then computer.beep(1000, 0.5) else computer.pullSignal(0) end end if r.durability() then while r.durability() < lowcharge do if autocharge then turnNcharge() else if speaker then for i = 1, 10 do computer.beep(700, 0.5) end else local ws = computer.uptime() + 5 --Wating 5 sec, then trying to drop blocks again repeat computer.pullSignal(ws - computer.uptime()) until computer.uptime() >= ws end end end end end for i = 1, inv do if r.count(i) > 0 then r.select(i) while not r.drop(0, 64) or r.count(i) > 0 do if speaker then for i = 1, 10 do computer.beep(700, 0.5) end else local ws = computer.uptime() + 5 --Wating 5 sec, then trying to drop blocks again repeat computer.pullSignal(ws - computer.uptime()) until computer.uptime() >= ws end end end end else if speaker then for i = 1, 10 do computer.beep(500, 0.5) end else local ws = computer.uptime() + 5 --Wating 5 sec, then trying to get blocks again repeat computer.pullSignal(ws - computer.uptime()) until computer.uptime() >= ws end end end а так вроде норм Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Bs0Dd 206 Опубликовано: 9 декабря, 2020 17 минут назад, serafim сказал: форматирование немного съезжает, поправил по 2 пробела Обновил. Нужно, пожалуй, найти что-то получше gedit'а для редактирования программ вне OpenOS Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 154 Опубликовано: 9 декабря, 2020 1 час назад, Bs0Dd сказал: Учел, добавил проверку на выгружаемость (проверяется также, выгружен ли слот полностью), иначе отдых Бонусом добавлено: ... Возможно, опять же, можно где-то сделать и лучше Улучшать программу можно бесконечно. Функционал растёт, увеличивается количество мест, где может возникнуть ошибка. Возникает куча вариантов их исправления. Например, что произойдёт, если в заряднике для инструмента рабочий слот окажется занятым? Игрок может что-то закинуть в него на зарядку. Значит, надо писать инструкцию, что зарядник должен быть свободен. Или робот должен временно вынимать этот инструмент, и вместо него класть на зарядку инструмент робота. Или просто выдавать ошибку и ждать. Но такую ситуацию в том или ином виде желательно предусмотреть. Код задержки начал так часто использоваться и копироваться, что пора выносить его в отдельную функцию. В текущем виде код разбухает, и есть шанс не заметить мелкую ошибку, допущенную при копировании. То же самое и со звуковыми сигналами: желательно разработать какую-то кодовую систему сигналов и вынести генерацию звука в отдельную функцию. Это упростит дальнейшую доработку программы, если она потребуется. И вообще, при большом разнообразии звуковых сигналов имеет смысл всё-таки ограничить их количество и добавить в робота видеокарту и монитор, чтобы выводить сообщения в более понятном виде. А звуковой сигнал можно использовать для привлечения внимания игрока. Впрочем, это моё субъективное отношение к проблеме оповещения, я не настаиваю именно на таком решении. Ещё я вижу проблему в этом участке кода: while r.durability() < lowcharge do Сейчас в случае, если автоматическая подзарядка не предусмотрена, робот просто ожидает, когда инструмент в его слоте зарядится. Сам собой от одного лишь ожидания он не зарядится, поэтому игрок в какой-то момент вручную извлечёт инструмент из робота для зарядки. А в это время на очередной итерации цикла программа прервётся ошибкой при попытке сравнения разных типов. Также желательно сбрасывать autocharge в false при отсутствии контроллера инвентаря или же обрабатывать ошибку в процессе работы, если, например, контроллер инвентаря съёмный. Или дожидаться его установки игроком. Тут, опять же, есть большой простор для обработки этой ситуации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах