View difference between Paste ID: ZKr1xEbF and K7KHr2hF
SHOW: | | - or go back to the newest paste.
1-
let findIndex2D (p:'A -> bool) (a:'A [,]) =  //finds index
1+
let findIndex2D (p:'A -> bool) (a:'A [,]) =
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
6+
let totalManhattanDistance board goal =
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
22+
let neighbors board (zeroX, zeroY) =
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)
29+
let notContainsTuple x list = not (List.forall (fun (b,g,f) ->
30
                                                    not (b = x)) list)
31
32
let notContainsList x list = not (List.exists ((=) x) list)
33
34
35
let Astar board goal =
36
    let gScore = 0
37
    let fScore = gScore + totalManhattanDistance board goal
38
    let startState = (board, gScore, fScore)
39
    let openSet = [startState]
40
    let closedSet = []
41-
    let rec find currentBoard CS OS GS =
41+
42
    let rec find currentBoard (CS : int[,] list) OS GS =
43
        if currentBoard = goal then GS
44
        else
45
            let zeroInd = findIndex2D ((=) 0) currentBoard
46
            let removedCurrent = List.tail OS
47
            let adjacentBoards = List.filter (fun elem ->
48
                                                 (notContainsList elem CS) && (notContainsTuple elem removedCurrent)) (neighbors currentBoard zeroInd)
49
            let adjacentStates = List.map (fun x ->
50
                                                    let newGS = GS + 1
51
                                                    let newFS = newGS + totalManhattanDistance x goal
52
                                                    (x, newGS, newFS)) adjacentBoards
53
            let newCS = currentBoard::CS
54
            let newOS = List.sortBy (fun (b,g,f) -> f) (List.append removedCurrent adjacentStates)
55-
    find board closedSet openSet gScore1)
55+
56
    find board closedSet openSet gScore