Search code examples
c++f#immutabilitycode-translation

C++ to F# smooth translation


Hey folks, I have the following piece of code from C++.

for (int i=0; i < nObstacles; i++)
{
  int x,y;
  bool bAlreadyExists;
  do {          
    x = rand() % nGridWidth;
    y = rand() % nGridHeight;                   
  } while (HasObstacle(x, y));
  SetObstacle(x, y, true);      
}

I can translate it to F# directly with no problem.

let R = new System.Random()
for i=0 to nObstacles do
        let mutable bGoodToGo = false;
        let mutable x =0;
        let mutable y = 0
        while not bGoodToGo do
            x <-R.Next(nWidth)
            y <-R.Next(nHeight)
            bGoodToGo <- IsEmptyAt x y
        board.[x,y]<-Obstacle;

Of course this probably makes most of you cringe, since this is not the way F# was meant to be used. This code has some "unkosher" concepts for F#, such as do-while loops and mutable data.

But what I would be interested in seeing is a "proper" F# translation with immutable data, and some sort of do-while equivalent.


Solution

  • Here is my try:

    Seq.initInfinite (fun _ -> rnd.Next(width), rnd.Next(height))
    |> Seq.filter (fun (x, y) -> IsEmptyAt x y)
    |> Seq.distinct
    |> Seq.take nObstacles
    |> Seq.iter (fun (x, y) -> board.[x,y] <- Obstacle)
    

    You can remove the Seq.filter if the board is empty at the beginning. Like in Tomas solution, it generates an infinite sequence of positions. Then, it removes bad and duplicated positions. Finally, it updates the board with the nObstacles first elements.