import java.util.Random;
public class Fighter {
int str;
int dex;
int hth;
Random gen = new Random(1535636);
public Fighter() {
str = gen.nextInt(9);
dex = gen.nextInt(9);
hth = gen.nextInt(14);
}
public int getHth(){
return hth;
}
public int getStr(){
return str;
}
public int getDex(){
return dex;
}
}
import java.util.Random;
public class Arena {
public static void main(String[] args) {
Random gen = new Random();
Fighter Guy1 = new Fighter();
int x =1;
while (x < 200000000){
x++;
}
Fighter Guy2 = new Fighter();
int hth1 = Guy1.getHth();
int hth2 = Guy2.getHth();
System.out.println("Fight Start");
System.out.println("---------------");
//System.out.println(gen.nextInt(10));
//System.out.println(gen.nextInt(17));
System.out.println(Guy1.getStr());
//Fighting
}
}
每当我运行这个时,无论如何我都会得到相同的结果。我希望每次都能制作2个随机战士。现在有几行只是为了确认它不会产生随机数。
有没有人知道如何在构造函数中正确使用随机数?或者我完全错了吗?
答案 0 :(得分:12)
您为随机数生成器提供了一个恒定的种子值:
Random gen = new Random(1535636);
不要那样做。它将始终提供相同的值。只需调用默认构造函数:
Random gen = new Random();
这
创建一个新的随机数生成器。其种子初始化为基于当前时间的值:
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#Random()
<强>为什么吗
与大多数“标准库”随机数生成器一样,Random
是"Pseudorandom number generator"。这意味着它不是实际上生成随机数!相反,它是以一种非常明确的方式计算它们 - 它们只是像随机数一样看起来,并且它们往往具有良好的分布。
PRNG初始化为种子值,用于设置其内部状态。如果每次都提供相同的种子值,PRNG每次运行时都会处于相同的状态,从而提供相同的数字序列!
使它们看起来随机的东西,通常是 1 它们默认是“播种”的,具有基于时间的值。在大多数库中,这是一个具有非常精确的时间值。所以大部分时间,如果你看到有人播种他们的PRNG,那可能是不正确的,或者至少是非常不必要的。
1 - 注意:这是 not 来自libc的rand()
的情况:“如果没有提供种子值,则rand()函数会自动播种值为1.“
答案 1 :(得分:4)
现在您正在使用相同的种子初始化随机数生成器。这将使它每次都产生相同的数字序列。您想要使用no-arg constructor:
Random gen = new Random();
此构造函数将随机数生成器的种子设置为非常可能与此构造函数的任何其他调用不同的值。