У меня есть простое дерево, определяется таким образом:Что случилось с моим кодом обхода дерева?
type BspTree =
| Node of Rect * BspTree * BspTree
| Null
я могу получить коллекцию листьев узлов (комнаты в моем дереве «темнице»), как это, и это похоже на работу:
let isRoom = function
| Node(_, Null, Null) -> true
| _ -> false
let rec getRooms dungeon =
if isRoom dungeon then
seq { yield dungeon }
else
match dungeon with
| Node(_, left, right) ->
seq { for r in getRooms left -> r
for r in getRooms right -> r }
| Null -> Seq.empty
Но теперь я пытаюсь получить комнаты с узлами сестринского листа, чтобы я мог соединить их с коридорами, и я терплю неудачу (как это часто бывает). Вот моя попытка:
let rec getCorridors dungeon =
match dungeon with
| Null -> failwith "Unexpected null room"
| Node(_, left, right) ->
match left, right with
| Null, Null -> Seq.empty
| Node(leftRect, _, _), Node(rightRect, _, _) ->
if isRoom left && isRoom right
then seq { yield makeCorridor leftRect rightRect }
else seq { for l in getCorridors left -> l
for r in getCorridors right -> r }
| _ -> failwith "Unexpected!"
Я только что закончил с пустой секцией. В любом случае, это все больно моему мозгу, и я знаю, что маловероятно, что кто-то прольет его, но я подумал, что это не помешает спросить.
это только предположение .. если вы используете выход ! когда вы рекурсивно называете getCorridors. Это объединит несколько возвращенных элементов последовательности в одну последовательность. – Jimmy
Дерево не является подходящей структурой для организации комнат. Вам нужен граф. Это может быть какой-то простой контейнер, например массив или список комнат, но каждая комната должна иметь все возможные выходы, которые ведут к другим комнатам в одном контейнере. Эти выходы могут быть организованы на карте с ключом, объединенным из комнаты и типа выхода (север, восток, юг, запад, вверх, вниз ... добавьте больше, если хотите), а стоимость - еще одна комната. – Dialecticus
Вы опустили makeCorridor, может ли оттуда быть свободным? –