随机骰子卷不是随机的

时间:2014-08-13 20:01:45

标签: scala random

简单的新手问题,我奇怪地无法想出一个解决方案。

我正在制作一个简单的骰子滚动模拟器,所以我可以比较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之外什么都不会打印,因为尽管在不同时间创建了不同的实例,但两个骰子总是会滚动相同的值。

我也尝试添加延迟,以便种子差异更大,但这也无济于事。

我该怎么做才能修补这个?

4 个答案:

答案 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/3189923http://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html的详细讨论说明。