F# 在F中创建复合迭代器#
我正在实现一个类似跳棋的游戏,我需要一个序列来枚举给定配置的所有合法移动 我有以下函数,直接从C#翻译过来: 这是可行的,但很尴尬,而且不是“F#方式”,更不用说我有一个偷偷的怀疑,我在这里做的不是最佳性能 我想要的是将它“展平”为使用“迭代所有单元格”、“迭代所有来自此单元格的有效移动”组合的内容 以下是我希望结合的功能:F# 在F中创建复合迭代器#,f#,iterator,yield,c#-to-f#,lazy-sequences,F#,Iterator,Yield,C# To F#,Lazy Sequences,我正在实现一个类似跳棋的游戏,我需要一个序列来枚举给定配置的所有合法移动 我有以下函数,直接从C#翻译过来: 这是可行的,但很尴尬,而且不是“F#方式”,更不用说我有一个偷偷的怀疑,我在这里做的不是最佳性能 我想要的是将它“展平”为使用“迭代所有单元格”、“迭代所有来自此单元格的有效移动”组合的内容 以下是我希望结合的功能: let AllCells = seq { for y=0 to BOARDSIZE-1 do for x=0 to BOAR
let AllCells =
seq {
for y=0 to BOARDSIZE-1 do
for x=0 to BOARDSIZE-1 do
yield (x,y);
};
及
让LegalMovesAround(x1,y1)=
序号{
如果电路板[x1,y1]=白色,则
对于dy=-2对2 do
对于dx=-2到2 do
设x2=x1+dx;
设y2=y1+dy;
让currentMove=newmovestruct(x1,y1,x2,y2);
如果(currentMove.DetermineMoveType MoveType.Invalical
&&板。[x2,y2]=无)然后
收益率变动;
}
我将不告诉你我的各种尝试的细节,因为它们都没有成功。但长话短说,我能想到的最好的方法是一个迭代器,该迭代器在每次生成时返回一个seq,而不是我正在寻找的平坦版本,它将返回一个简单的MoveStruct
有人知道如何组合所有单元格和LegalMovesAround(x,y)吗
问候,,
Aleks您应该能够按原样组合它们,然后将它们展平,如下所示:
let validMoves =
AllCells
|> Seq.collect LegalMovesAround
|> Seq.distinct
但从性能角度来看,它可能不是最好的解决方案
编辑:根据Tomas注释修复了示例代码您可以使用yield!在新的序列表达式中:
let allLegalMoves = seq {
for cell in AllCells do
yield! LegalMovesAround cell
}
您是否知道
yield代码>
差不多
seq {
for x,y in Allcells do
yield! LMA(x,y)
}
小心混合惰性序列和副作用!如果电路板发生了变异,那么清楚地了解整个序列的评估时间是很重要的。调用Seq.distinct在这里看起来很危险。不要介意我上面的评论,在进入移动树之前会调用Seq.distinct。这不是类型检查。我想legalMovesAround
应该是Seq.collect
@Tomas的论点:我真的不应该在没有FSI的情况下写答案。:)谢谢,这正是我想要的解决方案。简而言之,直截了当地说,循环是没有的:)这个解决方案也可以工作,除了它返回一个带有每个yield的序列,而我更喜欢它返回一个MoveStruct。调用方不需要知道实现的细节。不,它会生成一个MoveStruct。试试看。
let allLegalMoves = seq {
for cell in AllCells do
yield! LegalMovesAround cell
}
seq {
for x,y in Allcells do
yield! LMA(x,y)
}