我正在实施类似跳棋的游戏,我需要一个列举给定配置的所有合法移动的序列。
我有以下功能,直接从C#翻译过来:
seq {
for y1 = 0 to BOARDSIZE-1 do
for x1 = 0 to BOARDSIZE-1 do
for dy = -2 to 2 do
for dx = -2 to 2 do
let x2 = x1 + dx;
let y2 = y1 + dy;
let currentMove = new MoveStruct(x1, y1, x2, y2);
if (currentMove.SomeCondition = true) then
yield currentMove;
}
它有效,但它很尴尬,而不是“F#方式”,更不用说我有一种潜在的怀疑,我在这里做的不是性能最佳。
我想要的是“将其展平”为使用“遍历所有单元格”的组合,“迭代来自此单元格的所有有效移动”。
以下是我希望结合的功能:
let AllCells =
seq {
for y=0 to BOARDSIZE-1 do
for x=0 to BOARDSIZE-1 do
yield (x,y);
};
和
let LegalMovesAround(x1,y1) =
seq {
if board.[x1, y1] = WHITE then
for dy = -2 to 2 do
for dx = -2 to 2 do
let x2 = x1 + dx;
let y2 = y1 + dy;
let currentMove = new MoveStruct(x1, y1, x2, y2);
if (currentMove.DetermineMoveType <> MoveType.ILLEGAL
&& board.[x2, y2] = NONE) then
yield currentMove;
}
我将不遗余力地告诉你我各种尝试的细节,因为它们都没有成功。但是长话短说,我能想到的最好的是一个迭代器,它返回每个yield的seq,而不是我正在寻找的扁平版本,这将返回一个简单的MoveStruct。
任何人都知道如何组合AllCells和LegalMovesAround(x,y)?
此致 阿莱克斯
答案 0 :(得分:3)
你可以使用收益率!在一个新的序列表达式中:
let allLegalMoves = seq {
for cell in AllCells do
yield! LegalMovesAround cell
}
答案 1 :(得分:3)
您知道yield!
吗?
类似
seq {
for x,y in Allcells do
yield! LMA(x,y)
}
答案 2 :(得分:1)
你应该能够按照它们的方式将它们组合起来,然后展平,就像这样:
let validMoves =
AllCells
|> Seq.collect LegalMovesAround
|> Seq.distinct
虽然这可能不是性能方面的最佳解决方案。
编辑:根据Tomas评论修复了示例代码