Задача ханойских башен
Одна из популярных головоломок XIX века. Даны три стержня, на один из которых нанизаны несколько колец, причём кольца отличаются размером и лежат меньшее на большем. Задача состоит в том, чтобы перенести пирамиду из колец за наименьшее число ходов на другой стержень. За один раз разрешается переносить только одно кольцо, причём нельзя класть большее кольцо на меньшее.
Существует несколько подходов к решению. В данной публикации приведено решение с использованием рекурсивного метода.
Суть метода. Пусть есть 3 стержня (Стержень1, Стержень2, Стержень3). Переложим n-1 дисков с Стержень1 на Стержень3. Затем перенесём оставшийся (самый большой) диск с Стержень1 на Стержень2. Наконец, снова, переложим n-1 дисков с Стержень3 на Стержень2 (поверх того, самого большого диска). Таким образом, задача по переносу n дисков с Стержень1 на Стержень2 решена, а её код на 1С будет иметь вид:
Процедура ПеренестиДиски (НомерДиска,Стержень1,Стержень2,Стержень3) // переложить n-й диск с Стержень1 на Стержень2, используя Стержень3
Если НомерДиска <= 0 Тогда // (0) дисков нет - конец
Возврат;
КонецЕсли;
ПеренестиДиски(НомерДиска-1,Стержень1,Стержень3,Стержень2); // перекладываем n-1 диск с Стержень1 на Стержень3
Сообщить(Стержень1+"->"+Стержень2); // (1) переносим 1 диск c Стержень1 на Стержень2
ПеренестиДиски(НомерДиска-1,Стержень3,Стержень2,Стержень1); // перекладываем n-1 диск с Стержень3 на Стержень2
Возврат; // (2) конец
КонецПроцедуры
Реализация
Для начала "нарисуем" внешний вид ханойских башен используя HTML и CSS, и создадим метод который будет передвигать указанный диск на заданный стержень:
Далее сгенерируем получившийся код в форме 1С, используя Поле HTML Документа.
Для работы с HTML документами в 1С формах существует элемент управления Поле HTML Документа. HTML документ может быть сформирован в элементе управления программно, загружен из ресурса, указываемого через URL, или же загружен из макета типа HTML-документ.
В нашем случае HTML форма будет генерироваться при открытии формы:
В секции <script></script> описана функция MoveDisk(disk, st), которая принимает значение параметров из 1с, и двигает диски согласно этим параметрам.
Теперь перепишем процедуру "Переставить", таким образом, чтобы:
- каждый следующий шаг происходил по нажатию на кнопку формы;
- в алгоритме происходил вызов js функции MoveDisk.
Процедура примет вид:
&НаКлиенте
Процедура Переставить(ОбъектWindow,НомерДиска,Стержень1,Стержень2,Стержень3,ТекущийШаг)
Если НомерДиска <= 0 Тогда
Возврат;
КонецЕсли;
Переставить(ОбъектWindow,НомерДиска-1,Стержень1,Стержень3,Стержень2,ТекущийШаг);
Если ТекущийШаг = СледующийШаг Тогда
ОбъектWindow.MoveDisk("disk" + НомерДиска,Стержень2);
ТекущийШаг = ТекущийШаг +1;
Возврат;
КонецЕсли;
ТекущийШаг = ТекущийШаг +1;
Переставить(ОбъектWindow,НомерДиска-1,Стержень3,Стержень2,Стержень1,ТекущийШаг);
Возврат;
КонецПроцедуры
Вызов функции "Переставить" происходит по нажатию на кнопку:
&НаКлиенте
Процедура ВыполнитьПерестановку(Команда)
ОбъектWindow = Элементы.ПолеHTMLДокумента.Документ.parentWindow; // IE-only
Если ОбъектWindow = Неопределено Тогда
ОбъектWindow = Элементы.ПолеHTMLДокумента.Документ.defaultView; // Другие браузеры
КонецЕсли;
ТекущийШаг = 1;
Переставить(ОбъектWindow,КоличествоБашен,"st1","st2","st3",ТекущийШаг);
СледующийШаг = СледующийШаг +1;
КонецПроцедуры
ОбъектWindow является корневым объектом JavaScript. Все объекты JavaScript, а также переменные и функции определяемые пользователем хранятся в объекте window.
В контексте данного объекта и хранится javascript функция MoveDisk(disk, st).
Таким образом, используя связку html css javascript, реализовано решение головоломки в элементе формы 1с Поле HTML Документа.
Ссылки:
1с + js:
Ханойские башни:
http://synset.com/ai/ru/search/Towers_of_Hanoi.html
Тестировалось на платформе 8.3.12.
Обработка с реализацией прикреплена.