Если рассматривать состязания основной категории World Robot Olympiad 2013 с точки зрения программирования, то самым интересным можно назвать состязание "Батик", второе место займет "Остров Комодо", а самым скучным "Боробудур". |
В этой заметке рассматриваются основные этапы решения первой части задания "Батик", а именно сортировка кубиков-"красок" по разноцветным корзинам.
Начать следует с того, чтобы еще раз взглянуть на соответствующий участок трассы:
Хочется отметить несколько моментов:
- Базовые лагерь не отделен от основного поля черной разделительной линией
- Напротив каждой корзины - черная линия, которая может использоваться для позиционирования робота около данной корзины.
Поэтому программирование начнется с того, чтобы научить робота доезжать до соответствующей линии из зоны старта. В целях отладки, цвет кубика пока не определяется. Но в программе сразу предусматривается способ указания, до какой линии роботу нужно ехать. Также не рассматривается пока способ четкого позиционирования на линии - такого движения, когда робот после остановки находится в предсказуемом положении относительно линии.
Следует заметить, что робот останавливается после линии. Если говорить о ее границах, то это будет граница дальняя от зоны старта.
Допустим, после выгрузки кубика робот находится на третей линии, причем в том же положении, как прибыл на эту позицию, - теперь роботу надо возвращаться на первую линию. Следовательно, ему опять нужно пересечь определенное количество линий. Т.е. в целом программирования движения будет похоже на то, что рассмотрено выше. Однако будут нюансы - робот не разворачивается, поэтому движение теперь будет в противоположную сторону и, чтобы оказаться в том же положении, как если бы робот ехал вперед (это нужно чтобы алгоритм выгрузки кубиков был одним и тем же, вне зависимости от того откуда приехал робот ), робот должен остановиться на дальней от зоны старта границе линии.
За такое движение не будет создаваться отдельный код. Вместо этого расширится функциональность кода выше.
Блок разветвления после цикла нужен для того, чтобы пересечь светлую полосу и подъехать к соответствующей границе черной линии. Например, робот стоит на третьей линии, ее задней границе, а для того чтобы попасть на вторую, он должен выполнить одну итерацию цикла, остановившись на ближней границе все той же третьей линии, а потом двигаться по светлому куску поля, пока не возникнет задняя граница со второй линией.
Как уже говорилось код, приведенный выше, начал свое существование из необходимости двигаться считая пересеченные линии. Если внимательно посмотреть, как придется двигаться роботу от одной корзины к другой (от линии с одним номером, к линии с другим номером), то можно найти определенную закономерность:
При движении от 1ой к 3ей нужно пересечь 2 линии;
от 1ой ко 2ой - 1 линию;
от 2ой к 3ей - 1 линию
от 3ей к 1ой - 2 линии;
от 3ей ко 2ой - 1 линию;
от 2ой к 1ой - 1 линию.
Видно, что количество линий сколько нужно пересечь равно модулю разницы между номерами линий на какую надо попасть и откуда: 2 (куда) - 1 (откуда) = 1; 3 (куда) - 1 (откуда) = 2; 1 (куда) - 3 (откуда) = -2. При этом знак результирующего значения показывает в какую сторону нужно двигаться роботу: если результат положительный, то вперед; если результат отрицательный, то назад.
Получается, что если в программе существует два входных параметра обозначающих куда ехать и откуда, то она будет выглядеть вот так:
Теперь дело за малым - нужно предусмотреть ситуации, когда роботу вообще не нужно двигаться между линиями (соседние кубики оказались одного цвета) - разница в этом случае равна нулю.
Все. Блок программы для движения между любыми двумя корзинами готов.
Для упрощения объяснения дальнейшей логики программы, считается, что существует отдельный блок выгрузки кубика в нужную корзину.
Сейчас, можно сказать, что алгоритм работы с одним кубиком будет звучать как:
- определить цвет кубика
- определить корзину, куда везти кубик
- переместиться к нужной корзине
- выгрузить кубик
Поскольку для того, чтобы переместиться к нужной корзине, программе нужно знать и корзину, где робот сейчас находиться, то имеет смысл завести для текущей и новой корзины отдельные переменные. Значение из переменной
BinTo
будет записываться в переменную BinFrom после момента выгрузки кубика, так что в следующей итерации оно будет использоваться для прокладки нового маршрута:Для определения корзины, куда вести кубик, будут использоваться переменные
RED, GREEN, BLUE
, в которые будут записаны номера соответствующих корзин. Эти переменные будут задавать значение переменной BinTo
во время определения цвета кубика. Например, если кубик красный, то в переменную будет записываться значение из RED
.Теперь если перед циклом задать значения переменной
BinFrom
равное 0:то в первой итерации цикла это автоматически переместит робота из базового лагеря к нужной корзине (1-0=1 - одну линию надо пересечь, 3-0=3 - три линии надо пересечь).
Остается только на старте программы задать в
RED, GREEN
и BLUE
нужные номера ячеек (например, синяя/BLUE
корзина в ячейке 2) , и получившийся новый блок будет решать задачу раскладывания кубиков для определенной последовательности корзин.
Решение интересное, но не совсем лаконичное, мы использовали способ куда проще и на мой взгляд эффективнее и понятнее для маленьких детей. Мне бы не хотелось раскрывать все секреты, то готов поделиться своим решением задачи ровно как и конструкцией робота после всероссийского этапа.
ОтветитьУдалитьЭто на самом деле отлично, если у Вас получилось эффективнее и понятнее. Хотелось бы увидеть хотя бы скриншот (распространять не буду, даже среди детей :)
УдалитьА что является мерилом эффективности?
Я пытался вкладывать в решение такие параметры, как:
1. маленький размер исполняемого файла, так чтобы в блок могло уместиться 6 однотипных программ для каждой возможной раскладки корзин по цветам
2. Минимизация возможной ошибки. На соревнованиях ребята будут должны отлаживать и доделывать свою программу без вмешательства тренера, поэтому хотелось бы минимизировать возможную ошибку связанную с человеческим фактором при загрузке измененных версий программ на блок: ребятам после изменения нужно будет залить 6 одинаковых программ и не ошибиться.
Эффективнее тем, что метод хорошо понятен маленьким детям. По пункту 1 скажу, что у нас умещается 6 программ и еще 6 влезет. На счет 2 категорически согласен. Поэтому ребятам по факту надо будет в нашей программе правильно проставить значения в 2 местах, ну и соответсвенно продублировать во всех 6 программах. Скинул скриншот на почту =)
ОтветитьУдалить