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

[Java 8] O-Blocks IDE - визуальное программирование роботов

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

Годнота, только еще надо бы сделать возможность лепить несколько веревок на один вход/выход, а то чтобы прикрутить какой-нибудь код после if надо либо делать дублирование кода до if, либо составлять бороду из if if if, чтобы сделать необязательный if

 

Имеешь ввиду что-то такое?

 

ocb-programm0.png

 

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

 

Несколько веревеок на вход я делаю сейчас.

Тут проблема в том, во что это будет экспортировано. То что выше, на скриншоте - по сути цикл while. И по хорошемо должно экспортироваться в него. Однако схема может быть гораздо запутаннее, с несколькими переходами в начало цикла, или даже не только в начало.

Поэтому скорее всего, это все будет экспортировано в виде вермишели с операторами goto. =) Это конечно не радует, и противоречит принципам красивого кода... Но зато в OcBlocks "код" станет красивее и понятнее.

  • Like 1

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


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

Хм.. Я все не мог придумать, как экспортировать вермишель, про goto совсем забыл.

Главное, чтобы оно работало, а как оно будет работать это дело десятое :)

  • Like 1

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


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

Небольшое обновление. Запатчил и проапдейтил. Теперь будет запускаться на секунду дольше, это нормально. =)

 

dig_all_forward.png

 

Скачать

OcBlocks 0.21a (1 Mb)

 

Что нового

  • Экспорт "кода" в картинку PNG с прозрачным фоном. Типа той, что выше.
  • Поддержка вермишельного кода. Типа того, что выше.

Экспортируется во что-то такое:

-- [OcBlocks v0.21a generated code] --
local robot = require('robot')
::a::
local b = robot.detect()
if b then
  robot.swing()
  robot.forward()
  goto a
else
  robot.forward()
  os.exit()
end
-- [The END] --
  • Like 5

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


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

io.png

-- [OcBlocks v0.22a generated code] --
local robot = require('robot')
local a = io.read()
print(a)
os.exit()
-- [The END] --
  • Like 4

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


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

Теперь на O-Blocks можно официально написать свой "хеллоу-ворлд"!

untitled.png

Скачать бесплатно без СМС:

OcBlocks 0.3a (1.1 Mb)

-- [OcBlocks v0.3a generated code] --
local a = 'Hello World!'
local robot = require('robot')
::b::
print(a)
os.exit()
-- [The END] --
  • Like 6

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


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

e6a8a2012d2c2a033bcb0d6600c4894a.png

 

122a4c356130c2cece027bb39401749b.png

 

 

По логике программа спрашивает, стоит ли какой-то блок перед роботом. Если блок есть, то сначала выполняется robot.swing() и двигается вперед, а если нет, то робот просто двигается вперед. Сгенерировался какой-то непонятный код, явно несоответствующий моей логике хд

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


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

swing_check.png

 

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

 

Синий узел нужен для повторного использования этого значения позднее, если надо.

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

 

Код будет выглядеть так:

-- [OcBlocks v0.3a generated code] --
local robot = require('robot')
local a = robot.detect()
if a then
  robot.swing()
  ::b::
  robot.forward()
  os.exit()
else
  robot.forward()
  os.exit()
end
-- [The END] --

Не идеал в плане оптимизации, но логику передает верно.

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


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

 

 

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

 

А, вот оно как. Пасиба. 

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


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

Извини за назойливость, но так как в чате история храниться не долго, а мне надо тикать, то оставляю вопрос здесь:
 

Решил я сделать цикл, который проверяет, есть ли впереди блок. Если да - уничтожить и двигаться дальше, если нет - сразу двигаться дальше. В чём проблема: Я не пойму как вернуться обратно. Он просто прекращает цикл после проверки. Делает как надо, а потом стопорится и пишет, что закончил. Такие дела. Говнокод прилагаю: 90b6db9b2eab47319675f3e7ff4252a6.png

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


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

Если рассуждать логически. Здесь всё выполняется по линиям.

 

У цикла есть две ветки - ветка "плюс" и метка "минус".

По ветке "плюс" программа идёт когда цикл активен, а по ветке "минус" - когда он завершился.

 

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

 

Пример:

 

iE5Dd9L.png

Выполняется этот осьминог так:

1) Программа заходит в цикл

2) Цикл повторился 0 раз. Надо 10. Значит цикл активен. Значит идём по "плюсу".

3) Печатаем номер попытки в консоль

4) Возвращаемся к началу

5) Цикл повторился 1 раз. Надо 10. Идём по "плюсу".

....

31) Цикл повторился 10 раз. Цикл завершён, идем по "минусу".

32) Конец программы

 

Вот такой исходник сгенерится:

-- [OcBlocks v0.3a generated code] --
local a = '10'
local robot = require('robot')
for c = 1, tonumber(a) do
  print(c)
end
-- [The END] --
  • Like 1

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


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

посмотрел на код и на "осьминога",  и начал сомневаться, что же все-таки проще понять новичку, первое или второе :D

 

П.С. Интересно было бы увидеть копалку ProShow в этой программке. Какое там получится существо=)

  • Like 4

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


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

посмотрел на код и на "осьминога",  и начал сомневаться, что же все-таки проще понять новичку, первое или второе :D

 

П.С. Интересно было бы увидеть копалку ProShow в этой программке. Какое там получится существо=)

 

Да вот я тоже сомневаюсь. Надо сделать редизайн и ребрендинг  :)

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


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

Я тут тоже "копалку" делаю.Скоро выложу,посмотрим на код)))

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


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

Прикольно получилось. Графонистая такая, все на высшим уровне) но чет мне не зашло. Лично мне, проще написать код в Sublim'е, чем разбираться в детской 'поигрульке'. Хотя для новичков - будет полезно. Win10 64-bit, java: Version 8, Update 111. - робит.

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


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

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

Ещё будет така фишка как кастомные блоки. Можно будет нарисовать схемку и запечь её в свой блок. А потом использовать везде.

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


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

"Помогите. Я тут что-то тыкнул, а оно само сломалось. Что делать?"

 

le1gNEh.png

WbA6Pad.png

java.lang.NullPointerException
	at moonlightowl.openblocks.io.JSON.recreate(JSON.java:105)
	at moonlightowl.openblocks.OpenBlocks.load(OpenBlocks.java:399)
	at moonlightowl.openblocks.OpenBlocks.openProject(OpenBlocks.java:423)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at sun.reflect.misc.Trampoline.invoke(Unknown Source)
	at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
	at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1771)
	at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
	at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
	at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
	at javafx.event.Event.fireEvent(Event.java:198)
	at javafx.scene.control.MenuItem.fire(MenuItem.java:462)
	at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405)
	at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$343(ContextMenuContent.java:1358)
	at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
	at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
	at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
	at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
	at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
	at javafx.event.Event.fireEvent(Event.java:198)
	at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
	at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
	at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
	at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417)
	at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
	at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
	at com.sun.glass.ui.View.notifyMouse(View.java:937)
	at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
	at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
	at java.lang.Thread.run(Unknown Source)

 


"Ну и не сильно хотелось"

 

NcRDxqt.pngiIwPCrZ.png


"Ожидания - Реальность"

Действие -- Ожидание -- Реальность

ctrl + S -- сохранить файл -- двинуть полотно вверх

ctrl + shift + S -- сохранить файл как ... -- двинуть полотно вверх

ctrl + W -- закрыть файл -- двинуть полотно вниз

ctrl + A -- выделить всё (двинуть полотно влево) -- выделить всё  ?????????????????

ctrl + ПКМ -- копировать элемент -- nope
ПКМ + del -- удалить элемент -- активировать корзину
scroll -- сдвинуть полотно -- изменить масштаб

ctrl + [+-] -- изменить масштаб -- nope
ctrl + F -- поиск элемента -- nope
ПКМ -- выделить элемент -- nope
ЛКМ -- получить выпадающий список -- nope
соединение "портов" -- один драйвер (вывод) много буфферов (вход) -- много драйверов один буффер
ПКМ на порт -- получить список проводников и достать нужные -- достать только все
ПКМ и удержание на пустом месте -- движение полотна -- nope

 


Резюме

  • классная идея
  • нет документации и вообще какого-либо описания. А в таком проекте это самое важное, так как человек, который хочет использовать этот способ написания программ, может совершенно не знать, что такое программирование и с чем его едят.
    • Я 10 мин рисовал "Hello world", при этом заглядывая в код, который генерирует программа, иначе бы мог провозится гораздо дольше.
  • отсутствует многоуровневое описание
  • баги, много багов
    • выделение работатет только от верхнего левого к нижнему правому углу
    • фигня какая-то с проводничками, путаются и не хотят расутываться, улетают в космос
    • создаёт битые файлы
    • можно графически описать не синтезируемый алгоритм
    • создаются пременные, которые нельзя переиспользовать
    • ...

ps. почитай про: control flow graph и control flow analysis

Изменено пользователем Seryoga
  • Like 1

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


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

@@Seryoga, охрененный фидбек. А джва года такого ждал.  :D

 

Всё справедливо. Там надо передизайнить, отрефакторить, отдебажить и допилить всё. Я если честно начал забывать уже про этот проект.

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

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


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

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

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

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

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

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

Войти

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

Войти сейчас

×