четверг, 14 марта 2013 г.

Робот для состязаний: "Батик". Часть VI

Если рассматривать состязания основной категории 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. При этом знак результирующего значения показывает в какую сторону нужно двигаться роботу: если результат положительный, то вперед; если результат отрицательный, то назад.

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


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


Все. Блок программы для движения между любыми двумя корзинами готов.


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


Сейчас, можно сказать, что алгоритм работы с одним кубиком будет звучать как:
  1. определить цвет кубика
  2. определить корзину, куда везти кубик
  3. переместиться к нужной корзине
  4. выгрузить кубик
Для пяти кубиков данный алгоритм повториться 5 раз - имеет смысл расположить его внутри соответствующего цикла.

Поскольку для того, чтобы переместиться к нужной корзине, программе нужно знать и корзину, где робот сейчас находиться, то имеет смысл завести для текущей и новой корзины отдельные переменные. Значение из переменной BinTo будет записываться в переменную BinFrom после момента выгрузки кубика, так что в следующей итерации оно будет использоваться для прокладки нового маршрута:


Для определения корзины, куда вести кубик, будут использоваться переменные RED, GREEN, BLUE, в которые будут записаны номера соответствующих корзин. Эти переменные будут задавать значение переменной BinTo во время определения цвета кубика. Например, если кубик красный, то в переменную будет записываться значение из RED.


Теперь если перед циклом задать значения переменной BinFrom равное 0:


то в первой итерации цикла это автоматически переместит робота из базового лагеря к нужной корзине (1-0=1 - одну линию надо пересечь, 3-0=3 - три линии надо пересечь).

Остается только на старте программы задать в RED, GREEN и BLUE нужные номера ячеек (например, синяя/BLUE корзина в ячейке 2) , и получившийся новый блок будет решать задачу раскладывания кубиков для определенной последовательности корзин.

3 комментария:

  1. Решение интересное, но не совсем лаконичное, мы использовали способ куда проще и на мой взгляд эффективнее и понятнее для маленьких детей. Мне бы не хотелось раскрывать все секреты, то готов поделиться своим решением задачи ровно как и конструкцией робота после всероссийского этапа.

    ОтветитьУдалить
    Ответы
    1. Это на самом деле отлично, если у Вас получилось эффективнее и понятнее. Хотелось бы увидеть хотя бы скриншот (распространять не буду, даже среди детей :)

      А что является мерилом эффективности?

      Я пытался вкладывать в решение такие параметры, как:
      1. маленький размер исполняемого файла, так чтобы в блок могло уместиться 6 однотипных программ для каждой возможной раскладки корзин по цветам
      2. Минимизация возможной ошибки. На соревнованиях ребята будут должны отлаживать и доделывать свою программу без вмешательства тренера, поэтому хотелось бы минимизировать возможную ошибку связанную с человеческим фактором при загрузке измененных версий программ на блок: ребятам после изменения нужно будет залить 6 одинаковых программ и не ошибиться.

      Удалить
  2. Эффективнее тем, что метод хорошо понятен маленьким детям. По пункту 1 скажу, что у нас умещается 6 программ и еще 6 влезет. На счет 2 категорически согласен. Поэтому ребятам по факту надо будет в нашей программе правильно проставить значения в 2 местах, ну и соответсвенно продублировать во всех 6 программах. Скинул скриншот на почту =)

    ОтветитьУдалить

Related Posts Plugin for WordPress, Blogger...