Home > OS >  Adding 20 1s to a binary 2d array
Adding 20 1s to a binary 2d array

Time:07-01

I'm creating a pathfinding program and I have a 2d int array as with 1s indicating obstacles you can pass through/on and 0s meaning you can.

The starting grid is as follows:

int[][] map = {
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 1, 1, 1},
                {0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
                {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
        };

The start point of this is at [0, 0] and the end point is at [9, 9].

I want to create a method that takes map and returns it with 20 random obstacles (1s) in random positions however, the start point, end point and existing obstacles cannot be altered.

CodePudding user response:

You have many options on how to do it. You can prepare it like this:

public class HelloWorld{

     public static void main(String []args){
         Random random = new Random();
         int[][] map = new int[10][10];//you can user your existing array
         map[0][0] = 1;
         map[9][9] = 1;
        
         int counter = 20;
         while (counter > 0){
             int x = random.nextInt(9); 
             int y = random.nextInt(9);
             if(map[x][y] != 1){
                 System.out.println(x   " "   y);
                 map[x][y]=1;
                 counter--;
             }
         }
         
        map[0][0] = 0;
        map[9][9] = 0;
     }
}

CodePudding user response:

You can do it like so. This allows for any size rectangular matrix.

int[][] map = createMap(10, 10, 20);

for (int[] row : map) {
    System.out.println(Arrays.toString(row));
}

prints

[0, 0, 1, 1, 0, 0, 1, 0, 1, 0]
[1, 0, 0, 1, 0, 0, 1, 0, 0, 1]
[0, 0, 1, 1, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 1, 0, 0, 1, 0, 0, 0]
[1, 0, 0, 0, 1, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]

The method

Even though statistically you would populate the required number of 1's, it can't be guaranteed by just calling random x number of times. I took some liberties in returning a map based on a supplied row and column length. I deemed this okay since you only want to keep the first and last locations obstacle free.

  • The method takes row and column lengths and a desired obstacleCount.
  • An exception will be thrown if the map cannot accommodate the required number of obstacles.
  • First, generate a List of the required obstacles followed by 0 values.
  • then shuffle the sublist which omits the first and last cells.
  • simply copy the list to a map of the given dimensions.
  • and return it

public static int[][] createMap(int row, int col,
        int obstacleCount) {
    if (obstacleCount > row * col - 2) {
        throw new IllegalArgumentException(
                "Map too small for obstacles");
    }
    
    List<Integer> temp =new ArrayList<>();
    for( int i = 0; i < row*col; i  ) {
        temp.add(i > 0 && i <= obstacleCount ? 1 : 0);
    }

    Collections.shuffle(temp.subList(1, temp.size() - 1));
    int[][] map = new int[row][col];
    int start = 0;
    for (int[] mapRow : map) {
        for (int r = 0; r < row; r  ) {
            mapRow[r] = temp.get(start  );
        }
    }
    return map;
    
}

  • Related