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

робот добытчик удача x3

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

нужен цикл выполнения работы роботом

пример

поставить блок (алмаз например)

сломать блок 

повторение цикла 

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


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

Если нужно сэкономить на производстве роботов, то могу предложить немного переработанную версию (сделанную за пару минут на коленке) на основе той же программы от Asior'а: https://pastebin.com/gdk0by50

 

Разница (помимо большего размера) в том, что программа может исполняться прямо из EEPROM, что позволяет собирать крайне дешевых роботов (насколько уж это возможно):

 

2014150215_2020-12-0817-45-23.png.6675c9897a3c3517b3466d7f3c38d4ab.png

 

В данном случае не нужен даже дисплей и видеокарта, достаточно прошить каким-нибудь компьютером чип и собрать с ним робота

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


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, Bs0Dd сказал:

Если нужно сэкономить на производстве роботов, то могу предложить немного переработанную версию (сделанную за пару минут на коленке) на основе той же программы от Asior'а: https://pastebin.com/gdk0by50

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

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


Ссылка на сообщение
Поделиться на других сайтах
16 минут назад, eu_tomat сказал:

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

Ох, спасибо за замечание, скорая работа делает свое (и малый опыт работы с EEPROM программками).

Совсем забыл, что в данном случае будет достаточно computer.pullSignal(), ибо если приостановка собьется ивентом, по идее, ничего страшного быть не должно

Убрал нарезки из библиотеки в коде и заменил на него, вроде все работает.

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

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


Ссылка на сообщение
Поделиться на других сайтах
45 минут назад, Bs0Dd сказал:

Убрал нарезки из библиотеки в коде и заменил на него, вроде все работает.

Каких прекрасных результатов можно достичь, если не спешить, и немного подумать! Но я предлагаю дополнительно поразмыслить.

 

Казалось бы, в таком примитивном роботе попросту отсутствуют компоненты, которые бы могли генерировать сигналы. Тем не менее, генерируются сигналы при появлении или исчезновении предметов в инвентаре робота. При этом никто не забирает их из очереди событий. Теоретически, это могло бы происходить при вызове computer.pullSignal(0), но он выполняется только при неудачных попытках срубить блок, а значит, нечасто.

 

К моменту вызова computer.pullSignal(5) очередь событий окажется, скорее всего, непустой. И попытка взять паузу окажется неудачной.

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


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

Я ещё раз посмотрел код. Там после computer.pullSignal(0) следуют вызовы r.drop(0, 64).

 

Соответственно, даже если произошло везение в предыдущей части кода, и очередь сигналов каким-то образом очистилась, то успешное выполнение robot.drop() снова поставит сигнал очистки слота робота в очередь событий.

 

Итог: пауза не будет выполнена почти никогда.

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


Ссылка на сообщение
Поделиться на других сайтах
6 часов назад, eu_tomat сказал:

Я ещё раз посмотрел код. Там после computer.pullSignal(0) следуют вызовы r.drop(0, 64).

 

Соответственно, даже если произошло везение в предыдущей части кода, и очередь сигналов каким-то образом очистилась, то успешное выполнение robot.drop() снова поставит сигнал очистки слота робота в очередь событий.

 

Итог: пауза не будет выполнена почти никогда.

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

Можно конечно, как в слипе, через цикл по времени аптайма дергать пуллСигнал, тогда такого не будет. Но вообще в такой конструкции, как я говорил, сбив паузы не критичен. Задержка в 5 сек все равно работает (ибо робот берет блоки не сразу после их закидывания в сундук), проверял перед правкой в паст

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


Ссылка на сообщение
Поделиться на других сайтах
33 минуты назад, Bs0Dd сказал:

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

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

 

41 минуту назад, Bs0Dd сказал:

Но вообще в такой конструкции, как я говорил, сбив паузы не критичен. Задержка в 5 сек все равно работает (ибо робот берет блоки не сразу после их закидывания в сундук), проверял перед правкой в паст

Это уже зависит от критериев критичности. Для чего именно не критичен сбой паузы? Для нагрузки на сервер? Так нагрузка обычно и складывается из таких мелочей, когда программа продолжает что-то делать, когда делать уже ничего не требуется.

 

Да, задержка в 5 секунд всё равно сработает, рано или поздно. Тут я согласен. Я поспешил со своим категоричным заявлением. Был не прав. Переформулирую. Задержка почти никогда не выполнится сразу после рубки очередного стака блоков. В большинстве случаев задержка в 5 секунд выполнится лишь после 255 неудачных попыток получить блоки из сундука.

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


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

Почему бы не сделать так?

while computer.pullSignal(5) do;

В этом случае робот очистит очередь сигналов прежде чем начать отсчет таймаута.

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


Ссылка на сообщение
Поделиться на других сайтах
20 минут назад, Zer0Galaxy сказал:

Почему бы не сделать так?


while computer.pullSignal(5) do;

В этом случае робот очистит очередь сигналов прежде чем начать отсчет таймаута.

Можно сделать и так, если учесть, что при такой реализации пауза после переработки полного стака предметов будет равна не 5, а 8.2 секунды.

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


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

Мда, наделал я тут блинов комом

Сделал паузу по функции из ОС, проверял на роботе с дисплеем, теперь не спамит (вставлял перед слип-циклом принт)

И на всякий добавил проверку и на то, поставился ли блок, ибо если поставить блок не вышло, программа уйдет в нулевую паузу пытаясь сломать воздух и после уладки проблемы нужно самому поставить блок перед роботом, дабы он его сломал и вышел из цикла.

Возможно я наделал еще чего не так, честно говоря, в роботов полез впервые и не ожидал, что писать под них программы несколько сложнее, чем на обычные компьютеры (особенно если дело касается EEPROM-программ)

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


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, Bs0Dd сказал:

Сделал паузу по функции из ОС

Да, так вернее. Но всё равно не надо спешить и тупо копировать код:

local ws = computer.uptime()
repeat
  computer.pullSignal(ws - computer.uptime())
until computer.uptime() >= ws

Зачем в скопированном куске оставлять код цикла, зная, что тот выполнится ровно один раз?

Зачем в скопированном куске оставлять код получения текущего времени, зная, что параметром функции computer.pullSignanl всегда будет ноль?

 

Все эти лишние действия не бесплатны, они повышают нагрузку на игровой сервер.

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


Ссылка на сообщение
Поделиться на других сайтах
33 минуты назад, eu_tomat сказал:

Зачем в скопированном куске оставлять код цикла, зная, что тот выполнится ровно один раз?

Исправил и это упущение (надеюсь правильно).

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


Ссылка на сообщение
Поделиться на других сайтах
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 слотов, то игроку было бы удобно визуально контролировать процесс работы программы. Но это, похоже, не тот случай. Только лишняя нагрузка на сервер.

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


Ссылка на сообщение
Поделиться на других сайтах
8 часов назад, eu_tomat сказал:

Также есть три идеи для оптимизации

Учел, добавил проверку на выгружаемость (проверяется также, выгружен ли слот полностью), иначе отдых

 

Бонусом добавлено:

-Опциональная возможность использования динамика в качестве индикатора проишествия

-Проверка, не исчерпалась ли прочность/заряд инструмента (иначе снова спим)

-Если есть возможность вставить в робота контроллер инвентаря, то можнр включить автозарядку инструмента (например Иридиевый бур). По достижению лимита робот прервет работу, повернется в сторону зарядника (кол-во поворотов до него задается в переменной), положит бур, уснет на время его зарядки (задается вручную), проснется, заберет, повернется обратно и продолжит работу

 

Возможно, опять же, можно где-то сделать и лучше

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


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

форматирование немного съезжает, поправил по 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

 

 а так вроде норм

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


Ссылка на сообщение
Поделиться на других сайтах
17 минут назад, serafim сказал:

форматирование немного съезжает, поправил по 2 пробела

Обновил.

Нужно, пожалуй, найти что-то получше gedit'а для редактирования программ вне OpenOS

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


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, Bs0Dd сказал:

Учел, добавил проверку на выгружаемость (проверяется также, выгружен ли слот полностью), иначе отдых

 

Бонусом добавлено:

...

Возможно, опять же, можно где-то сделать и лучше

Улучшать программу можно бесконечно. Функционал растёт, увеличивается количество мест, где может возникнуть ошибка. Возникает куча вариантов их исправления.

 

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

 

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

 

То же самое и со звуковыми сигналами: желательно разработать какую-то  кодовую систему сигналов и вынести генерацию звука в отдельную функцию. Это упростит дальнейшую доработку программы, если она потребуется.

 

И вообще, при большом разнообразии звуковых сигналов имеет смысл всё-таки ограничить их количество и добавить в робота видеокарту и монитор, чтобы выводить сообщения в более понятном виде. А звуковой сигнал можно использовать для привлечения внимания игрока. Впрочем, это моё субъективное отношение к проблеме оповещения, я не настаиваю именно на таком решении.

 

Ещё я вижу проблему в этом участке кода:

while r.durability() < lowcharge do

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

 

Также желательно сбрасывать autocharge в false при отсутствии контроллера инвентаря или же обрабатывать ошибку в процессе работы, если, например, контроллер инвентаря съёмный. Или дожидаться его установки игроком. Тут, опять же, есть большой простор для обработки этой ситуации.

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


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

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

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

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

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

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

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

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

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


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