Piotr Żak
Piotr Żak

Reputation: 2132

Recursion inside foreach loop

I have repetition in loop - when isAllowed = true - then continue next iteration, but when isAllowed is false - then the program should repeat generate random positions, coordinates and check if the isAllowed until is true.

How to make recursion in that loop to achieve this objective?

foreach (var fleet in groupedFleetsbySpaceshipCounts)
{
    var randomPositionX = new Random().Next(0, 9);
    var randomPositionY = new Random().Next(0, 9);

    var cords = int.Parse(randomPositionX.ToString() + randomPositionY);
    map.Location[cords].ActualFleetPosition = fleet.Key[i];
    var isAllowed = IsPositionAllowed(map, cords);
    if (isAllowed)
    {
        break;
    }
    else
    {
        randomPositionX = new Random().Next(0, 9);
        randomPositionY = new Random().Next(0, 9);

        cords = int.Parse(randomPositionX.ToString() + randomPositionY);
        map.Location[cords].ActualFleetPosition = fleet.Key[i];
        isAllowed = IsPositionAllowed(map, cords);
        if (isAllowed)
        {
            break;
        }
        else
        {
            //recursion
        }
    }
    i++;
}

Upvotes: 1

Views: 586

Answers (2)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112762

Maybe you want something like this:

var random = new Random();
foreach (var fleet in groupedFleetsbySpaceshipCounts)
{
    int coords;
    do {
        int randomPositionX = random.Next(0, 9);
        int randomPositionY = random.Next(0, 9);

        coords = 10 * randomPositionX + randomPositionY;
    } while (!IsPositionAllowed(map, coords));

    map.Location[coords].ActualFleetPosition = fleet.Key[i++];
}

I.e., you don't need a recursion (i.e., a method that calls itself), but another loop nested inside the first one.

Note that the max value of random.Next is exclusive. So, if you want numbers up to 9 you must use an upper value of 10. Also, if the lower value is 0, you can simply write random.Next(10).

It is important to create the Random object only once, because otherwise you might end up having different random objects generating the same pseudo random sequence. Using a static field in your class is even a better option than using a local variable

private static readonly _random = new Random();

Upvotes: 1

Agustín Orejudo
Agustín Orejudo

Reputation: 101

I guess this should do the trick (edited with some of your comments, I didn't want to enter on other things rather than the question):

var random = new Random();    
foreach (var fleet in groupedFleetsbySpaceshipCounts)
    {
        do
        {
            var randomPositionX = random.Next(0, 9);
            var randomPositionY = random.Next(0, 9);

            //Im not sure how you're managing this 'coords' map, but gonna just go to the point 
            var cords = int.Parse(randomPositionX.ToString() + randomPositionY);
            map.Location[cords].ActualFleetPosition = fleet.Key[i];
        } while (!IsPositionAllowed(map, cords));
        i++;
    }

If you want 'cords' variable to be available outside the do...while loop you can safely declare it outside the loop (even better, outside the foreach).

Upvotes: 0

Related Questions