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

Программа для робота "Miner"

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

Здравствуйте, друзья мои!

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

Представляю вашему вниманию программу для робота "Miner" ("Шахтер").

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

 

Системные требования:

  • Корпус 1-го уровня
  • Процессор 1-го уровня
  • 1 планка памяти 1,5-го уровня (это с запасом)
  • HDD 1-го уровня
  • Видеокарта -1го уровня
  • Lua-BIOS
  • Монитор 1-го уровня
  • Клавиатура
  • Улучшение "Инвентарь"
  • Улучшение "Контейнер" 1-го уровня
  • Геоанализатор

Дополнения для обслуживания робота:

  • Зарядное устройство
  • Преобразователь энергии
  • Источник энергии
  • Сундук (1-2 шт.)

Подготовка, установка, настройка и запуск.

Робот устанавливается на поверхности (можно и в пещере), перед будущей шахтой справа.

post-13229-0-79041300-1454248519_thumb.png

Под робота ставится сундук. Сбоку ставится зарядное устройство с источником питания. Например, я использую генератор из IC2 через АКБ, на угле, который добыл робот.

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

post-13229-0-86186300-1454251623_thumb.png

Первое что робот спрашивает - это какая у шахты будет ширина. Т.е. это размер второстепенных тоннелей. Мин. значение - 2. Если ввести некорректное значение (<2) или не ввести вовсе, то робот примет значение по умолчанию равное 2.

Второй вопрос - это длина. Т.е. размер главного тоннеля (от робота прямо по курсу). В связи со спецификой работы робота, введенное значение будет округлено до десятков в меньшую сторону, но не менее 10. Например, если ввести 34, то шахта будет 30 блоков в длину. Значение по умолчанию 10.

Третий вопрос - глубина шахты. Отсчет ведется от места старта робота. Уровень на котором он стоит = 0, на один блок ниже = 1 и т.д. Например, если робот стоит на уровне 64, а бедрок находится на уровне 1 и вам надо дорыть до него, тогда задайте глубину 62. Так же, если ввести отрицательное значение или не ввести вовсе - значение будет 0.

И последний вопрос - с какой глубины начать копать. Этот параметр удобен тем, что робот может начать копать с любой глубины, а не от точки старта. Например мне нужны алмазы. Я ставлю робота на поверхность (например высота 64), задаю ему глубину шахты = 59 (т.к. с глубины 5 начинается бедрок, а его робот грызть не умеет) и глубину для начала раскопок = 52 (основные залежи алмазов на глубине 12-5). После старта робот выкопает себе вертикальный тоннель, доберется до начала раскопок и начнет работать. Затем вернется тем же путем.

После прохода одного уровня (одной высоты), робот возвращается на место старта, вываливает всё что нарыл вниз (надеюсь вы не забыли поставить под него сундук) и заряжается 20 сек. После этого идет на сл. глубину.

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

 

Достоинства данной программы:

  • Минимальные системные требования
  • Добывает всё под чистую (кроме блэк-листа)
  • Начинает копать с любого уровня
  • Есть немного места для установки дополнительных апгрейдов
  • Из-за встречи с мобом программа не собъется
  • Добывает не только внутри шахты, но и ее внешний слой

Недостатки:

  • Если по каким-то причинам робот собьется (а вы его сможете найдете), то его не возможно вернуть в нужное русло. Только выключить, вернуть руками на старт и запустить заново с последней высоты.
  • Необходимо следить, чтобы инструмент робота не сломался.
  • Необходимо следить за уровнем энергии робота.
  • Не может сам снабжать себя энергией.
  • Заряжается на старте 20 сек. (может ему этого мало или много, в зависимости от размера шахты)

Планы на будущее:

  • Если робот собьется, то после повторного запуска сам начнет копать с глубины на которой закончил.
  • Научить робота работать с буром из IC2 (зарядить, положить, взять)
  • Ввести блек-лист задаваемый игроком.
  • Робот будет сам заряжаться сколько ему необходимо.
  • Если нужно вмешательство игрока, робот будет подавать сигнал.
  • Разный цвет подсветки, в зависимости от выполняемой операции.
  • Т.к. реализовать бОльшую самодостаточность робота с таким железом крайне сложно (хотя еще небольшой запас есть), далее будет программа для робота второго уровня.

Просьбы:

  1. Как всегда жду здоровой критики, идей, предложений. Единственное ограничение - это должен быть робот 1-го уровня.
  2. Нужны советы в оптимизации кода.
  3. В коде много комментариев. Это для меня и др. новичков. Так что не пинать.
  4. Если вы знаете подобную программу - покажите ее, пожалуйста. Хочется сравнить. Зашел в соседнюю ветку, посмотрел, опупел. Моя прога еще только в зачатке.
  5. К админам сервера: придумайте, пожалуйста, что-нибудь с лагами на сервере. В сингле программа работает идеально. На сервере - пропускает команды, выполняет их по два раза. В общем жуть. Робот зарывается в такую опу, что приходится его часами искать.

А! Собственно программа. http://pastebin.com/XkivBpat

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

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


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

 

 

К админам сервера: придумайте, пожалуйста, что-нибудь с лагами

Слава грегу! :smile3:  

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


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

Первое, за что глаз зацепился:

function forward() --Движение робота на 1 блок вперед
  if r.forward() then -- Если робот может сделать шаг
    return true -- то хорошо :-)
  else  -- Иначе...
    repeat
      r.swing() -- бъет по объекту впереди
      r.detect() -- проверяет остался ли объект
    until r.detect() == false -- Если нет..
    r.forward() -- то шаг вперед
  end
end
1) r.detect() внутри repeat/until совершенно бесполезен. Зачем его вызывать, если результат не проверяется?

2) Конструция r.detect() == false заменяется более компактной not r.detect()

3) Ошибка: r.forward() сразу за repeat/until не проверяется на успешное действие, поэтому могут быть сбои в движении. Конечно, перед этим была проверка, но между проверкой и действием могли произойти изменения: гравий осыпался, новый моб появился и т.д.

4) r.forward() в самом начале функции работает крайне неэффективно. Полгода назад я рассказывал об этом Артему (artem211), когда он писал свой геокопатель. Тогда, наверное, во всех найденных мною на этом форуме копалках имелась такая неэффективность. Безуспешная попытка r.forward() занимает столько же времени на выполнение, как и успешное движение. Поэтому продвижение сквозь сплошной массив породы по такому алгоритму замедляет робота почти в два раза.

Есть два выхода. Самый простой и выбранный Артемом – делать взмах киркой до попытки движения. Почему-то на неудачный взмах кирки время не тратилось. Сейчас может быть иначе, или потом может измениться. Второй вариант более надежный в будущем, но и сложный – анализировать второй параметр, возвращаемый r.detect().

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

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


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

Первое что робот спрашивает - это какая у шахты будет ширина. Т.е. это размер второстепенных тоннелей. Мин. значение - 2. Если ввести некорректное значение (<2) или не ввести вовсе, то робот примет значение по умолчанию равное 2.

До фразы про второстепенные тоннели следует объяснить, что это за тоннели такие, да и вообще хорошо бы кратко описать алгоритм разработки шахты. Тогда и программу будет легче читать.

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


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

Первое, за что глаз зацепился:

function forward() --Движение робота на 1 блок вперед
  if r.forward() then -- Если робот может сделать шаг
    return true -- то хорошо :-)
  else  -- Иначе...
    repeat
      r.swing() -- бъет по объекту впереди
      r.detect() -- проверяет остался ли объект
    until r.detect() == false -- Если нет..
    r.forward() -- то шаг вперед
  end
end
1) r.detect() внутри repeat/until совершенно бесполезен. Зачем его вызывать, если результат не проверяется?

2) Конструция r.detect() == false заменяется более компактной not r.detect()

3) Ошибка: r.forward() сразу за repeat/until не проверяется на успешное действие, поэтому могут быть сбои в движении. Конечно, перед этим была проверка, но между проверкой и действием могли произойти изменения: гравий осыпался, новый моб появился и т.д.

3) r.forward() в самом начале функции работает крайне неэффективно. Полгода назад я рассказывал об этом Артему (artem211), когда он писал свой геокопатель. Тогда, наверное, во всех найденных мною на этом форуме копалках имелась такая неэффективность. Безуспешная попытка r.forward() занимает столько же времени на выполнение, как и успешное движение. Поэтому продвижение сквозь сплошной массив породы по такому алгоритму замедляет робота почти в два раза.

Есть два выхода. Самый простой и выбранный Артемом – делать взмах киркой до попытки движения. Почему-то на неудачный взмах кирки время не тратилось. Сейчас может быть иначе, или потом может измениться. Второй вариант более надежный в будущем, но и сложный – анализировать второй параметр, возвращаемый r.detect().

 

1) Результат проверяется в until r.detect() == false. Здесь он вызывается, а ниже проверяется. Или я чего-то не так понял?

2) Если я заменю, можно убрать "r.detect() -- проверяет остался ли объект"?

3) Логично. Надо подумать, как красиво исправить.

Функция forward() служит исключительно для движения вперед, т.к. не всегда нужно копать перед собой. Если нужно что-то вскопать, это прописывается перед ее вызовом. Но раз там тратится столько времени, r.detect() действительно будет эффективнее.

Спасибо за замечания! Исправлю.

До фразы про второстепенные тоннели следует объяснить, что это за тоннели такие, да и вообще хорошо бы кратко описать алгоритм разработки шахты. Тогда и программу будет легче читать.

Придется картинку нарисовать. У меня не хватает воображения словами это описать.

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

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


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

1) Результат проверяется в until r.detect() == false. Здесь он вызывается, а ниже проверяется. Или я чего-то не так понял?

2) Если я заменю, можно убрать "r.detect() -- проверяет остался ли объект"?

3) Логично. Надо подумать, как красиво исправить.

3) В смысле 4) Функция forward() служит исключительно для движения вперед, т.к. не всегда нужно копать перед собой. Если нужно что-то вскопать, это прописывается перед ее вызовом. Но раз там тратится столько времени, r.detect() действительно будет эффективнее.

1) r.detect() вызывается и в том и в другом случае, но результат проверяется лишь во втором, поэтому первый вызов бесполезен.

2) r.detect() внутри цикла не нужен в любом случае, а предложенная мною замена при проверке -- всего лишь более короткая форма записи, не влияющая на алгоритм работы.

4) Тут вопрос стоит так. Что будет быстрее? Сначала попытаться двигаться, а при неудаче сломать блок и еще раз попытаться, либо сначала не глядя сломать, а потом двигаться. В большинстве случаев путь робота-шахтера преграждают блоки. Поэтому даже если тратится время на неудачную добычу блока, в среднем по шахте это все равно будет быстрее, чем тратить время на неудачную попытку движения.

 

P.S.: Поправлю свое сообщение, чтобы не путаться в двух пунктах с номером 3.

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


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

В большинстве случаев путь робота-шахтера преграждают блоки.

 

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

post-13229-0-82001200-1454270765_thumb.png

Так что не вижу смысла махать тяпкой перед каждым шагом или за зря проверять есть ли впереди помеха. Если заранее знаешь, что впереди блок (например при рытье тоннеля), то у меня там стоит r.swing(), а потом уже forward(). А если робот возвращается на подзарядку - вря тле там ему что-то помешает. А если и появится какой-то моб, то время на его устранение уйдет меньше, чем проверять каждый раз впереди стоящий блок.

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

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


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

1) r.detect() вызывается и в том и в другом случае, но результат проверяется лишь во втором, поэтому первый вызов бесполезен.

2) r.detect() внутри цикла не нужен в любом случае, а предложенная мною замена при проверке -- всего лишь более короткая форма записи, не влияющая на алгоритм работы.

4) Тут вопрос стоит так. Что будет быстрее? Сначала попытаться двигаться, а при неудаче сломать блок и еще раз попытаться, либо сначала не глядя сломать, а потом двигаться. В большинстве случаев путь робота-шахтера преграждают блоки. Поэтому даже если тратится время на неудачную добычу блока, в среднем по шахте это все равно будет быстрее, чем тратить время на неудачную попытку движения.

 

P.S.: Поправлю свое сообщение, чтобы не путаться в двух пунктах с номером 3.

Переписал функцию "forward() по твоему совету.

function forward() --Движение робота на 1 блок вперед
  if r.forward() then -- Если робот может сделать шаг
    return true -- то хорошо :-)
  else  -- Иначе...
    repeat
      r.swing() -- бъет по объекту впереди
    until not r.detect() -- Впереди чисто?
    forward() -- то шаг вперед
  end
end

Не знаю, правильно ли вызывать функцию в этой же функции, но всё работает и теперь проверяется. Спасибо!

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

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


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

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

Одно из двух: либо робот бродил в пустоте (повторно в той же шахте, или в пещере), либо счетчик что-то не то считает. Ищи ошибку.

А я поднял свои записи шестимесячной давности, когда писал статью об эффективной копке, да ногу тогда сломал, и майнкрафт забросил.

Сейчас перепроверил на свежей версии мода: при копке массива земли голой рукой ускорение в 1.5 раза, и в два – иридиевым буром. При проходе пустоты замедление на 10%.

Не знаю, правильно ли вызывать функцию в этой же функции, но всё работает и теперь проверяется.

Функцию из той же функции вызывать очень даже можно, и прием этот называется рекурсией. Иногда незаменимый и крайне эффективный, но в данном случае он дает только лишнее потребление памяти. А у тебя одна планка T-1.5. Код, конечно, рабочий, но он монструозный и тяжело воспринимается даже с комментариями, да и требует много места в памяти, а тут еще и рекурсия. Поэтому настоятельно советую: избавляйся от рекурсии. Готовое решение давать не буду, простые циклы ты освоил, а большего и не требуется. Изменено пользователем eu_tomat

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


Ссылка на сообщение
Поделиться на других сайтах
Код, конечно, рабочий, но он монструозный и тяжело воспринимается даже с комментариями

Вот оно! Надо мне правильно код научится писать. Так что:

1) Дополню статью алгоритмом разработки шахты и картиночками.

2) Уберу рекурсию.

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

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

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


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

И не забудь, что кроме r.forward() у тебя еще есть r.up() и r.down(). С ними надо работать аналогично, чтобы робот не сбивался с пути.

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


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

У меня есть глупый вопрос ... А как программу запустить ?

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


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

 

Ну, если автор желает сам решить проблему, то не будем ему мешать. Но, @@TraerTaer, ты чууть-чуть ошибаешься.

 

 

function forward()
  while not r.forward() then
    r.swing()
  end
end

Вот так, надеюсь, прокатит.

Хотя мы, опять же, не принимаем в расчет время, затрачиваемое разными действиями робота, а это важно!

 

 

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

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


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

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

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

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

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

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

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

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

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


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