我有一个2d数组,我已将所有单元格设置为枚举类型State.SAFE。现在我想把这些单元格中的5个随机放到State.HIT中。所以我有:
Random objrandom = new Random();
State[][] playField = new State[5][5];
int w;
for (w = 0; w < 5; w++) { // set all states to SAFE first
int h = 0;
playField[w][h] = State.SAFE;
for (h = 0; h < 5; h++) {
playField[w][h] = State.SAFE;
}
}
for (int i = 0; i < 5; i++) { // try and set 5 states, randomly, to HIT
playField[objrandom.nextInt(5)][objrandom.nextInt(5)] = State.HIT;
}
问题在于每次运行它时,所有单元格仍处于SAFE状态或Hit状态非随机分布,即每列的第一行或超过5个HIT状态。
答案 0 :(得分:1)
如果您需要将5个单元格设置为HIT,则不能使用这样的随机数,因为您可能会多次获得相同的数字。我就是这样做的:
public static void main(String[] args) {
State[][] playField = new State[5][5];
setStateToSafe(playField);
List<Integer> hits = getRandomIndices(5);
applyHitStateToIndices(hits, playField);
System.out.println(Arrays.deepToString(playField));
}
private static void setStateToSafe(State[][] playField) {
for (int w = 0; w < playField.length; w++) {
Arrays.fill(playField[w], State.SAFE);
}
}
private static List<Integer> getRandomIndices(int n) {
List<Integer> hits = new ArrayList<>();
for (int i = 0; i < n * n; i++) hits.add(i);
Collections.shuffle(hits);
return hits.subList(0, n);
}
private static void applyHitStateToIndices(List<Integer> hits, State[][] playField) {
for (int i = 0; i < hits.size(); i++) {
int hitIndex = hits.get(i);
int row = hitIndex / playField.length;
int column = hitIndex % playField.length;
playField[row][column] = State.HIT;
}
}
答案 1 :(得分:0)
您的解决方案存在问题,因为行playField[objrandom.nextInt(5)][objrandom.nextInt(5)]=...
可能会导致同一个单元格被引用两次。我无法确定这是否是您问题的原因,但它可能至少是其中的一部分。
如果您想解决此问题,则必须根据已更改的单元格的历史记录检查每个随机数,并在双击时请求不同的随机数。
我建议采用完全不同的方法。随机应该表示值将改变的概率,而不是请求改变值的单元格的行和列的索引。
换句话说:
nextDouble()
)State.HIT
,否则将其设置为State.SAFE
代码看起来像这样:
Random objrandom = new Random();
State[][] playField = new State[5][5];
for (int w = 0; w < 5; w++) {
for (int h = 0; h < 5; h++) {
playField[w][h] = (objrandom.nextDouble() < 0.2d) ? State.HIT : State.SAFE;
}
}
答案 2 :(得分:0)
如果小开销不会造成太大麻烦,那么你可以这样做:
创建一个用于表示字段上的点的类。
final class Point {
public final int x;
public final int y;
public Point(final int x, final int y) {
this.x = x;
this.y = y;
}
}
填写包含所有可能点的列表,并将其随机播放。
List<Point> points = new ArrayList<>();
for (int x = 0; x < 5; x++) {
for (int y = 0; y < 5; y++) {
points.add(new Point(x, y));
}
}
Collections.shuffle(points);
现在第一个N
(在你的情况下为5)点将被随机化,100%不一样。
for (int i = 0; i < 5; i++) {
Point p = points.get(i);
playField[p.x][p.y] = State.HIT;
}