Перейти к публикации
Форум - ComputerCraft
VeLLeSSS

Робот - укладчик

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

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

  • Можно регулировать длину и ширину будущей дороги
  • Робот может использовать больше одного слота

Ни на что не претендую, просто моё первое знакомство с модом вообще :)
И чего я вообще с роботов начал...
 
Ссылка на программу - http://pastebin.com/yf8FGJW9

Спасибо за внимание.

  • Like 6

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


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

Чистенький, аккуратный код. Хорошее начало. =)

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


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

Если функция вызывается из одного и того же места, то можно ее не выносить отдельно.

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

local com = require("component")
local bot = require("robot")
local term = require("term")
local turn, l, w

print('Введите длину дороги: ')
l = tonumber(term.read())
print('Введите ширину дороги: ')
w = tonumber(term.read())
print('Спасибо! Робот приступил к работе.')
for i = 1, w do
  if bot.count() < l then
    bot.select(bot.select()+1)
  end
  if i % 2 == 0 then
    turn = bot.turnRight
  else
    turn = bot.turnLeft
  end
  for i = 1, l do
    bot.swingDown()
    bot.placeDown()
    bot.forward()
  end
  turn()
  bot.forward()
  turn()
  bot.forward()
end

Неплохо бы добавить строительство лестниц, они более трудоемкие в постройке руками.

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


Ссылка на сообщение
Поделиться на других сайтах
Если функция вызывается из одного и того же места, то можно ее не выносить отдельно.

 

if x >= rx and y >= ry and x < (rx + w) and y < (ry + h) and btn == rbtn then ... end

-- VS

local function buttonClickInBox(x, y, btn, rx, ry, rw, rh, rbtn)
  return x >= rx and y >= ry and x < (rx + w) and y < (ry + h) and btn == rbtn
end

if buttonClickInBox(x, y, btn, rx, ry, rw, rh) then ... end

сравни и сделай вывод, какой код понятнее

  • Like 1

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


Ссылка на сообщение
Поделиться на других сайтах
local function contains(box, x, y)
  return x >= button.x and y >= button y
     and x < (button.x+button.width) and y < (button.y+button.height)
end

local function isClicked(box, x, y, button)
  return contains(box, x, y) and button == leftButton
end

Вот. :D

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


Ссылка на сообщение
Поделиться на других сайтах
local function contains(box, x, y)
  return x >= button.x and y >= button y
     and x < (button.x+button.width) and y < (button.y+button.height)
end

local function isClicked(box, x, y, button)
  return contains(box, x, y) and button == leftButton
end
Вот. :D

 

ты накосячил

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


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

ты накосячил

 

Главное идея. А так-то понятно, что это не промышленный код.

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


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

Ссылка на программу - http://pastebin.com/yf8FGJW9

 

Замечания и предложения.

  1. Код чистенький и аккуратненький
  2. Чем локальнее переменная тем лучше. Использовать глобальные переменные стоит только в тех случаях, когда ты как минимум сутки сидишь и не можешь понять как написать код не исспользуя её. Когда используешь глобальные переменные, ты можешь изменить работу кривонаписаной библиотеки, совершенно не подазревая об этом. Также в обратную сторону.
  3. Переменные w и l нужно сделать локальными и передавать в функцию через аргументы

    local function digandplace(lenght) --операция укладывания
  4. work_r и work_l лучше заменить вот на такую штуку

    local function work(length, side)
      local turn = bot[(side == "right") and "turnRight" or "turnLeft"]
      digandplace(length)
      turn()
      bot.forward()
      turn()
      bot.forward()
    end
                                                                                                         @fixed by fingercomp
    
    а вызывать эту функцию так:

    work(l, (i % 2 == 0) and "right" or "left")
  5. Функция, в названии которой первое слово check, должна возращать переменную типа bool 
Изменено пользователем Seryoga
  • Like 4

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


Ссылка на сообщение
Поделиться на других сайтах
Главное идея. А так-то понятно, что это не промышленный код.

 

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

 

можно было сделать и так

local function contains(rx, ry, rw, rh, x, y)
  return x >= rx and y >= ry
     and x < (rx + rw) and y < (ry + rh)
end

if contains(tab.x, tab.y, tab.w, tab.h, clickX, clickY)
   and clickButton == tab.button then
  ...
end

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


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

 

  1. work_r и work_l лучше заменить вот на такую штуку

    function work(lenght, side)
        turn = bot[(side == "right") and "turnRight" or "turnLeft"]
        digandplace(lenght)
        turn()
        bot.forward()
        turn()
        bot.forward()
    end
    а вызывать эту функцию так:

    work(l, (i % 2 == 0) and "right" or "left")

 

 

Очень интересные предложения.  Это очень упрощает код.

 

Я только не понял, как осуществляется поворот. А именно  вот эту строчку:

turn = bot[(side == "right") and "turnRight" or "turnLeft"]

Почему в квадратных скобках?   И почему нет (side == "left")?

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

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


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

(side == "right") — сравнение строки со строкой. Будет true, если строка в переменной side равна "right", и false в противном случае.

 

(side == "right") and "turnRight" or "turnLeft" — это некое подобие :?, тернарного оператора, в Луа.

Разделим его на три части: левая — всё, что до and, правая — всё, что после or, и средняя — всё, что между этими операторами.

Тогда получаем следующую логику: если левый и средний значения не равны false или nil, то будет возвращено выражение средней части. Иначе — правой.

То есть, если у нас сторона равна "right", будет возвращена строка "turnRight", иначе же будет "turnLeft".

 

bot[(side == "right") and "turnRight" or "turnLeft"] — строка, которая у нас вернулась в прошлом шаге, теперь подставляется между квадратных скобок. Получаем bot["turnRight"] или bot["turnLeft"].

Тут нужно помнить, что для Луа tbl.key и tbl["key"] — одинаковые выражения, а точка — это просто синтаксический сахар. Тогда выходит, что при сравнения у нас возвращаются bot.turnLeft или bot.turnRight.

 

turn = bot[(side == "right") and "turnRight" or "turnLeft"] — значение, полученное выше (bot.turnLeft или bot.turnRight), присваивается переменной turn.

 

 

Код предложенный совершенно не идеален — так вообще писать нельзя.

  • Неправильно слово написано: длина по-английски — length, а не lenght.
  • Функция не локальная, а глобальная. Это считается дурным тоном — вы засоряете _G.
  • Переменные без local становятся глобальными. То же, что и выше — мусор в _G. Я так однажды баг не мог часами найти — откуда-то переменная уже имела значение, хотя я его не присваивал. Просто забыл local, как оказалось.

Вот так какнонично должен выглядеть код:

 

 

local function work(length, side)
  local turn = bot[(side == "right") and "turnRight" or "turnLeft"]
  digandplace(length)
  turn()
  bot.forward()
  turn()
  bot.forward()
end
  • Like 4

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


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

Огромное спасибо!

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

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

 

То, что функции лучше делать тоже локальными  не знал, спасибо!

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

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


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

Вот тут подробнее про эти логические операторы Ktlo рассказывал: http://computercraft.ru/topic/1058-logicheskie-vyrazheniia-v-lua-ili-izbavliaemsia-ot-logi/

Рекомендую прочитать. А лучше ещё всю "Базу знаний" просмотреть.

  • Like 1

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


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

VeLLeSSS, если бы не ты, со своей программой, то я бы ни за что не взялся бы делать свою программу для робота!
Спасибо тебе за практический пример использования функций в цельной программе!

Я смог разобраться "что к чему" и "как" - работает в ней: и начал делать свою программу, взяв за основу - твою ))
Но в итоге, я глубоко переработал тело программы, да так, что от твоей программы у меня осталась только "шапка", да несколько строк диалогов.
Остальное все новое.
Потом выложу свою, чтобы было лучше понятно о чем говорю.

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

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


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

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

×