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

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

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

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

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 13 ноября 2011

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

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

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

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

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

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

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

1 голос
/ 13 ноября 2011

Дерево kd или quadtree - это хорошая структура данных для решения вашей проблемы.Особенно последний - это умный способ обратиться к сетке и уменьшить сложность 2d до сложности 1d.Quadtrees также используется во многих приложениях карт, таких как Bing и Google Maps.Вот хорошее начало: Nick quadtree пространственный индекс блог кривой Гильберта.

...