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

9

Можно ли получить улей-подобную структуру, соединяющую все комнаты без слишком большого количества коридоров? (Слишком много из 3-4 комнат, идущих из одной комнаты)

Ниже приведен вывод о том, как выглядят мои комнаты, в основном они расположены случайно.

вывод сетки комнат, размещенных случайным образом

Что я надеюсь получить в коридоре.

http://i.imgur.com/9GUi6Yy.png

Blenderer
источник
Я не думаю, что 3 или 4 "слишком много коридоров". Особенно, если у вас в комнате 9 комнат. Кроме того, я не уверен, что вы имеете в виду под «ульевидной структурой», не могли бы вы уточнить, на что вы пытаетесь взглянуть?
fnord
Возможно, включите «готовую» карту, чтобы показать, что вы заинтересованы в том, чтобы иметь.
MichaelHouse
Ах да, я имел в виду максимум 3 или 4 корридера из каждой комнаты.
Блендер
Я добавил изображение того, над чем я работаю, до коридоров.
Блендер
2
Если у вас нет 3-х коридоров из каких-либо комнат, вы сможете сделать простое линейное соединение комнат, поэтому просто выберите один и соедините его с двумя ближайшими соседями, не соединенными.
Ник

Ответы:

6

Ну, самый простой способ, который я могу придумать, начинается с того, что все комнаты соединены хотя бы одним коридором:

  1. Начните с последней или первой комнаты.
  2. Возьмите случайную комнату на расстоянии 1 расстояние, которое еще не связано с какой-либо комнатой (все комнаты начинают отключаться, поэтому вы будете следить за этим по ходу дела).
  3. Если такой комнаты нет, пройдите на расстояние +1. Если можно проложить туннель над / под другой комнатой, это проще, если вы не хотите соединять коридоры.
  4. Проходите псевдослучайно, пока все комнаты не соединятся.

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

В качестве последнего шага вы можете добавить правила, которые бы изменили ваши результаты для соответствия различным ситуациям. Например, вы можете заметить, что любая комната с одним коридором по определению является тупиком; Вы можете сделать больше тупиков, или вы можете устранить их все, убедившись, что у всего есть как минимум 2 соединения. Вы можете сделать тупики иметь секретный проход. Вы могли бы убедиться, что комната босса - тупик. Вы можете убедиться, что ваша начальная комната тупиковая, но затем убедитесь, что вторая комната имеет минимум X соединений. До бесконечности.

Каждое предположение и правило могут радикально изменить внешний вид ваших уровней, но это часть веселья! Это должно, по крайней мере, дать вам комнаты, похожие на улья / пещеры.

BrianH
источник
Это довольно близко к алгоритму минимального связующего дерева Крускала - он изменяет условие в 2 с «еще не подключен к некоторой комнате» до «еще не подключен к тому же кластеру », что исправляет ошибку в правилах, описанных выше, где вы могли бы иметь Ситуация, когда каждая комната связана с какой-то комнатой, но темница в целом все еще образует несколько отключенных островов. Kruskal's гарантированно найдет график соединений с минимальной общей длиной коридора.
DMGregory
3

Просто постройте свои комнаты уже подключенными. Начните с одной комнаты, затем построите 1-3 коридора в другие комнаты. Затем повторяйте, пока не добавите достаточно комнат.

Николь Болас
источник
2

Поскольку эти комнаты представляют собой вершины графа, встроенные в 2-мерную плоскость, теоретически это можно сделать, решив задачу коммивояжера (что было бы хорошо только с несколькими комнатами). Очевидно, что простая эвристика будет в порядке и обеспечит разумную масштабируемость.

Вы вычисляете края (длины коридора) между всеми комнатами. Вы сортируете их по длине. Вы добавляете кратчайший коридор, если только он не создает цикл или не увеличивает степень вершины (комнаты) над желаемым максимальным значением (3-4) (повтор). Чтобы проверить циклы, вы можете применить UnionFind или сделать быстрый BFS на небольших данных.

AturSams
источник
Этот ответ лучше, чем принятый ответ. Должна сработать жадная стратегия выбора кратчайших соединительных коридоров. Чтобы избежать циклов, не подключайтесь к комнатам, к которым уже подключен коридор.
Желе ван Кампен
@JellevanCampen Спасибо. ;) У вас может быть два изолированных подключенных компонента. Так что вы, вероятно, захотите использовать объединение поиска или проверки с BFS, если два узла соединены.
AturSams
Ах да, вы правы об этом, мой плохой.
Желе ван Кампен