我正在尝试在 2D 网格上按程序生成一个世界。对于随机数生成,我使用单个全局 java.utils.Random 实例和种子。
像这样:
public class Game {
private static final int SEED = 1111;
private static final Random RANDOM = new Random(SEED);
private static final int roomsCount = generateRandomNumberOfRooms();
}
一切都工作得很好,直到我写了这个方法:
public ArrayList<XYCoords> generateRandomCoordinates(){
ArrayList<XYCoords> coords = new ArrayList<>(roomsCount);
for(int i = 0; i < roomsCount; i+=1) {
XYCoords xy = new XYCoords(RANDOM.nextInt(WIDTH), RANDOM.nextInt(HEIGHT));
coords.add(xy);
}
return coords;
}
当我执行它时,我得到了XY坐标列表,但它们都具有相同的两个X和Y值,例如(11 ,20) 或 (12, 5)... 等等,所有房间都落在同一个位置。在我看来,for 循环中对 RANDOM.nextInt() 的调用不会更新 RANDOM 实例的状态。
在我调用 RANDOM.nextInt() 的所有其他函数中,它工作正常。其中一些也使用 for 循环。问题仅出在这个函数上。它直接在 main() 中使用一次,并且不嵌套在任何地方。
有人知道问题可能出在哪里吗?如果您需要,我可以上传更多代码,但我认为这是无关紧要的。
最佳答案
不需要的行为 1:每个应用程序运行都会以相同的顺序生成相同的值。原因是您的 RANDOM 对象是用种子实例化的。尝试以下调整:(删除种子,允许 Random
为您提供随机值):
public class Game {
private static final Random RANDOM = new Random();
private static final int roomsCount = generateRandomNumberOfRooms();
}
如果您出于某种原因需要种子,您可以尝试在每次启动时更新种子。
澄清种子的实际作用:
(请注意,如果您提供种子,种子也会从构造函数设置)
setSeed
public void setSeed(long seed)
Sets the seed of this random number generator using a single long seed. The general contract of setSeed is that it alters the state of this random number generator object so as to be in exactly the same state as if it had just been created with the argument seed as a seed. The method setSeed is implemented by class Random by atomically updating the seed to (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1) and clearing the haveNextNextGaussian flag used by nextGaussian(). The implementation of setSeed by class Random happens to use only 48 bits of the given seed. In general, however, an overriding method may use all 64 bits of the long argument as a seed value.
Parameters: seed - the initial seed
不需要的行为2:循环后的电线都是一样的。 XYCoords
类可能将 x
和 y
声明为 static
变量。 解决方案:删除静态声明。由于这些值是静态的,因此对象在绑定(bind)到类时共享这些值。最后设置的值是迭代所有 XYCoords
对象时将获得的值。
一般来说,这是两者的混合,导致您始终获得相同的值。
关于Java Random.nextInt() 仅在循环中重复数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55299791/