Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 7th, 2012  |  syntax: None  |  size: 2.29 KB  |  hits: 11  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. module Tools
  2. open System
  3.  
  4. let sqr x = float(x * x)
  5.  
  6. let rec remove l predicate =
  7.     match l with
  8.     | [] -> []
  9.     | hd::tl -> if predicate(hd) then
  10.                     (remove tl predicate)
  11.                  else
  12.                      hd::(remove tl predicate)
  13.  
  14. let loadMap path =
  15.      IO.File.ReadAllText(path).Split(';')
  16.         |> Array.filter(fun s -> s<> String.Empty)
  17.         |> Array.map(fun s-> Int32.Parse(s.Replace(";",String.Empty)))                  
  18.  
  19. (* The A* Algorithm *)
  20. let rec aStar value g h neighbors goal start (openNodes: 'a list) (closedNodes: 'a list) =
  21.     let f x:float = (g x)+(h x) (*f will be the value we sort open nodes buy *)
  22.     let isShorter nodeA nodeB = nodeA = nodeB && f nodeA < f nodeB
  23.            
  24.     let rec checkNeighbors neighbors openNodeAcc =
  25.         match neighbors with
  26.         | [] -> openNodeAcc
  27.         | currentNode::rest ->
  28.             let likeCurrent = fun n -> (value n) = (value currentNode)
  29.             let containsCurrent = likeCurrent |> List.exists (* list contains likeCurrent *)
  30.             let checkNeighbors = checkNeighbors rest
  31.  
  32.             (* The current node is a shorter path than than one we already have. *)
  33.             if openNodeAcc |> List.exists (isShorter currentNode) then
  34.                 (* So remove the old one... *)    
  35.                 let shorterPath = remove openNodeAcc likeCurrent
  36.                 (* ...and carry on with the new one. *)                
  37.                 checkNeighbors  (currentNode::shorterPath)
  38.             (* The current node has not been queried *)
  39.             elif not(containsCurrent closedNodes) && not(containsCurrent openNodeAcc) then
  40.                 checkNeighbors (currentNode::openNodeAcc) (* So add it to the open set *)
  41.             else checkNeighbors openNodeAcc (* else carry on *)
  42.  
  43.     let nodes = neighbors openNodes.Head (* The next neighbors to work on *)
  44.    
  45.     let pathToGoal = nodes |> List.tryFind (fun x -> (value x) = goal)
  46.     if pathToGoal.IsSome then pathToGoal (* Found the goal! *)
  47.     else
  48.         let nextSet =
  49.             checkNeighbors nodes openNodes.Tail
  50.             |> List.sortBy f  (* sort open set by node.f *)
  51.         if nextSet.Length > 0 then (* Carry on pathfinding *)
  52.             aStar value g h neighbors goal start nextSet (nextSet.Head::closedNodes)
  53.         else None (* if there are no open nodes pathing has failed *)