Я бы представлял сетку в виде списка списков, введите [[Bool]]
. И я бы определил функцию, чтобы знать, заполнен ли элемент сетки:
type Grid = [[Bool]]
isFullAt :: Grid -> (Int, Int) -> Bool -- returns True for anything off-grid
Тогда я бы определил функцию для поиска соседей:
neighbors :: (Int, Int) -> [(Int, Int)]
Чтобы найти неполных соседей по point
, вы можете отфильтровать с помощью filter (not . isFullAt) $ neighbors point
.
На этом этапе я бы определил две структуры данных:
- Отобразить каждую точку на
Maybe Cost
- Храните все очки с известной стоимостью в куче
Инициализировать только с начальным квадратом A в куче, с нулевой стоимостью.
Затем выполните цикл следующим образом:
- Удалите квадрат минимальной стоимости из кучи.
- Если его еще нет на конечной карте, добавьте его и его стоимость
c
и добавьте в кучу всех неполных соседей со стоимостью c+1
.
Когда куча пуста, вы будете иметь стоимость всех достижимых точек и можете посмотреть B на конечной карте. (Этот алгоритм можно назвать «алгоритмом Дейкстры»; я забыл.)
Вы можете найти конечные карты в Data.Map
. Я предполагаю, что где-то в огромной библиотеке есть куча (приоритетная очередь), но я не знаю, где.
Надеюсь, этого достаточно, чтобы вы начали.