Я только начал новый проект, в котором я хотел бы, чтобы игровой мир состоял из процедурно сгенерированных локаций, связанных телепортами. После небольшого исследования я обнаружил, что это можно назвать «теорией графов» или «чертовски сложным», в зависимости от того, кто это обсуждает. К сожалению, я нашел очень мало информации о генерации графов; большинство инструментов, которые я видел, направлены на изучение существующих графиков.
Предполагая, что я правильно определил терминологию, мои требования таковы:
- просто - ни в одном месте (вершине) не должно быть телепорта (ребра), который соединяется обратно с самим собой, и при этом две вершины не должны иметь нескольких ребер, соединяющих их
- подключен - должна быть возможность перемещаться между любыми двумя вершинами в графе (хотя я не предвижу необходимости когда-либо находить путь; достаточно просто знать, что игрок может найти одну из них, если он выберет, достаточно)
- циклический - между любыми двумя вершинами должно быть несколько путей
- ненаправленный - все края могут перемещаться в любом направлении
- бесконечный - если игрок желает этого, он должен иметь возможность путешествовать бесконечно, с продолжением генерации графа по мере приближения к
его самымнеизведанным вершинам - локально конечный - степень вершины никогда не должна изменяться после того, как игрок посетил ее
- стабильно помечен - каждая вершина представляет местоположение, которое само будет процедурно генерироваться из начального числа; одно и то же семя должно быть назначено вершине независимо от того, по какому пути туда ходил игрок или насколько велик график, когда он это делает.
У меня были некоторые идеи (которые я еще не пытался реализовать) относительно использования локальных максимумов двумерного перлин-шума в качестве вершин (входные данные x и y могли бы использоваться в качестве его метки), но это кажется неуклюжим и слишком сложным.
Есть ли лучший способ для создания такого графика? Я занимаюсь разработкой на Python 2.6 с использованием Panda3D и numpy, и, конечно, хотел бы посмотреть на включение других библиотек, если они помогут с этой проблемой!
редактировать
Я думаю, что плохо справился с объяснением некоторых моих требований, так что пришло время иллюстрации! Надеюсь, это прояснит ситуацию.
Под стабильными метками я подразумеваю, например, то, что игрок А должен иметь возможность исследовать и находить, помимо прочего, циклический путь к их исходному месту и гору, похожую на кошку. Его игра теперь выглядит примерно так (вершины нумеруются с начальным и реберным порядком, в котором игрок проходил их). Он начал с вершины 8329 (зеленый), а гора Happycat - в вершине 6745 (синий).
Хороший друг Игрока A Игрок B - фанат кошек, поэтому он хочет показать это ей. Он дает ей корневое семя для своего мира и направления по более короткому маршруту на интересующую гору. Ее игра теперь должна выглядеть так:
Проблема, с которой я в настоящее время сталкиваюсь больше всего, заключается в том, «Как создать те же семена для Игрока B, если ее исследование не пошло по тому же пути?» Вот что привело меня к идее использования шума Перлина - пока используется один и тот же начальный корень, максимумы не будут двигаться, поэтому их координаты могут использоваться в качестве стабильных начальных вершин.
источник
Ответы:
Вы не можете сделать бесконечный граф. Ваша память конечна, поэтому число вершин и ребер также конечно. Что вы можете сделать, это сделать конечный граф, а затем добавить к нему больше. Вы, кажется, поняли это, но я думаю, что это важно четко указать, чтобы вы не пошли по тупиковому пути.
Вы должны быть очень осторожны, когда говорите о «крайних вершинах». Граф - это набор вершин, набор ребер и функция, которая связывает их. Не существует заданной геометрической интерпретации, если вы не примените ее. Например: обе эти картинки показывают один и тот же график. На первом изображении вершина 2 может рассматриваться как «самая внешняя» вершина, но во втором изображении вершина 2 не будет считаться «самой внешней». Если бы вы рассматривали три измерения, вы могли бы сказать, что все вершины являются «внешними».
Это означает, что у вас должна быть какая-то другая информация, чтобы вы могли знать, что такое «самая внешняя» вершина. Вы можете использовать (x, y) пары, так как это даст вам возможность легко визуализировать геометрическое представление, однако я не думаю, что вам нужно заходить так далеко. Из того, что вы говорите, все, что вам нужно знать, это то, какие вершины уже есть в графе.
Если вы запускаете это каждый раз, когда посещаете вершину:
ваш график будет соответствовать всем вашим требованиям, за исключением циклического. Я не знаю, нужна ли вам гарантия. Если вы это сделаете, то вы могли бы специально выбрать не посещенный узел и установить соединение, что гарантировало бы путь между текущим узлом и уже посещенным узлом, так как все не посещенные узлы подключены по крайней мере к одному посещенному узлу и, поскольку вы должны были посещенный узел, чтобы добраться туда, где вы находитесь, теперь есть как минимум два пути.
Это просто, потому что есть явная проверка для него, связанная, потому что все новые узлы получают по крайней мере одно соединение, локально конечные, потому что ребра добавляются только перед вашим посещением или при первом посещении, и только к не посещенным узлам. Технически это не ненаправленное, но функционально это то же самое, что вы создаете направленное ребро в обоих направлениях. Вы можете пометить узел как угодно, я использую случайное число, но вы можете добавить другие параметры в конструктор, один из которых будет вашим начальным числом.
источник
Один метод:
Я упустил много деталей, но это должно отражать общую идею. Возможно, вы захотите сохранить соседей в памяти, которые находятся на большем расстоянии от текущего местоположения, в зависимости от того, как много мировых расстояний между порталами, сколько доступно памяти и т. Д.
источник