Search code examples
carraysarc4random

How to get N unique random quantities without indefinite loop?


I want to generate 5 random positions on a map. I can only come up with the code below, which uses while (1) and break:

 int map[10][10];
 memset(map,0,sizeof(map));

 for (int i = 0; i < 5; i++) {
     while (1) {
         int x = RAND_FROM_TO(0, 10);
         int y = RAND_FROM_TO(0, 10);
         if (map[x][y]==0) {
             map[x][y]=1;
             break;
         }
     }
 }

Is there any other way to do the same job without while(1), because I have been told the while(1) is very bad.

I just want to find a simple way to do it, so the efficiency of the generating random numbers is not under my consideration.


Solution

  • You can use a shuffle algorithm such as Fisher–Yates. I would pose a modified (truncated) version as so:

    1. Express your XY coordinates as a single number.
    2. Construct a list of all coordinates.
    3. Pick one at random, mark it.
    4. Remove that coordinate from the list (swap it with the one at the end of the list, and treat the list as 1 element shorter)
    5. repeat with the list that no longer contains the marked coordinate.

    This way, rather than choosing 5 numbers from 0-99, you choose one 0-99, 0-98, ... 0-95, which guarantees that you can complete the task with exactly 5 choices.

    EDIT: Upon further consideration, step 1 is not strictly necessary, and you could use this on a system with sparse coordinates if you did it that way.