編輯賞金是關於我的後續問題重新:代碼的通用版本。按我的最後一個職位在這個線程,謝謝,JD有點幫助F-Sharping這個路徑查找代碼,請
大家好,
我只是試着端起我的一些C#2D路徑查找代碼到F#。但是我目前處於C#OO開發人員的'殭屍'之中,也可能試圖用我的F#來完全實現功能。因此,考慮到這段代碼,這可能是迄今爲止我寫的最不重要的F#,我希望將它作爲一段F#代碼的一些建議。 (對不起,如果這是有點太「做我的作業」,但我找不到一個很好的F#A *路徑查找樣本供參考)。
立即想到的一件事是:我過度使用if/else/elseif「functional」夠了嗎?
一些注意事項:
1)「去除」是一個簡單的工具函數,從列表
2)「nodeToPathNode」僅僅需要一個點在空間中刪除的元素,使一個路徑節點出它(添加親參考,和H,G & F(按照典型的A *))
EDIT(#1):我已經更新與給定的(沒有建議的代碼關於使它通用的一個,我會在稍後介紹)...只是一些人通過谷歌來到這裏,並將它的錯誤的格式和邏輯錯誤複製我的代碼。
完整,2D瓷磚具體的實現,可以在這裏找到:http://jdoig.net/blog/?p=81
EDIT(#2)或通用版本可以在這裏找到:http://jdoig.net/blog/?p=127
let rec pathFind (area:Map) goal start (openNodes:PathingNode list) (closedNodes:PathingNode list) =
let pointToPathNode = pointToPathNode openNodes.Head goal //localy specific version of nTPN
let rec checkNeighbours neighbours openNodeAcc= //Loop over list of neighbours accumalating a list of open nodes
match neighbours with
|[] -> openNodeAcc //When list of neighbours is exhausted return the open nodes.
|hd::tl ->
let checkNeighbours = checkNeighbours tl //localy specific version of cn
let node = {hd with parent = Some(openNodes.Head)}
if (List.exists (isShorter hd) openNodeAcc) then //if a higher costingnode is in open...
let shorterPath = remove openNodeAcc (nodePointEquals hd.point) //... remove it..
checkNeighbours (node::shorterPath)
elif not(List.exists (nodePointEquals hd.point) closedNodes) && not (List.exists (nodePointEquals hd.point) openNodeAcc) then //If path is not open or closed...
checkNeighbours (node::openNodeAcc)
else checkNeighbours openNodeAcc //Else carry on.
let neighbours =
area.GetNeighboursOf openNodes.Head.point //Get the neighbours of our current node (openNodes.Head) ...
|> List.filter isClear //...filter out collidable tiles...
|> List.map pointToPathNode //...for each neighbour we can walk to: generate a pathing node
let pathToGoal = List.tryFind (nodePointEquals goal) neighbours //Try and find the goal node in the walkable neighbours of this tile.
if pathToGoal.IsSome then pathToGoal //If we found our goal return it...
else
let nextSet =
checkNeighbours neighbours openNodes.Tail
|> List.sortBy(fun x -> x.f)
if nextSet.Length > 0 then
pathFind area goal start nextSet (nextSet.Head::closedNodes) //...Else carry on
else None
謝謝,
JD
謝謝布賴恩,那只是我之後的東西:¬) – jdoig 2010-08-22 11:04:51