如何在2D阵列中选择三个随机点?

时间:2019-04-10 18:28:28

标签: java multidimensional-array

我有一些代码将创建一个2D布尔数组,随机选择3个空格并将它们分配为true。现在,我的代码可能会选择两个相同的空格,并将其分配为true,因此我可能不会以3个空格结尾。如何更改代码以从数组中选择3个随机且唯一的空格?

boolean mineLocations[][] = new boolean[rows][cols];

int rRow = random.nextInt(rows);
int rCol = random.nextInt(cols);
mineLocations[rRow][rCol] = true;

rRow = random.nextInt(rows);
rCol = random.nextInt(cols);
mineLocations[rRow][rCol] = true;

rRow = random.nextInt(rows);
rCol = random.nextInt(cols);
mineLocations[rRow][rCol] = true;

5 个答案:

答案 0 :(得分:1)

您可以尝试使用类似的东西:

//if already true, keep rolling new row and col,
//then when you find one that isn't, the loop breaks, and
//you set it to true
while(mineLocations[rRow][rCol])
{
   //try again
   rRow = random.nextInt(rows);
   rCol = random.nextInt(cols);
}
mineLocations[rRow][rCol] = true;

答案 1 :(得分:1)

以下是您如何执行此操作的示例:

boolean mineLocations[][] = new boolean[rows][cols];
Random random = new Random();

int counter = 0;
while (counter < 3) { //looping while 3 distinct cells are not set to true
    int rRow = random.nextInt(rows);
    int rCol = random.nextInt(cols);

    if (!mineLocations[rRow][rCol]) {
        mineLocations[rRow][rCol] = true;
        counter++; //increasing the counter only when a new cell is set to true
    }
}

逻辑很简单:每次迭代都会生成一个新坐标。然后检查该坐标处的值是否仍为false(尚未更改)。如果是,请将其设置为true。

重复N次。

答案 2 :(得分:1)

您如何创建一种用于设置初始随机地雷位置的单独方法?

例如:

import java.util.Arrays;
import java.util.Random;

class Main {
  public static void main(String[] args) {
    int rows = 3, cols = 4;
    boolean mineLocations[][] = new boolean[rows][cols];
    System.out.println(Arrays.deepToString(mineLocations));
    placeMines(3, mineLocations);
    System.out.println(Arrays.deepToString(mineLocations));
  }

  private static void placeMines(int numMines, boolean mineLocations[][]) {
    int n = mineLocations.length;
    int m = mineLocations[0].length;
    if (numMines > n * m) {
      System.err.println("Can't place more mines than slots avalaible on the grid!");
      return;
    }
    int minesPlaced = 0;
    while (minesPlaced != numMines) {
      int randomRow = new Random().nextInt(n);
      int randomCol = new Random().nextInt(m);
      if (!mineLocations[randomRow][randomCol]) {
        mineLocations[randomRow][randomCol] = true;
        minesPlaced++;
      }
    }
    return;
  }
}

示例输出:

[[false, false, false, false], [false,false, false, false], [false, false, false, false]]
[[false, false, false, true], [false, true, false, false], [false, true, false, false]]

答案 3 :(得分:1)

您可以首先通过随机生成三个唯一坐标并将其存储在集合中来确保已创建三个唯一坐标,除非集合的大小达到三个。然后遍历集合并返回坐标并初始化数组。您可以像这样编写它,

public static void main(String[] args) throws Exception {
    Set<String> coordSet = new HashSet<>();
    Random random = new Random();
    int rows = 3;
    int cols = 3;
    boolean mineLocations[][] = new boolean[rows][cols];

    while(coordSet.size() < 3) {
        int rRow = random.nextInt(rows);
        int rCol = random.nextInt(cols);
        coordSet.add(String.format("%d:%d", rRow, rCol)); // set always stores unique values hence no need to check for existing data
    }
    System.out.println(coordSet);

    coordSet.stream().forEach(x -> {
        String[] pair = x.split(":");
        mineLocations[Integer.parseInt(pair[0])][Integer.parseInt(pair[1])] = true;
    });     
}

此代码在独立执行中很少打印随机值,

[1:0, 0:2, 2:0]
[1:0, 2:0, 2:1]
[1:0, 0:1, 1:2]
[2:0, 2:1, 2:2]

如您所见,在单个条目中,每个坐标都不相同。

在这里,我将坐标存储为以冒号分隔的字符串,但是如果您想要更好的实现,则可以创建一个自定义类来存储X和Y坐标,这样会更简洁。

您会注意到,此代码通常可用于您可以初始化的任何行和列的值,并且仅通过在while循环条件下更改值3即可更改随机点选择的数量

答案 4 :(得分:1)

这是使用Random和IntStream / forEach的解决方案

boolean mineLocations[][] = new boolean[rows][cols];

int count = rows * cols;
new Random().ints(3, 0, rows * cols - 1).forEach( rand -> {
  int y = rand / rows;
  int x = rand % cols;
  mineLocations[x][y] = true;
});