Определение того, захвачена ли точка (заключена) в сетке

У меня есть сетка (пример ниже), содержащая внешние стены (отмеченные как W), блоки окружения (E), открытое пространство (o) и активные точки (A). В настоящее время эта сетка хранится в [,] со всеми данными, связанными с данной точкой. Я пытаюсь определить, замкнута ли активная точка (определяется как неспособная достичь верхней части сетки, потому что она заблокирована блоками среды), но мне трудно найти простой способ решения этой проблемы. Я знаю, что мог бы реализовать A*, и это было бы более или менее легко со всем имеющимся кодом примеров, но я не думаю, что удар по производительности был бы действительно необходим или стоил бы для такой, казалось бы, тривиальной операции.

W--Top Of Grid--W
W---------------W
W-EEAEE-----EEE-W
WEEEEEEE-EEEEAEEW
WEEEEEEE--EEEEEEW
WEEEEEEEE-AEEEEEW
WWWWWWWWWWWWWWWWW

Буква A в третьей строке может нарисовать путь к вершине сетки, как и буква в последней строке, а буква в четвертой строке — нет. Меня не интересуют фактические пути, мне просто нужно определить, попал ли объект в ловушку или нет. Какое решение было бы оптимальным для этого проекта?

Что бы это ни стоило, это проект C # для пошаговой игры с сеткой, если это вообще помогает.

Заранее благодарим вас за любую помощь, которую вы можете предложить, это очень ценится.


person Kai Zohar    schedule 01.08.2012    source источник
comment
Если сетка близка к такой маленькой, снижение производительности будет почти нулевым, поэтому приступайте к реализации A*. Вы также можете выполнить простой поиск в ширину, но A* на самом деле не сложнее, чем BFS.   -  person BlueRaja - Danny Pflughoeft    schedule 02.08.2012
comment
Сетка значительно больше (может достигать 100x100 узлов), показанная сетка мала для удобства просмотра. Будет ли это по-прежнему применяться в этом масштабе?   -  person Kai Zohar    schedule 02.08.2012
comment
Я бы все же сказал, что это, вероятно, не будет проблемой, если только у вас не будет много активных очков. Просто установите эвристику на высоту сверху. Когда все это будет сделано, профилируйте свое приложение и посмотрите, не является ли поиск пути узким местом — если да, возможно, мы сможем придумать что-то более быстрое, но до тех пор не стоит тратить время на его оптимизацию.   -  person BlueRaja - Danny Pflughoeft    schedule 02.08.2012
comment
Большое тебе спасибо! Я попробую!   -  person Kai Zohar    schedule 02.08.2012


Ответы (1)


Думаю заливка из верхних сеток решит всю проблему. Залить сверху, потом проверить, какие "А" залиты :)

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

Вот алгоритм:

http://en.wikipedia.org/wiki/Flood_fill

из вики:

    Flood-fill (node, target-color, replacement-color):
 1. If the color of node is not equal to target-color, return.
 2. Set the color of node to replacement-color.
 3. Perform Flood-fill (one step to the west of node, target-color, replacement-color).
    Perform Flood-fill (one step to the east of node, target-color, replacement-color).
    Perform Flood-fill (one step to the north of node, target-color, replacement-color).
    Perform Flood-fill (one step to the south of node, target-color, replacement-color).
 4. Return.

и это выглядит так: (из вики)

Заливка

Короче:

  1. флуд из верхних сеток, где 'W' и 'E' блокируют флуд (как черные клетки на картинке)
  2. после затопления проверьте, сколько мест, содержащих «А», затоплено.
person lavin    schedule 02.08.2012
comment
Это было бы даже хуже, чем BFS, если бы не было много активных узлов. A* определенно предпочтительнее для большой сетки. - person BlueRaja - Danny Pflughoeft; 02.08.2012