Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a compound iterator in F#

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

like image 322
user627943 Avatar asked Feb 22 '11 08:02

user627943


People also ask

How to write a custom iterator in C++?

Writing a custom iterator in modern C++ 1 A dummy container for our experiments. ... 2 Choose the nature of our iterator. ... 3 Prepare the custom iterator. ... 4 Define the iterator constructors. ... 5 Implement operators. ... 6 Prepare the container. ... 7 Time to test our iterator. ... 8 Final notes. ... 9 Full source code 10 Sources. ...

How to create an iterator for any container object using Python ITER?

To create an iterator for any container object using the iter() function, we just have to pass the object to the iter() function. The function creates an iterator and returns a reference to it. We can create an iterator using the iter() function as follows.

What are the elements of an iterator in Python?

The list is: [1, 2, 3, 4, 5, 6, 7] The elements in the iterator are: 1 4 9 16 25 36 49 Process finished with exit code 0 Conclusion In this article, we have studied two ways to create an iterator in Python. You can use custom iterators to perform different operations on the elements of a container object while traversing it.

How to use ITER() function in Python?

The iter() function takes a container object such as list, tuple, or set and returns an iterator with which we can access the elements of the container object. To create an iterator for any container object using the iter() function, we just have to pass the object to the iter() function.


1 Answers

You could use yield! in a new sequence expression:

let allLegalMoves = seq {
  for cell in AllCells do
    yield! LegalMovesAround cell
}
like image 141
Joh Avatar answered Sep 30 '22 12:09

Joh