Определение, соответствует ли созданная игроком структура шаблону в трехмерной блочной игре

8

Отказ от ответственности: это один из тех страшных вопросов в стиле Minecraft, но я чувствую, что это больше вопрос структуры данных и алгоритмов

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

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

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

WillP
источник
1
В качестве примера, вы думаете о том, как шаблонировать структуры, такие как портал Minecraft?
замедленная
1
@ Даниэль На самом деле, я думаю, это был бы хороший пример. Хотя моей целью было бы иметь как угодно большую / сложную структуру. Порталы довольно просты.
WillP
1
Не ответ, а просто мысль - если структуры становятся сколь угодно большими, а список целевых структур (которые вы должны искать, чтобы найти совпадение) становится невероятно большим, это становится проблемой распознавания образов, такой как распознавание текста или речи. Затем вы переходите от сравнения грубой силы к статистическим методам, таким как скрытые марковские модели, обученные на ваших целевых структурах. Это было бы так круто.
Питер Мюллер
@Harikawashi О, чувак, это было бы очень круто. Хотя моя цель не является чем-то астрономически большим, я все равно могу это сделать, просто чтобы поиграть с этим. Спасибо!
WillP

Ответы:

10

Если честно, я бы взял простое решение.

Сделайте матрицу, которая определяет структуру. Всякий раз, когда блок изменяется, попытайтесь применить эту матрицу ко всем местоположениям, которые могли создать новую структуру. Это будет ширина * глубина * высота местоположения, так как игрок мог закончить любую точку на структуре, но это не должно быть слишком плохо, потому что большинство из этих мест собираются рано выходить, когда первая проверка не удалась.

По сути, у вас есть 3D-матрица, и вы сравниваете ее с другой 3D-матрицей с кучей смещений.

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

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

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

ZorbaTHut
источник
3
Вы правы. Грубое принуждение действительно не должно быть серьезной проблемой производительности. Я чувствую, что попал в ловушку преждевременной оптимизации. Спасибо за ваше понимание.
WillP
0

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

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

Что касается структуры данных, то подойдет простой вектор или, возможно, пользовательская структура данных.

Интересный вопрос.

Avlagrath
источник