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


Фотография

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

OpenComputers

  • Авторизуйтесь для ответа в теме
Сообщений в теме: 14

#1 Оффлайн   VeLLeSSS

VeLLeSSS
  • Пользователи
  • Сообщений: 1
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 29 Октябрь 2016 - 13:21

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

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

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

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


  • Totoro, electronic_steve, Quant и 3 другим это нравится

#2 Оффлайн   Totoro

Totoro
  • Хранители Кода
  • Сообщений: 1 735
  • Уровень сигнала: 0,29%
  • В игре: 2 час. 13 мин.

Награды

                                      

Отправлено 29 Октябрь 2016 - 16:13

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



#3 Оффлайн   Doob

Doob
  • Пользователи
  • Сообщений: 814
  • Уровень сигнала: 19,36%
  • В игре: 146 час. 10 мин.

Награды

                                   

Отправлено 30 Октябрь 2016 - 06:02

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

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

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

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



#4 Оффлайн   LeshaInc

LeshaInc
  • Пользователи
  • Сообщений: 1 207
  • Уровень сигнала: 15,5%
  • В игре: 117 час. 1 мин.
  • ГородЛуна

Награды

                       

Отправлено 30 Октябрь 2016 - 11:16

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



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

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

#5 Оффлайн   Doob

Doob
  • Пользователи
  • Сообщений: 814
  • Уровень сигнала: 19,36%
  • В игре: 146 час. 10 мин.

Награды

                                   

Отправлено 30 Октябрь 2016 - 12:28

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

 

Оба одинаково непонятны.


  • Kartze это нравится

#6 Оффлайн   Totoro

Totoro
  • Хранители Кода
  • Сообщений: 1 735
  • Уровень сигнала: 0,29%
  • В игре: 2 час. 13 мин.

Награды

                                      

Отправлено 30 Октябрь 2016 - 13:32

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



#7 Оффлайн   LeshaInc

LeshaInc
  • Пользователи
  • Сообщений: 1 207
  • Уровень сигнала: 15,5%
  • В игре: 117 час. 1 мин.
  • ГородЛуна

Награды

                       

Отправлено 30 Октябрь 2016 - 13:36

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



ты накосячил

#8 Оффлайн   Totoro

Totoro
  • Хранители Кода
  • Сообщений: 1 735
  • Уровень сигнала: 0,29%
  • В игре: 2 час. 13 мин.

Награды

                                      

Отправлено 30 Октябрь 2016 - 13:38

ты накосячил

 

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



#9 Оффлайн   Seryoga

Seryoga
  • Пользователи
  • Сообщений: 108
  • Уровень сигнала: 0,34%
  • В игре: 2 час. 33 мин.
  • ГородSaint-Petersburg

Награды

        

Отправлено 30 Октябрь 2016 - 13:45

Ссылка на программу - 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: 13 Ноябрь 2016 - 12:35

  • Totoro, Fingercomp, bob558 и еще 1 это нравится

#10 Оффлайн   LeshaInc

LeshaInc
  • Пользователи
  • Сообщений: 1 207
  • Уровень сигнала: 15,5%
  • В игре: 117 час. 1 мин.
  • ГородЛуна

Награды

                       

Отправлено 30 Октябрь 2016 - 13:45

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



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

можно было сделать и так
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


#11 Оффлайн   bob558

bob558
  • Пользователи
  • Сообщений: 78
  • Уровень сигнала: 40,95%
  • В игре: 309 час. 14 мин.

Награды

     

Отправлено 13 Ноябрь 2016 - 09:19

 

  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: 13 Ноябрь 2016 - 10:59


#12 Онлайн   Fingercomp

Fingercomp
  • Гуру
  • Сообщений: 2 002
  • Уровень сигнала: 169,33%
  • В игре: 1278 час. 43 мин.

Награды

                                               

Отправлено 13 Ноябрь 2016 - 09:57

(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

  • Totoro, bob558, qwertyMAN и еще 1 это нравится

#13 Оффлайн   bob558

bob558
  • Пользователи
  • Сообщений: 78
  • Уровень сигнала: 40,95%
  • В игре: 309 час. 14 мин.

Награды

     

Отправлено 13 Ноябрь 2016 - 10:28

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

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

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

 

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


Сообщение отредактировал bob558: 13 Ноябрь 2016 - 10:59


#14 Онлайн   Fingercomp

Fingercomp
  • Гуру
  • Сообщений: 2 002
  • Уровень сигнала: 169,33%
  • В игре: 1278 час. 43 мин.

Награды

                                               

Отправлено 13 Ноябрь 2016 - 12:06

Вот тут подробнее про эти логические операторы Ktlo рассказывал: http://computercraft...aemsia-ot-logi/

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


  • bob558 это нравится

#15 Оффлайн   KleptoMMT5

KleptoMMT5
  • Пользователи
  • Сообщений: 5
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 30 Ноябрь 2016 - 17:31

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

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

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







Темы с аналогичным тегами OpenComputers

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных