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 desiredobstacleCount
. - 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;
}