Разреженная (псевдо) Бесконечная сеточная структура данных для веб-игры

#algorithm #web-applications #data-structures #sparse-matrix

#алгоритм #веб-приложения #структуры данных #разреженная матрица

Вопрос:

Я рассматриваю возможность создания игры, действие которой разворачивается на практически бесконечной сетке.

  • Сетка очень разреженная. Определенные небольшие области с относительно высокой плотностью. Относительно немного изолированных непустых ячеек.
  • Объем используемой сетки слишком велик для наивной реализации, но, вероятно, маловат по стандартам «больших данных» (я не пытаюсь отобразить Интернет или что-то в этом роде)
  • Это должно быть легко сохранить.

Вот операции, которые я, возможно, захочу выполнить (достаточно эффективно) с этой сеткой:

  • Запросите некоторую небольшую прямоугольную область ячеек и все их содержимое (текущее местоположение игрока)
  • Устанавливайте отдельные ячейки или выделяйте небольшие области (игрок делает ход)
  • Запросите приблизительную форму или контур / силуэт некоторых более крупных прямоугольных областей (карта мира или предварительный просмотр региона)
  • Найдите несколько областей с приблизительно заданной плотностью (место появления игрока)
  • Приблизительный кратчайший путь через промежутки, состоящие не более чем из нескольких небольших постоянных пустых пространств за переход (часто можно быть плохим приближением, но не нормально продолжать поиск в неправильном направлении)
  • Приблизительная выпуклая оболочка для области

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

Ребята, какой совет вы можете мне дать по реальной реализации этого? Как бы вы это сделали, если бы не было ограничений веб-приложения? Как бы вы изменили это, если бы они были?

Всем большое спасибо!

Комментарии:

1. K-d деревья или квадратичные деревья — это структуры данных, которые поддерживают разреженные сетки с запросами ближайших соседей и диапазона. Однако я не знаю, будут ли они нормально работать для плотностей, путей и оболочек.

2. Это входит в игру?! Я думал, что такого рода вещи достаточно приятны для работы, но я никогда не рассматривал возможность преобразования своей работы во что-то, что звучит как TRON. Удачи с этим!

Ответ №1:

Я думаю, вы можете сделать все, используя quadtrees, как предлагали другие, и, возможно, несколько дополнительных структур данных. Вот немного больше деталей:

  • Запрос содержимого ячейки, установка содержимого ячейки: это основные операции с деревом квадратиков.
  • Приблизительная форма / абрис: учитывая прямоугольник, спуститесь на достаточное количество ступеней в пределах квадрата, чтобы большинство ячеек были пустыми, и сделайте непустые вложенные ячейки на этом уровне черными, остальные — белыми.
  • Регион с приблизительно заданной плотностью: если плотность, которую вы ищете, высока, тогда я бы поддерживал отдельный индекс всех объектов на вашей карте. Возьмите случайный объект и проверьте плотность вокруг этого объекта в quadtree. Большинство объектов будут находиться вблизи областей с высокой плотностью, просто потому, что в областях с высокой плотностью много объектов. Если плотность вблизи выбранного вами объекта не та, которую вы искали, выберите другой.

    Если вы ищете места с низкой плотностью, то просто выберите случайные местоположения на карте — учитывая, что это разреженная карта, это обычно должно дать вам места с низкой плотностью. Опять же, если это не сработает правильно, попробуйте еще раз.

  • Приблизительный кратчайший путь: если это не слишком частая операция, то создайте приблизительный график области «между» начальной точкой A и конечной точкой B, для некоторого подходящего определения between (возможно, квадрат, содержащий круг с серединой AB в качестве центра и диаметром 1,5 * AB в качестве, за исключением случаев, когда этот диаметр меньше определенного минимума, в этом случае … поэкспериментируйте). Создайте сетку того же типа, которую вы использовали бы для приблизительной формы / контура, затем создайте (скажем) триангуляцию черных точек по Делоне. Создайте кратчайший путь на этом графике, затем наложите его на реальную карту и уточните путь до того, который имеет смысл, учитывая реальную карту. Возможно, вам придется переделать это на нескольких разных уровнях уточнения — начните с очень приблизительного графика, затем «увеличьте», взяв две точки, которые вы получили с более высокого уровня, в качестве начальной и конечной точек, и повторите.

    Если вам нужно делать это очень часто, вы захотите поддерживать этот тип графика для всей карты вместо того, чтобы восстанавливать его каждый раз. Хотя это может быть дорого.

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

Я не уверен, что это было бы легко поместить в реляционную базу данных; хранилище на основе файлов могло бы работать, но было бы непрактично, чтобы операция записи была одновременной с чем-либо еще, что вы, вероятно, захотите, если хотите, чтобы это число увеличилось до разумного числа игроков (на мир / карту, если существует несколько миров / карт). Я думаю, что в этом случае вам, вероятно, лучше всего поддерживать отдельный процесс … и даже тогда заставить его должным образом учитывать многопоточность будет головной болью.

Ответ №2:

kd-дерево или quadtree — хорошая структура данных для решения вашей проблемы. Особенно последнее, это умный способ обратиться к сетке и уменьшить сложность 2d до сложности 1d. Quadtrees также используется во многих приложениях maps, таких как bing и Google Maps. Вот хорошее начало: Блог Nick quadtree spatial index hilbert curve.