0
如何将两个案例值表达式重构为一个?如何将两个案例值表达式重构为一个?
恐怕我还没有就如何从这个逻辑消除重复清晰:
match redPiece with
| Checker checker -> checker |> set (checker |> attemptJump blackChecker yIncrementValue)
| King king -> king |> set (king |> attemptJump blackChecker yIncrementValue)
这个问题可能是一个duplicate。不过,我仍然在努力重构这种类型的代码异味。
我该如何实际实现我提供的link上提供的海报中的一个海报的包装功能?
下面是完整的功能:
let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list)) (redPiece:RedPiece) =
let yIncrementValue = -1
let minY = 0
let set position piece =
match position with
| pos when pos = piece -> position , blackCheckers
| _ -> position , blackCheckers |> remove blackChecker
match redPiece with
| Checker checker -> checker |> set (checker |> attemptJump blackChecker yIncrementValue)
| King king -> king |> set (king |> attemptJump blackChecker yIncrementValue)
整个域可以在这里找到:
(* Types *)
type BlackOption = NorthEast | NorthWest
type RedOption = SouthEast | SouthWest
type KingOption =
| NorthEast
| NorthWest
| SouthEast
| SouthWest
type Position = { X:int; Y:int }
type BlackChecker = Position
type RedChecker = Position
type BlackKing = Position
type RedKing = Position
type King =
| BlackKing of BlackKing
| RedKing of RedKing
type RedPiece =
| Checker of RedChecker
| King of RedKing
type BlackPiece =
| BlackChecker of BlackChecker
| BlackKing of BlackKing
(* Private *)
let private remove item list = list |> List.filter (fun x -> x <> item)
let private 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 private 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 private attemptJump 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 private initializeBlack() =
let setPosition index =
index |> setRowPosition 7 6 5
let blackCheckers = List.init 12 setPosition |> List.map (fun pos -> { X=pos.X; Y=pos.Y })
blackCheckers
let private initializeRed() =
let setPosition index =
index |> setRowPosition 0 1 2
let redCheckers = List.init 12 setPosition |> List.map (fun pos -> { X=pos.X; Y=pos.Y })
redCheckers
(* Exposed *)
let moveBlack direction positions (checker:BlackChecker) =
let position = checker
match direction with
| BlackOption.NorthEast -> (positions, position) ||> set ((position.X + 1), (position.Y + 1))
| BlackOption.NorthWest -> (positions, position) ||> set ((position.X - 1), (position.Y + 1))
let moveRed direction positions (checker:RedChecker) =
let position = checker
match direction with
| RedOption.SouthEast -> (positions, position) ||> set ((position.X + 1), (position.Y - 1))
| RedOption.SouthWest -> (positions, position) ||> set ((position.X - 1), (position.Y - 1))
let moveKing direction positions (king:King) =
let position = match king with
| King.BlackKing bk -> bk
| King.RedKing rk -> rk
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 result
| King.RedKing _ -> King.RedKing result
let jumpRed ((redChecker:RedChecker), (redCheckers:RedChecker list)) (blackChecker:BlackChecker) =
let yIncrementValue = 1
let maxY = 7
let position = blackChecker |> attemptJump redChecker yIncrementValue
match position with
| pos when pos = blackChecker -> BlackChecker position , redCheckers
| pos when pos.Y = maxY -> BlackKing position , redCheckers |> remove redChecker
| _ -> BlackChecker position , redCheckers |> remove redChecker
let jumpBlack ((blackChecker:BlackChecker),(blackCheckers:BlackChecker list)) (redPiece:RedPiece) =
let yIncrementValue = -1
let minY = 0
let set position piece =
match position with
| pos when pos = piece -> position , blackCheckers
| _ -> position , blackCheckers |> remove blackChecker
match redPiece with
| Checker checker -> checker |> set (checker |> attemptJump blackChecker yIncrementValue)
| King king -> king |> set (king |> attemptJump blackChecker yIncrementValue)
也许我错了,但分开黑色和红色分类是一种错误的做法。一个棋子完成同样的事情,不管它的颜色(去**是左边还是右边)。颜色/播放器只是其状态的一个参数。重复IMO来自那里。 – Sehnsucht
这是一个很奇怪的领域模型。就像@Sehnsucht说的那样,你在那里的定义中有很多重复。 – asibahi
感谢您的反馈。我的意图是让编译器执行基于颜色和国王身份的检查器移动规则。因此,我试图实践使非法国家不能代表和不幸惨败的想法。 –