Вопрос

I'm implementing a checkers-like game, and I need a sequence that enumerates all legal moves for a given configuration.

I've got the following function, directly translated from 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;
   }

It works, but it's awkward, and not quite the "F# way", let alone I have a sneaking suspicion that what I'm doing here is not performance optimal.

What I would like is to "flatten this out" into something that uses a combination of "iterate over all cells", "iterate over all valid moves from this cell".

And here are the functions I'm hoping to combine:

let AllCells =
    seq {
        for y=0 to BOARDSIZE-1 do
            for x=0 to BOARDSIZE-1 do
                yield (x,y);
    };

AND

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

I'm going to spare you the details of my various attempts to make it work, because none of them were successful. But to make the long story short, the best I could come up with is an iterator that returns a seq with each yield, instead of the flattened version I'm looking for, which would return a simple MoveStruct.

Anyone have a good idea how to combine AllCells, and LegalMovesAround(x,y)?

Regards, Aleks

Это было полезно?

Решение

You should be able to combine them the way they are and then flatten, something like this:

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

It may not be the best solution performance-wise though.

EDIT: Fixed sample code as per Tomas comment

Другие советы

You could use yield! in a new sequence expression:

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

Are you aware of yield!?

something like

seq {
    for x,y in Allcells do
        yield! LMA(x,y)
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top