5

チェッカーのようなゲームを実装していますが、特定の構成ですべての正当な動きを列挙するシーケンスが必要です。

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

それを機能させるためのさまざまな試みの詳細は割愛します。どれも成功しなかったからです。しかし、長い話を短くするために、単純な MoveStruct を返す平坦化されたバージョンではなく、yield ごとに seq を返すイテレータを思い付くことができました。

AllCells と LegalMovesAround(x,y) を組み合わせる方法を知っている人はいますか?

よろしく、 アレックス

4

3 に答える 3

3

あなたは利回りを使うことができます!新しいシーケンス式:

let allLegalMoves = seq {
  for cell in AllCells do
    yield! LegalMovesAround cell
}
于 2011-02-22T10:27:25.410 に答える
3

知っていyield!ますか?

何かのようなもの

seq {
    for x,y in Allcells do
        yield! LMA(x,y)
}
于 2011-02-22T10:31:32.443 に答える
1

次のように、それらをそのまま組み合わせてから平らにすることができるはずです。

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

ただし、パフォーマンスに関しては最適なソリューションではない可能性があります。

EDIT:Tomasのコメントに従ってサンプルコードを修正

于 2011-02-22T08:54:15.717 に答える