简单的新手问题,我奇怪地无法想出一个解决方案。
我正在制作一个简单的骰子滚动模拟器,所以我可以比较nontransitive dice以及普通骰子,但问题是如果我在所述脸上制作两个具有相同数量的面和值的骰子,这两个骰子每次都会滚动相同的值。 (也就是说,每个掷骰产生不同的数字,但两个骰子都有相同的值)
这是我的代码:
class Die(values: Int*) {
private val rand: util.Random = new util.Random(compat.Platform.currentTime)
private val high = values.size + 1
private val low = values(0)
def roll(): Int = rand.nextInt(high - low) + low
def this(vals: Range) = this(vals: _*)
def rollAndCompareTo(that: Die): Symbol = {
val a = this.roll()
val b = that.roll()
if(a > b) 'GT
else if (a < b) 'LT
else 'EQ
}
}
object Program extends App {
val d61 = new Die(1 to 6)
val d62 = new Die(1 to 6)
for(_ <- 1 to 100)
println(d61 rollAndCompareTo d62)
}
100%的时间,程序除了'EQ
之外什么都不会打印,因为尽管在不同时间创建了不同的实例,但两个骰子总是会滚动相同的值。
我也尝试添加延迟,以便种子差异更大,但这也无济于事。
我该怎么做才能修补这个?
答案 0 :(得分:3)
尝试为您的Random实例留下种子,或使用
new util.Random(System.currentTimeMillis)
如果你在很短的时间内拨打了很多电话,种子的特异性就很重要。
答案 1 :(得分:1)
正如在其他评论中所说,您可以在伴侣对象中使用单个rand,然后您不必担心种子的解决方案。考虑使用SecureRandom使用它来为您的单个常规util.Random播种,以避免SecureRandom的开销或可能阻塞行为
object Die {
// consider using java.security.SecureRandom or using that to seed a util.Random
private[Die] val rand: util.Random = new util.Random(compat.Platform.currentTime)
}
class Die(values: Int*) {
private val high = values.size + 1
private val low = values(0)
def roll(): Int = Die.rand.nextInt(high - low) + low
def this(vals: Range) = this(vals: _*)
def rollAndCompareTo(die: Die): Symbol = {
val a = this.roll()
val b = die.roll()
if (a > b) 'GT
else if (a < b) 'LT
else 'EQ
}
}
object Program extends App {
val d61 = new Die(1 to 6)
val d62 = new Die(1 to 6)
for (_ <- 1 to 100)
println(d61 rollAndCompareTo d62)
}
答案 2 :(得分:0)
您可能希望选择不同的固定种子。此外,compat.Platform.currentTime()和System.currentTimeMillis()似乎工作正常(2014 Macbook Pro)。如果两个对象在同一毫秒内实例化,您可以尝试System.nanoTime()。但实际上,固定种子更好,例如用于检测。
此外,这看起来完全像Java - 具有可变状态,副作用等。如果您正在考虑学习Scala的方式,鼓励其创作者使用(尽可能实用),请查看Paul的书Chiusano和RúnarBjarnason称之为“Scala中的函数式编程”(Manning Press,早期访问,http://manning.com/bjarnason/)。他们使用随机数生成器的示例有一整章关于纯函数的状态。或者,查看NICTA的示例:https://github.com/NICTA/rng
答案 3 :(得分:0)
考虑java.security.SecureRandom
,它比线性同余生成器中的java.util.Random
更难以预测。
有关实例https://stackoverflow.com/a/11052736/3189923和http://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html的详细讨论说明。