Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 如何将参数作为联合大小写值返回?_F# - Fatal编程技术网

F# 如何将参数作为联合大小写值返回?

F# 如何将参数作为联合大小写值返回?,f#,F#,如何将参数作为联合大小写值返回 我有以下功能: let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list)) (redPiece:RedPiece) = let yIncrementValue = -1 let minY = 0 match redPiece with | RedPiece.RedChecker rc -> let positi

如何将参数作为联合大小写值返回

我有以下功能:

let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list))  (redPiece:RedPiece) =

    let yIncrementValue = -1
    let minY = 0

    match redPiece with
    | RedPiece.RedChecker rc -> 
       let position = rc.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
       | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

    | RedPiece.RedKing rk -> 
       let position = rk.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
       | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
match redPiece with
| RedPiece.RedChecker rc -> 
   let position = rc.Position |> jump blackChecker.Position yIncrementValue
   match position with
   | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
   | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
   | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

| RedPiece.RedKing rk -> 
   let position = rk.Position |> jump blackChecker.Position yIncrementValue
   match position with
   | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
   | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
   | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
(* Types *)
type North = NorthEast | NorthWest
type South = SouthEast | SouthWest

type Direction = 
    | NorthEast 
    | NorthWest
    | SouthEast 
    | SouthWest

type Position =     { X:int; Y:int }

type BlackChecker = { Position:Position }
type RedChecker =   { Position:Position }
type BlackKing =    { Position:Position }
type RedKing =      { Position:Position }

type Checker =
    | BlackChecker of BlackChecker
    | RedChecker   of RedChecker
    | BlackKing    of BlackKing
    | RedKing      of RedKing

type King = 
    | BlackKing of BlackKing
    | RedKing of RedKing

type RedPiece = 
    | RedChecker of RedChecker 
    | RedKing of RedKing

(* Functions *)
let rec remove item list = list |> List.filter (fun x -> x <> item)

let setRowPosition y1 y2 y3 index =
    match index with 
    | x when x < 4 -> { X=x; Y=y1 }
    | x when x < 8 -> { X=x-4; Y=y2 }
    | _            -> { X=index-8; Y=y3 }

let initializeBlack () =
    let setPosition index =
        index |> setRowPosition 7 6 5

    let blackCheckers = List.init 12 setPosition |> List.map (fun pos -> { BlackChecker.Position= { X=pos.X; Y=pos.Y } })
    blackCheckers

let initializeRed () =
    let setPosition index =
        index |> setRowPosition 0 1 2

    let redCheckers =   List.init 12 setPosition |> List.map (fun pos -> { RedChecker.Position= { X=pos.X; Y=pos.Y } })
    redCheckers

let set (x, y) positions (position:Position) =
    match not (positions |> List.exists (fun pos -> pos = { X=x; Y=y })) with
    | true -> { X=x; Y=y }
    | false -> position

let moveBlack direction positions (checker:BlackChecker) =
    let position = checker.Position

    match direction with
    | North.NorthEast -> { BlackChecker.Position= (positions, position) ||> set ((position.X + 1), (position.Y + 1 )) } 
    | North.NorthWest -> { BlackChecker.Position= (positions, position) ||> set ((position.X - 1), (position.Y + 1 )) }

let moveRed direction positions (checker:RedChecker) =
    let position = checker.Position

    match direction with
    | South.SouthEast -> { RedChecker.Position= (positions, position) ||> set ((position.X + 1), (position.Y - 1 )) }
    | South.SouthWest -> { RedChecker.Position= (positions, position) ||> set ((position.X - 1), (position.Y - 1 )) }

let moveKing direction positions (king:King) =

    let position = match king with
                   | King.BlackKing bk -> bk.Position
                   | King.RedKing   rk -> rk.Position

    let result = match direction with
                 | NorthEast -> (positions, position) ||> set ((position.X + 1), (position.Y + 1 ))
                 | NorthWest -> (positions, position) ||> set ((position.X - 1), (position.Y + 1 ))
                 | SouthEast -> (positions, position) ||> set ((position.X + 1), (position.Y - 1 ))
                 | SouthWest -> (positions, position) ||> set ((position.X - 1), (position.Y - 1 ))

    match king with
    | King.BlackKing _ -> King.BlackKing { BlackKing.Position= result }
    | King.RedKing   _ -> King.RedKing   { RedKing.Position=   result }

let jump target yDirection source =
    let updateX value = { X=target.X + value
                          Y=target.Y + yDirection }
    match source with
    | position when position.Y + yDirection = target.Y &&
                    position.X + 1 = target.X -> updateX 1

    | position when position.Y + yDirection = target.Y &&
                    position.X - 1 = target.X -> updateX -1
    | _ -> source

let jumpRed ((redChecker:RedChecker), (redCheckers:RedChecker list)) (blackChecker:BlackChecker) =

    let yIncrementValue = 1
    let maxY = 7
    let position = blackChecker.Position |> jump redChecker.Position yIncrementValue

    match position with
    | pos when pos = blackChecker.Position -> BlackChecker { blackChecker with Position= position }, redCheckers
    | pos when pos.Y = maxY                -> Checker.BlackKing { BlackKing.Position=position }, redCheckers |> remove redChecker
    | _ -> BlackChecker { blackChecker with Position= position }, redCheckers |> remove redChecker

let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list))  (redPiece:RedPiece) =

    let yIncrementValue = -1
    let minY = 0

    match redPiece with
    | RedPiece.RedChecker rc -> 
       let position = rc.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
       | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

    | RedPiece.RedKing rk -> 
       let position = rk.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
       | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
[<Test>
let ``red king jumps checker``() =
    let blackChecker = { BlackChecker.Position= { X=1 ; Y=1 } }
    let target = (blackChecker, [blackChecker])

    RedKing { RedKing.Position= { X=0 ; Y=2 } } |> jumpBlack target
                                                |> fst
                                                |> should equal (RedPiece.RedKing { RedKing.Position= { X=2 ; Y=0 } })

[<Test>]
let ``black checker removed after being jumped``() =
    let target = { BlackChecker.Position= { X=1 ; Y=1 } }, []
    RedChecker { RedChecker.Position= { X=2 ; Y=2 } } |> jumpBlack target
                                                      |> snd
                                                      |> should equal []
[<Test>]
let ``red checker jumps black checker southeast``() =
    let blackChecker = { BlackChecker.Position= { X=3 ; Y=2 } }
    let target = blackChecker, [blackChecker]

    RedChecker { RedChecker.Position= { X=2 ; Y=3 } } |> jumpBlack target
                                                      |> fst
                                                      |> should equal (RedChecker { RedChecker.Position= { X=4 ; Y=1 } })
具体来说,我想将上述函数的这一部分重构为一个函数:

let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list))  (redPiece:RedPiece) =

    let yIncrementValue = -1
    let minY = 0

    match redPiece with
    | RedPiece.RedChecker rc -> 
       let position = rc.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
       | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

    | RedPiece.RedKing rk -> 
       let position = rk.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
       | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
match redPiece with
| RedPiece.RedChecker rc -> 
   let position = rc.Position |> jump blackChecker.Position yIncrementValue
   match position with
   | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
   | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
   | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

| RedPiece.RedKing rk -> 
   let position = rk.Position |> jump blackChecker.Position yIncrementValue
   match position with
   | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
   | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
   | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
(* Types *)
type North = NorthEast | NorthWest
type South = SouthEast | SouthWest

type Direction = 
    | NorthEast 
    | NorthWest
    | SouthEast 
    | SouthWest

type Position =     { X:int; Y:int }

type BlackChecker = { Position:Position }
type RedChecker =   { Position:Position }
type BlackKing =    { Position:Position }
type RedKing =      { Position:Position }

type Checker =
    | BlackChecker of BlackChecker
    | RedChecker   of RedChecker
    | BlackKing    of BlackKing
    | RedKing      of RedKing

type King = 
    | BlackKing of BlackKing
    | RedKing of RedKing

type RedPiece = 
    | RedChecker of RedChecker 
    | RedKing of RedKing

(* Functions *)
let rec remove item list = list |> List.filter (fun x -> x <> item)

let setRowPosition y1 y2 y3 index =
    match index with 
    | x when x < 4 -> { X=x; Y=y1 }
    | x when x < 8 -> { X=x-4; Y=y2 }
    | _            -> { X=index-8; Y=y3 }

let initializeBlack () =
    let setPosition index =
        index |> setRowPosition 7 6 5

    let blackCheckers = List.init 12 setPosition |> List.map (fun pos -> { BlackChecker.Position= { X=pos.X; Y=pos.Y } })
    blackCheckers

let initializeRed () =
    let setPosition index =
        index |> setRowPosition 0 1 2

    let redCheckers =   List.init 12 setPosition |> List.map (fun pos -> { RedChecker.Position= { X=pos.X; Y=pos.Y } })
    redCheckers

let set (x, y) positions (position:Position) =
    match not (positions |> List.exists (fun pos -> pos = { X=x; Y=y })) with
    | true -> { X=x; Y=y }
    | false -> position

let moveBlack direction positions (checker:BlackChecker) =
    let position = checker.Position

    match direction with
    | North.NorthEast -> { BlackChecker.Position= (positions, position) ||> set ((position.X + 1), (position.Y + 1 )) } 
    | North.NorthWest -> { BlackChecker.Position= (positions, position) ||> set ((position.X - 1), (position.Y + 1 )) }

let moveRed direction positions (checker:RedChecker) =
    let position = checker.Position

    match direction with
    | South.SouthEast -> { RedChecker.Position= (positions, position) ||> set ((position.X + 1), (position.Y - 1 )) }
    | South.SouthWest -> { RedChecker.Position= (positions, position) ||> set ((position.X - 1), (position.Y - 1 )) }

let moveKing direction positions (king:King) =

    let position = match king with
                   | King.BlackKing bk -> bk.Position
                   | King.RedKing   rk -> rk.Position

    let result = match direction with
                 | NorthEast -> (positions, position) ||> set ((position.X + 1), (position.Y + 1 ))
                 | NorthWest -> (positions, position) ||> set ((position.X - 1), (position.Y + 1 ))
                 | SouthEast -> (positions, position) ||> set ((position.X + 1), (position.Y - 1 ))
                 | SouthWest -> (positions, position) ||> set ((position.X - 1), (position.Y - 1 ))

    match king with
    | King.BlackKing _ -> King.BlackKing { BlackKing.Position= result }
    | King.RedKing   _ -> King.RedKing   { RedKing.Position=   result }

let jump target yDirection source =
    let updateX value = { X=target.X + value
                          Y=target.Y + yDirection }
    match source with
    | position when position.Y + yDirection = target.Y &&
                    position.X + 1 = target.X -> updateX 1

    | position when position.Y + yDirection = target.Y &&
                    position.X - 1 = target.X -> updateX -1
    | _ -> source

let jumpRed ((redChecker:RedChecker), (redCheckers:RedChecker list)) (blackChecker:BlackChecker) =

    let yIncrementValue = 1
    let maxY = 7
    let position = blackChecker.Position |> jump redChecker.Position yIncrementValue

    match position with
    | pos when pos = blackChecker.Position -> BlackChecker { blackChecker with Position= position }, redCheckers
    | pos when pos.Y = maxY                -> Checker.BlackKing { BlackKing.Position=position }, redCheckers |> remove redChecker
    | _ -> BlackChecker { blackChecker with Position= position }, redCheckers |> remove redChecker

let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list))  (redPiece:RedPiece) =

    let yIncrementValue = -1
    let minY = 0

    match redPiece with
    | RedPiece.RedChecker rc -> 
       let position = rc.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
       | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

    | RedPiece.RedKing rk -> 
       let position = rk.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
       | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
[<Test>
let ``red king jumps checker``() =
    let blackChecker = { BlackChecker.Position= { X=1 ; Y=1 } }
    let target = (blackChecker, [blackChecker])

    RedKing { RedKing.Position= { X=0 ; Y=2 } } |> jumpBlack target
                                                |> fst
                                                |> should equal (RedPiece.RedKing { RedKing.Position= { X=2 ; Y=0 } })

[<Test>]
let ``black checker removed after being jumped``() =
    let target = { BlackChecker.Position= { X=1 ; Y=1 } }, []
    RedChecker { RedChecker.Position= { X=2 ; Y=2 } } |> jumpBlack target
                                                      |> snd
                                                      |> should equal []
[<Test>]
let ``red checker jumps black checker southeast``() =
    let blackChecker = { BlackChecker.Position= { X=3 ; Y=2 } }
    let target = blackChecker, [blackChecker]

    RedChecker { RedChecker.Position= { X=2 ; Y=3 } } |> jumpBlack target
                                                      |> fst
                                                      |> should equal (RedChecker { RedChecker.Position= { X=4 ; Y=1 } })
如何重构上面重复的代码?

我被困在如何删除重复,仍然返回两种不同的联合类型(即红色棋盘格和红色国王)

域:

let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list))  (redPiece:RedPiece) =

    let yIncrementValue = -1
    let minY = 0

    match redPiece with
    | RedPiece.RedChecker rc -> 
       let position = rc.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
       | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

    | RedPiece.RedKing rk -> 
       let position = rk.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
       | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
match redPiece with
| RedPiece.RedChecker rc -> 
   let position = rc.Position |> jump blackChecker.Position yIncrementValue
   match position with
   | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
   | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
   | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

| RedPiece.RedKing rk -> 
   let position = rk.Position |> jump blackChecker.Position yIncrementValue
   match position with
   | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
   | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
   | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
(* Types *)
type North = NorthEast | NorthWest
type South = SouthEast | SouthWest

type Direction = 
    | NorthEast 
    | NorthWest
    | SouthEast 
    | SouthWest

type Position =     { X:int; Y:int }

type BlackChecker = { Position:Position }
type RedChecker =   { Position:Position }
type BlackKing =    { Position:Position }
type RedKing =      { Position:Position }

type Checker =
    | BlackChecker of BlackChecker
    | RedChecker   of RedChecker
    | BlackKing    of BlackKing
    | RedKing      of RedKing

type King = 
    | BlackKing of BlackKing
    | RedKing of RedKing

type RedPiece = 
    | RedChecker of RedChecker 
    | RedKing of RedKing

(* Functions *)
let rec remove item list = list |> List.filter (fun x -> x <> item)

let setRowPosition y1 y2 y3 index =
    match index with 
    | x when x < 4 -> { X=x; Y=y1 }
    | x when x < 8 -> { X=x-4; Y=y2 }
    | _            -> { X=index-8; Y=y3 }

let initializeBlack () =
    let setPosition index =
        index |> setRowPosition 7 6 5

    let blackCheckers = List.init 12 setPosition |> List.map (fun pos -> { BlackChecker.Position= { X=pos.X; Y=pos.Y } })
    blackCheckers

let initializeRed () =
    let setPosition index =
        index |> setRowPosition 0 1 2

    let redCheckers =   List.init 12 setPosition |> List.map (fun pos -> { RedChecker.Position= { X=pos.X; Y=pos.Y } })
    redCheckers

let set (x, y) positions (position:Position) =
    match not (positions |> List.exists (fun pos -> pos = { X=x; Y=y })) with
    | true -> { X=x; Y=y }
    | false -> position

let moveBlack direction positions (checker:BlackChecker) =
    let position = checker.Position

    match direction with
    | North.NorthEast -> { BlackChecker.Position= (positions, position) ||> set ((position.X + 1), (position.Y + 1 )) } 
    | North.NorthWest -> { BlackChecker.Position= (positions, position) ||> set ((position.X - 1), (position.Y + 1 )) }

let moveRed direction positions (checker:RedChecker) =
    let position = checker.Position

    match direction with
    | South.SouthEast -> { RedChecker.Position= (positions, position) ||> set ((position.X + 1), (position.Y - 1 )) }
    | South.SouthWest -> { RedChecker.Position= (positions, position) ||> set ((position.X - 1), (position.Y - 1 )) }

let moveKing direction positions (king:King) =

    let position = match king with
                   | King.BlackKing bk -> bk.Position
                   | King.RedKing   rk -> rk.Position

    let result = match direction with
                 | NorthEast -> (positions, position) ||> set ((position.X + 1), (position.Y + 1 ))
                 | NorthWest -> (positions, position) ||> set ((position.X - 1), (position.Y + 1 ))
                 | SouthEast -> (positions, position) ||> set ((position.X + 1), (position.Y - 1 ))
                 | SouthWest -> (positions, position) ||> set ((position.X - 1), (position.Y - 1 ))

    match king with
    | King.BlackKing _ -> King.BlackKing { BlackKing.Position= result }
    | King.RedKing   _ -> King.RedKing   { RedKing.Position=   result }

let jump target yDirection source =
    let updateX value = { X=target.X + value
                          Y=target.Y + yDirection }
    match source with
    | position when position.Y + yDirection = target.Y &&
                    position.X + 1 = target.X -> updateX 1

    | position when position.Y + yDirection = target.Y &&
                    position.X - 1 = target.X -> updateX -1
    | _ -> source

let jumpRed ((redChecker:RedChecker), (redCheckers:RedChecker list)) (blackChecker:BlackChecker) =

    let yIncrementValue = 1
    let maxY = 7
    let position = blackChecker.Position |> jump redChecker.Position yIncrementValue

    match position with
    | pos when pos = blackChecker.Position -> BlackChecker { blackChecker with Position= position }, redCheckers
    | pos when pos.Y = maxY                -> Checker.BlackKing { BlackKing.Position=position }, redCheckers |> remove redChecker
    | _ -> BlackChecker { blackChecker with Position= position }, redCheckers |> remove redChecker

let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list))  (redPiece:RedPiece) =

    let yIncrementValue = -1
    let minY = 0

    match redPiece with
    | RedPiece.RedChecker rc -> 
       let position = rc.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
       | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

    | RedPiece.RedKing rk -> 
       let position = rk.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
       | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
[<Test>
let ``red king jumps checker``() =
    let blackChecker = { BlackChecker.Position= { X=1 ; Y=1 } }
    let target = (blackChecker, [blackChecker])

    RedKing { RedKing.Position= { X=0 ; Y=2 } } |> jumpBlack target
                                                |> fst
                                                |> should equal (RedPiece.RedKing { RedKing.Position= { X=2 ; Y=0 } })

[<Test>]
let ``black checker removed after being jumped``() =
    let target = { BlackChecker.Position= { X=1 ; Y=1 } }, []
    RedChecker { RedChecker.Position= { X=2 ; Y=2 } } |> jumpBlack target
                                                      |> snd
                                                      |> should equal []
[<Test>]
let ``red checker jumps black checker southeast``() =
    let blackChecker = { BlackChecker.Position= { X=3 ; Y=2 } }
    let target = blackChecker, [blackChecker]

    RedChecker { RedChecker.Position= { X=2 ; Y=3 } } |> jumpBlack target
                                                      |> fst
                                                      |> should equal (RedChecker { RedChecker.Position= { X=4 ; Y=1 } })
(*类型*)
类型北=东北|西北
类型南=东南|西南
类型方向=
|东北
|西北
|东南
|西南
类型位置={X:int;Y:int}
类型BlackChecker={Position:Position}
键入RedChecker={Position:Position}
类型BlackKing={Position:Position}
键入RedKing={Position:Position}
类型检查器=
|黑棋子的黑棋子
|RedChecker的RedChecker
|黑金中的黑金
|红字红字
国王类型=
|黑金中的黑金
|红字红字
类型红片=
|RedChecker的RedChecker
|红字红字
(*功能*)
让rec remove item list=list |>list.filter(乐趣x->x项)
设置行位置y1 y2 y3索引=
与索引匹配
|当x<4->{x=x;Y=y1}
|当x<8->{x=x-4;Y=y2}
|{X=index-8;Y=y3}
让初始化为black()=
设置位置索引=
索引|>设置行位置7 6 5
设blackCheckers=List.init 12 setPosition |>List.map(fun pos->{BlackChecker.Position={X=pos.X;Y=pos.Y})
黑棋
让我们初始化()=
设置位置索引=
索引|>设置行位置0 1 2
让redCheckers=List.init 12 setPosition |>List.map(fun pos->{RedChecker.Position={X=pos.X;Y=pos.Y})
红人
设置(x,y)位置(位置:位置)=
不匹配(positions |>List.exists(fun pos->pos={X=X;Y=Y}))与
|真->{X=X;Y=Y}
|错误->位置
允许移动黑色方向位置(棋盘格:黑色棋盘格)=
让位置=棋盘格位置
配合方向
|North.North->{BlackChecker.Position=(positions,Position)| |>set((Position.X+1),(Position.Y+1))}
|North.North->{BlackChecker.Position=(positions,Position)| |>set((Position.X-1),(Position.Y+1))}
允许移动红色方向位置(棋盘格:红色棋盘格)=
让位置=棋盘格位置
配合方向
|South.South->{RedChecker.Position=(positions,Position)| |>set((Position.X+1),(Position.Y-1))}
|South.South->{RedChecker.Position=(positions,Position)| |>set((Position.X-1),(Position.Y-1))}
允许移动国王方向位置(国王:国王)=
让位置=与国王匹配
|国王黑王位置->国王黑王位置
|国王。红色国王->国王。位置
让结果=与方向匹配
|东北->(位置,位置)| |>设置((位置X+1),(位置Y+1))
|西北->(位置,位置)| |>设置((位置X-1),(位置Y+1))
|东南->(位置,位置)| |>设置((位置X+1),(位置Y-1))
|西南->(位置,位置)| |>集合((位置X-1),(位置Y-1))
匹配国王
|King.BlackKing \->King.BlackKing{BlackKing.Position=result}
|King.RedKing \->King.RedKing{RedKing.Position=result}
让我们跳转目标指向源=
让updateX值={X=target.X+value
Y=target.Y+yDirection}
匹配源
|当position.Y+yddirection=target.Y时的位置&&
position.X+1=target.X->updateX 1
|当position.Y+yddirection=target.Y时的位置&&
position.X-1=target.X->updateX-1
|->来源
让跳转红色((红色棋盘格:红色棋盘格),(红色棋盘格:红色棋盘格列表))(黑色棋盘格:黑色棋盘格)=
让yIncrementValue=1
设maxY=7
让position=blackChecker.position |>跳转redChecker.position yIncrementValue
对位
|pos=blackChecker.Position->blackChecker{blackChecker with Position=Position}时的pos,红色Checker
|pos.Y=maxY->Checker.BlackKing{BlackKing.Position=Position}时的pos,redChecker |>删除redChecker
|->BlackChecker{BlackChecker with Position=Position},redChecker |>删除redChecker
让jumpBlack((黑棋子:黑棋子),(黑棋子:黑棋子列表))(红色棋子:红色棋子)=
让yIncrementValue=-1
设minY=0
将红字与
|RedPiece.RedChecker rc->
让position=rc.position |>跳转blackChecker.position yIncrementValue
对位
|pos=rc.Position->RedPiece.RedChecker{rc with Position=Position}时的pos,黑棋子
|当pos.Y=minY->RedPiece.RedKing{RedKing.Position=Position}时,黑棋子|>移除黑棋子
|->RedPiece.RedChecker{rc with Position=Position},blackChecker |>删除blackChecker
|RedPiece.RedKing rk->
让position=rk.position |>跳转blackChecker.position yIncrementValue
对位
|当pos=rk.Position->RedPiece.RedKing{rk with Position=Position}时的pos,黑棋子
|当pos.Y=minY->RedPiece.RedKing{Position=Position}时,黑棋子|>移除黑棋子
|->RedPiece.RedKing{rk with Position=Position},blackChecker |>删除blackChecker
测试:

let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list))  (redPiece:RedPiece) =

    let yIncrementValue = -1
    let minY = 0

    match redPiece with
    | RedPiece.RedChecker rc -> 
       let position = rc.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
       | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

    | RedPiece.RedKing rk -> 
       let position = rk.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
       | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
match redPiece with
| RedPiece.RedChecker rc -> 
   let position = rc.Position |> jump blackChecker.Position yIncrementValue
   match position with
   | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
   | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
   | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

| RedPiece.RedKing rk -> 
   let position = rk.Position |> jump blackChecker.Position yIncrementValue
   match position with
   | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
   | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
   | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
(* Types *)
type North = NorthEast | NorthWest
type South = SouthEast | SouthWest

type Direction = 
    | NorthEast 
    | NorthWest
    | SouthEast 
    | SouthWest

type Position =     { X:int; Y:int }

type BlackChecker = { Position:Position }
type RedChecker =   { Position:Position }
type BlackKing =    { Position:Position }
type RedKing =      { Position:Position }

type Checker =
    | BlackChecker of BlackChecker
    | RedChecker   of RedChecker
    | BlackKing    of BlackKing
    | RedKing      of RedKing

type King = 
    | BlackKing of BlackKing
    | RedKing of RedKing

type RedPiece = 
    | RedChecker of RedChecker 
    | RedKing of RedKing

(* Functions *)
let rec remove item list = list |> List.filter (fun x -> x <> item)

let setRowPosition y1 y2 y3 index =
    match index with 
    | x when x < 4 -> { X=x; Y=y1 }
    | x when x < 8 -> { X=x-4; Y=y2 }
    | _            -> { X=index-8; Y=y3 }

let initializeBlack () =
    let setPosition index =
        index |> setRowPosition 7 6 5

    let blackCheckers = List.init 12 setPosition |> List.map (fun pos -> { BlackChecker.Position= { X=pos.X; Y=pos.Y } })
    blackCheckers

let initializeRed () =
    let setPosition index =
        index |> setRowPosition 0 1 2

    let redCheckers =   List.init 12 setPosition |> List.map (fun pos -> { RedChecker.Position= { X=pos.X; Y=pos.Y } })
    redCheckers

let set (x, y) positions (position:Position) =
    match not (positions |> List.exists (fun pos -> pos = { X=x; Y=y })) with
    | true -> { X=x; Y=y }
    | false -> position

let moveBlack direction positions (checker:BlackChecker) =
    let position = checker.Position

    match direction with
    | North.NorthEast -> { BlackChecker.Position= (positions, position) ||> set ((position.X + 1), (position.Y + 1 )) } 
    | North.NorthWest -> { BlackChecker.Position= (positions, position) ||> set ((position.X - 1), (position.Y + 1 )) }

let moveRed direction positions (checker:RedChecker) =
    let position = checker.Position

    match direction with
    | South.SouthEast -> { RedChecker.Position= (positions, position) ||> set ((position.X + 1), (position.Y - 1 )) }
    | South.SouthWest -> { RedChecker.Position= (positions, position) ||> set ((position.X - 1), (position.Y - 1 )) }

let moveKing direction positions (king:King) =

    let position = match king with
                   | King.BlackKing bk -> bk.Position
                   | King.RedKing   rk -> rk.Position

    let result = match direction with
                 | NorthEast -> (positions, position) ||> set ((position.X + 1), (position.Y + 1 ))
                 | NorthWest -> (positions, position) ||> set ((position.X - 1), (position.Y + 1 ))
                 | SouthEast -> (positions, position) ||> set ((position.X + 1), (position.Y - 1 ))
                 | SouthWest -> (positions, position) ||> set ((position.X - 1), (position.Y - 1 ))

    match king with
    | King.BlackKing _ -> King.BlackKing { BlackKing.Position= result }
    | King.RedKing   _ -> King.RedKing   { RedKing.Position=   result }

let jump target yDirection source =
    let updateX value = { X=target.X + value
                          Y=target.Y + yDirection }
    match source with
    | position when position.Y + yDirection = target.Y &&
                    position.X + 1 = target.X -> updateX 1

    | position when position.Y + yDirection = target.Y &&
                    position.X - 1 = target.X -> updateX -1
    | _ -> source

let jumpRed ((redChecker:RedChecker), (redCheckers:RedChecker list)) (blackChecker:BlackChecker) =

    let yIncrementValue = 1
    let maxY = 7
    let position = blackChecker.Position |> jump redChecker.Position yIncrementValue

    match position with
    | pos when pos = blackChecker.Position -> BlackChecker { blackChecker with Position= position }, redCheckers
    | pos when pos.Y = maxY                -> Checker.BlackKing { BlackKing.Position=position }, redCheckers |> remove redChecker
    | _ -> BlackChecker { blackChecker with Position= position }, redCheckers |> remove redChecker

let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list))  (redPiece:RedPiece) =

    let yIncrementValue = -1
    let minY = 0

    match redPiece with
    | RedPiece.RedChecker rc -> 
       let position = rc.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rc.Position -> RedPiece.RedChecker { rc with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing    { RedKing.Position=position },  blackCheckers |> remove blackChecker
       | _ ->                          RedPiece.RedChecker { rc with Position= position }, blackCheckers |> remove blackChecker

    | RedPiece.RedKing rk -> 
       let position = rk.Position |> jump blackChecker.Position yIncrementValue
       match position with
       | pos when pos = rk.Position -> RedPiece.RedKing { rk with Position= position }, blackCheckers
       | pos when pos.Y = minY      -> RedPiece.RedKing { Position=position }, blackCheckers |> remove blackChecker
       | _                          -> RedPiece.RedKing { rk with Position= position }, blackCheckers |> remove blackChecker
[<Test>
let ``red king jumps checker``() =
    let blackChecker = { BlackChecker.Position= { X=1 ; Y=1 } }
    let target = (blackChecker, [blackChecker])

    RedKing { RedKing.Position= { X=0 ; Y=2 } } |> jumpBlack target
                                                |> fst
                                                |> should equal (RedPiece.RedKing { RedKing.Position= { X=2 ; Y=0 } })

[<Test>]
let ``black checker removed after being jumped``() =
    let target = { BlackChecker.Position= { X=1 ; Y=1 } }, []
    RedChecker { RedChecker.Position= { X=2 ; Y=2 } } |> jumpBlack target
                                                      |> snd
                                                      |> should equal []
[<Test>]
let ``red checker jumps black checker southeast``() =
    let blackChecker = { BlackChecker.Position= { X=3 ; Y=2 } }
    let target = blackChecker, [blackChecker]

    RedChecker { RedChecker.Position= { X=2 ; Y=3 } } |> jumpBlack target
                                                      |> fst
                                                      |> should equal (RedChecker { RedChecker.Position= { X=4 ; Y=1 } })
[
让``红王跳棋盘格``()=
设blackChecker={blackChecker.Position={X=1;Y=1}
让目标=(blackChecker,[blackChecker])
RedKing{RedKing.Position={X=0;Y=2}}}}跳黑目标