Вы, вероятно, могли бы разработать алгоритмы для этого, которые являются второстепенными вариантами ряда алгоритмов создания случайных лабиринтов. Я предлагаю вариант, основанный на методе union-find.
Основная идея объединения-поиска состоит в том, чтобы, учитывая набор элементов, разделенных на непересекающиеся (непересекающиеся) подмножества, быстро определить, к какому разделу принадлежит конкретный элемент. «Объединение» объединяет два непересекающихся набора вместе, чтобы сформировать больший набор, «найти» определяет, к какому разделу принадлежит конкретный элемент. Идея состоит в том, что каждый раздел набора может быть идентифицирован конкретным элементом набора, поэтому вы можете формировать древовидные структуры, в которых указатели указывают от элемента к элементу к корню. Вы можете объединить два раздела (с произвольным элементом для каждого), сначала найдя корень для каждого раздела, а затем изменив (ранее нулевой) указатель для одного корня, чтобы он указывал на другой.
Вы можете сформулировать свою задачу как задачу о непересекающихся объединениях. Изначально каждая отдельная ячейка представляет собой отдельный раздел. Что вы хотите, так это объединять разделы, пока не получите небольшое количество разделов (не обязательно два) связанных ячеек. Затем вы просто выбираете один (возможно, самый большой) из разделов и рисуете его.
Для каждой ячейки вам понадобится указатель (изначально нулевой) для объединения. Вам, вероятно, понадобится битовый вектор, чтобы действовать как набор соседних ячеек. Первоначально каждая ячейка будет иметь набор из четырех (или восьми) соседних ячеек.
Для каждой итерации вы выбираете ячейку случайным образом, затем следуете по цепочке указателей, чтобы найти ее корень. В деталях из корня вы найдете набор его соседей. Выберите из него случайный элемент, затем найдите для него корень, чтобы идентифицировать соседний регион. Выполните объединение (укажите один корень на другой и т. д.), чтобы объединить две области. Повторяйте, пока не будете довольны одним из регионов.
При объединении разделов новый набор соседей для нового корня будет представлять собой набор симметричных разностей (исключающее ИЛИ) наборов соседей для двух предыдущих корней.
Вы, вероятно, захотите сохранить другие данные по мере роста своих разделов, например. размер - в каждом корневом элементе. Вы можете использовать это, чтобы более избирательно относиться к конкретному союзу и помочь решить, когда остановиться. Некоторая мера рассеяния ячеек в разделе может иметь значение, например. небольшое отклонение или стандартное отклонение (относительно большого количества клеток), вероятно, указывает на плотное пятно примерно круглой формы.
Когда вы закончите, вы просто просканируете все ячейки, чтобы проверить, является ли каждая из них частью выбранного вами раздела, чтобы создать отдельное растровое изображение.
В этом подходе, когда вы случайным образом выбираете ячейку в начале итерации, существует сильный уклон в сторону выбора больших разделов. Когда вы выбираете соседний раздел, вы также склоняетесь к выбору большего соседнего раздела. Это означает, что вы, как правило, довольно быстро получаете одну явно доминирующую каплю.
person
Steve314
schedule
27.08.2010