Advertisement
Guest User

Untitled

a guest
May 13th, 2014
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 2.56 KB | None | 0 0
  1. let findIndex2D (p:'A -> bool) (a:'A [,]) =  //finds index
  2.   a |> Array2D.mapi (fun x y v -> x,y,v)
  3.     |> Seq.cast<int*int*'A>
  4.    |> Seq.pick (fun (x,y,v) -> if p v then Some (x,y)  else None)
  5.  
  6. let totalManhattanDistance board goal = //manhatten distance for every tile for Fscore
  7.    let manhattanDistance (x1, y1) (x2, y2) =
  8.        abs(x1 - x2) + abs (y1 - y2)
  9.    board |> Array2D.mapi (fun x y v -> manhattanDistance (x, y)
  10.                                        <| findIndex2D ((=) v) goal)
  11.          |> Seq.cast<int>         // flatten
  12.          |> Seq.reduce (+)
  13.  
  14. let swap (arr : int[,]) i1 i2 =
  15.    let map i j v =
  16.        match (i,j) with
  17.        | t when t = i1 -> arr.[fst i2, snd i2]
  18.        | u when u = i2 -> arr.[fst i1, snd i1]
  19.        | _ -> v
  20.    arr |> Array2D.mapi map
  21.  
  22. let neighbors board (zeroX, zeroY) =  // gets every neighbor nodes given the empty "0" tile and the starting board
  23.    let (x,y) = findIndex2D ((=) 0) board
  24.    [if x > 0 then yield swap board (zeroX,zeroY) (zeroX - 1, zeroY)
  25.     if x < Array2D.length1 board - 1 then yield swap board (zeroX,zeroY) (zeroX + 1, zeroY)
  26.     if y > 0 then yield swap board (zeroX,zeroY) (zeroX, zeroY - 1)
  27.     if y < Array2D.length2 board - 1 then yield swap board (zeroX,zeroY) (zeroX, zeroY + 1)]
  28.  
  29. let notContainsTuple (b,g,f) list = not (List.exists ((=) b) list)
  30.  
  31. let notContainsList x list = not (List.exists ((=) x) list)
  32.  
  33.  
  34. let Astar board goal =
  35.    let gScore = 0
  36.    let fScore = gScore + totalManhattanDistance board goal
  37.    let startState = (board, gScore, fScore)
  38.    let openSet = [startState]
  39.    let closedSet = []
  40.    
  41.    let rec find currentBoard CS OS GS =
  42.        if currentBoard = goal then GS
  43.        else
  44.            let zeroInd = findIndex2D ((=) 0) currentBoard
  45.            let removedCurrent = List.tail OS
  46.            let adjacentBoards = List.filter (fun elem ->
  47.                                                 (notContainsList elem CS) && (notContainsTuple elem removedCurrent)) (neighbors currentBoard zeroInd)
  48.            let adjacentStates = List.map (fun x ->
  49.                                                    let newGS = GS + 1
  50.                                                    let newFS = newGS + totalManhattanDistance x goal
  51.                                                    (x, newGS, newFS)) adjacentBoards
  52.            let newCS = currentBoard::CS
  53.            let newOS = List.sortBy (fun (b,g,f) -> f) (List.append removedCurrent adjacentStates)
  54.            find (List.head newOS) newCS newOS (GS + 1)
  55.    find board closedSet openSet gScore1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement