2011-02-22 9 views
5

私はチェッカーのようなゲームを実装しています。特定の構成に対してすべての有効な移動を列挙するシーケンスが必要です。F#で複合反復子を作成する

私は直接のC#から翻訳、以下の機能を持っている:かなり「F#の道」それは動作しますが、それは厄介だ、とない

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; 
    } 

、おろか、私はそれがどのようなIひそか疑いを持っていますここでやっているのはパフォーマンスが最適ではありません。

私が望むのは、「すべてのセルを反復する」、「このセルからすべての有効な移動を反復する」という組み合わせを使用するものに「これを平坦化する」ことです。ので、

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; 
    } 

私はそれを動作させるためにあなたに私の様々な試みの詳細を惜しまするつもりですが:

そして、ここでは、私が結合するために望んでいる機能ですいずれも成功しなかった。しかし、長いストーリーを短くするために、私が思いつくことができる最高のものは、単純なMoveStructを返すフラットなバージョンではなく、各歩留まりでseqを返すイテレータです。

誰もがAllCellsとLegalMovesAround(x、y)を組み合わせる方法を知っていますか?

よろしく、 ALEKS

答えて

1

あなたは彼らがしている方法をまとめると、平らに、このような何かすることができるはずです。

let validMoves = 
    AllCells 
    |> Seq.collect LegalMovesAround 
    |> Seq.distinct 

それが最善の解決策の性能面いえないかもしれません。

EDIT:固定サンプルコードトマスコメントどおり

+0

よう

何かが怠惰なシーケンスと副作用を混合の用心します!ボードに変異がある場合は、配列全体が評価される時期を明確に理解することが重要です。 Seq.distinctを呼び出すのは危険です。 – Joh

+0

上記の私のコメントを気にしないで、Seq.distinctはmoveツリーを下る前に呼び出されます。 – Joh

+1

これはタイプチェックを行いません。私は 'legalMovesAround'が' Seq.collect'の引数になるはずです。 –

3

あなたが降伏を使用することができます!新しいシーケンス式に:

let allLegalMoves = seq { 
    for cell in AllCells do 
    yield! LegalMovesAround cell 
} 
3

あなたはyield!を知っていますか?

seq { 
    for x,y in Allcells do 
     yield! LMA(x,y) 
} 
+0

このソリューションは、各歩留まりのシーケンスを返しますが、MoveStructを返すのが好ましいことを除けば、機能します。呼び出し元は、実装の詳細を知る必要はありません。 – user627943

+0

いいえ、MoveStructが生成されます。それを試してみてください。 – Brian

+0

真実です。マジックのように動作します。 – user627943

関連する問題