Какой хороший алгоритм для создания лабиринта?

Предположим, вам нужен простой лабиринт 9X_algorithm-design на сетке N на M, с одним проходом и большим 9X_algorithm-design количеством тупиков, но он выглядит «правильно» (то 9X_maze есть, как будто кто-то сделал его вручную 9X_algorithm-design без слишком большого количества крошечных 9X_algorithms тупиков и всего тот). Есть ли известный 9X_algorithm способ сделать это?

76
0
9
Общее количество ответов: 9

Ответ #1

Ответ на вопрос: Какой хороший алгоритм для создания лабиринта?

Оказывается, существует 11 классических 9X_algorithm-design алгоритмов для создания «идеальных» лабиринтов. Лабиринт 9X_algorithm-design идеален, если у него одно и только одно 9X_algorithms решение. Вот несколько ссылок на каждый 9X_algorithm алгоритм в приблизительном порядке, в котором 9X_maze я предпочитаю.

  1. Kruskal's
  2. Prim's
  3. Recursive Backtracker
  4. Aldous-Broder
  5. Growing Tree
  6. Hunt-and-Kill
  7. Wilson's
  8. Eller's
  9. Recursive Division (предсказуемо)
  10. Sidewinder (предсказуемо)
  11. Binary Tree (некорректно)

Для получения дополнительной 9X_algorithms информации ознакомьтесь с mazelib на GitHub, библиотеке 9X_algorithm Python, реализующей все стандартные алгоритмы 9X_algorithm-design создания / решения лабиринтов.

70
2

  • Вы говорите, что здесь клеточный автомат создает идеальные лабиринты, но ваша библиотека утверждает обратное. Как придешь? https://github.com/theJo ...

Ответ #2

Ответ на вопрос: Какой хороший алгоритм для создания лабиринта?

От http://www.astrolog.org/labyrnth/algrithm.htm

Рекурсивный поиск с возвратом: Это в 9X_algorithm некоторой степени связано с методом решения 9X_algorithm рекурсивного возврата, описанным ниже, и 9X_algorithm-design требует стека до размера лабиринта. При 9X_algorithms вырезании будьте максимально жадными и всегда 9X_algorithm вырезайте незавершенный участок, если он 9X_algorithm находится рядом с текущей ячейкой. Каждый 9X_maze раз, когда вы переходите на новую ячейку, помещайте 9X_algorithms предыдущую ячейку в стек. Если рядом с текущей 9X_algorithm позицией нет незавершенных ячеек, вставьте 9X_algorithms стек в предыдущую позицию. Лабиринт готов, когда 9X_algorithm-design вы вытаскиваете все из стека. Этот алгоритм 9X_algorithm-design приводит к лабиринтам с максимально высоким 9X_maze фактором «реки», с меньшим количеством, но 9X_maze более длинными тупиками, и, как правило, с 9X_algorithm очень длинным и извилистым решением. Он 9X_maze работает довольно быстро, хотя алгоритм 9X_algorithm-design Прима немного быстрее. Рекурсивный поиск 9X_algorithm с возвратом не работает как сумматор стен, потому 9X_maze что в результате он приводит к тому, что 9X_algorithm путь решения следует за внешним краем, где 9X_maze вся внутренняя часть лабиринта прикреплена 9X_maze к границе одним стеблем.

Они производят только 9X_algorithm 10% тупиков

9X_Какой хороший алгоритм для создания лабиринта?_algorithm-design

— пример лабиринта, созданного 9X_algorithm этим методом.

46
0

Ответ #3

Ответ на вопрос: Какой хороший алгоритм для создания лабиринта?

Довольно простым решением может быть присвоение 9X_algorithms случайных весов ребрам графа и применение 9X_algorithm Kruskal's algorithm для поиска минимального остовного дерева.

Лучшее 9X_algorithm обсуждение алгоритмов создания лабиринтов: http://www.jamisbuck.org/presentations/rubyconf2011/index.html (было 9X_algorithm на HN пару дней назад).

28
3

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

Ответ #4

Ответ на вопрос: Какой хороший алгоритм для создания лабиринта?

Мой любимый способ - использовать алгоритм 9X_maze Краскала, но при случайном выборе и удалении 9X_maze ребер взвешивайте выбор в зависимости от 9X_algorithm-design типов ребер, с которыми он связан.

Варьируя 9X_algorithm-design веса для разных типов ребер, вы можете создавать 9X_maze лабиринты с множеством различных характеристик 9X_algorithm или "индивидуальностей". См. Мой 9X_algorithm пример здесь:

https://mtimmerm.github.io/webStuff/maze.html

9
0

Ответ #5

Ответ на вопрос: Какой хороший алгоритм для создания лабиринта?

Как ни странно, слегка изменив «канонические» правила 9X_algorithm-design и начав со случайной конфигурации, Conway's Game of Life, кажется, генерирует 9X_maze довольно красивые лабиринты!

(точное правило 9X_algorithms я не помню, но это очень простая модификация, направленная 9X_algorithm на «уплотнение» популяции клеток...)

5
0

Ответ #6

Ответ на вопрос: Какой хороший алгоритм для создания лабиринта?

Рекурсивный поиск с возвратом - самый простой 9X_maze для реализации алгоритм.

Вот реализация Java:

Здесь 9X_algorithms Cell - это класс, представляющий ячейку в 2D-сетке, а 9X_algorithms cells - это 2D-массив объектов Cell. Ячейка имеет логические 9X_algorithms переменные top, bottom, left и right, чтобы указать, у ячейки 9X_algorithm-design есть стены с этих сторон, логическая переменная 9X_maze посещена, чтобы проверить, прошли ли мы ее, и две 9X_maze целочисленные переменные row и col, чтобы указать 9X_maze ее положение в сетке.

Cell current = cells[0][0] , next; current.visited=true; do{ next = getNeighbour(current); if(next!=null){ removeWall(current , next); st.push(current); current = next; current.visited = true; } else { current = st.pop(); } } while (!st.empty()); private Cell getNeighbour(Cell cell){ ArrayList ara = new ArrayList<>(); if(cell.col>0 && !cells[cell.col-1][cell.row].visited) ara.add(cells[cell.col-1][cell.row]); if(cell.row>0 && !cells[cell.col][cell.row-1].visited) ara.add(cells[cell.col][cell.row-1]); if(cell.col0){ return ara.get(new Random().nextInt(ara.size())); }else{ return null; } } private void removeWall(Cell curr , Cell nxt){ if((curr.col == nxt.col) && (curr.row == nxt.row+1)){/// top curr.top=nxt.botttom=false; } if(curr.col==nxt.col && curr.row == nxt.row-1){///bottom curr.botttom = nxt.top = false; } if(curr.col==nxt.col-1 && curr.row==nxt.row ){///right curr.right = nxt.left = false; } if(curr.col == nxt.col+1 && curr.row == nxt.row){///left curr.left = nxt.right = false; } } 

3
0

Ответ #7

Ответ на вопрос: Какой хороший алгоритм для создания лабиринта?

Один из методов создания лабиринта - это 9X_maze рандомизированная версия алгоритма Прима.

Начните 9X_maze с сетки, полной стен. Выберите ячейку, отметьте 9X_algorithm-design ее как часть лабиринта. Добавьте стены камеры 9X_algorithm-design в список стен. Пока в списке есть стены:

Выберите 9X_algorithm-design случайную стену из списка. Если ячейка на 9X_algorithm-design противоположной стороне еще не в лабиринте:

(i) Сделайте 9X_algorithm стену проходом и отметьте ячейку на противоположной 9X_algorithm-design стороне как часть лабиринта.

(ii) Добавьте 9X_algorithm соседние стены камеры в список стен.

Если 9X_maze ячейка на противоположной стороне уже была 9X_algorithms в лабиринте, удалите стену из списка.

2
0

Ответ #8

Ответ на вопрос: Какой хороший алгоритм для создания лабиринта?

Вот алгоритм DFS, записанный как псевдокод:

создать 9X_algorithms CellStack (LIFO) для хранения списка местоположений 9X_algorithms ячеек
установить TotalCells = количество 9X_algorithm ячеек в сетке
случайным образом выберите 9X_algorithm-design ячейку и назовите ее CurrentCell
установить 9X_algorithms VisitedCells = 1

в то время как VisitedCells 9X_algorithm
если один или несколько найдены выберите 9X_maze один наугад
пробить стену между ним и CurrentCell 9X_algorithms
поместить местоположение CurrentCell в 9X_algorithm CellStack
сделать новую ячейку CurrentCell 9X_maze
добавить 1 в VisitedCells еще извлекать 9X_maze самую последнюю запись ячейки из CellStack 9X_algorithm
сделайте это CurrentCell конец endWhile

1
0

Ответ #9

Ответ на вопрос: Какой хороший алгоритм для создания лабиринта?

Я предпочитаю версию алгоритма рекурсивного 9X_algorithm-design деления. Подробно описано here.

Я дам краткий обзор:
Исходный алгоритм 9X_algorithm-design рекурсивного деления работает следующим 9X_algorithm образом. Сначала начните с пустой области 9X_algorithm для лабиринта. Добавьте одну прямую стену, чтобы 9X_algorithms разделить камеру надвое, и проделайте где-нибудь 9X_algorithms одно отверстие в этой стене. Затем рекурсивно 9X_algorithms повторяйте этот процесс для каждой из двух 9X_algorithms новых камер, пока не будет достигнут желаемый 9X_algorithms размер прохода. Это просто и хорошо работает, но 9X_algorithms есть очевидные узкие места, которые упрощают 9X_algorithm-design решение лабиринта.

Этот вариант решает 9X_algorithm эту проблему путем рисования случайных «изогнутых» стен, а 9X_algorithm не прямых, что делает узкие места менее 9X_algorithm-design очевидными.

1
0