【问题标题】:Dice Roller for any sided dice in VB.Net用于 VB.Net 中任何双面骰子的骰子滚轮
【发布时间】:2014-10-23 07:05:33
【问题描述】:

我想创建一个骰子滚轮,以便用户可以选择骰子上的多个面,它会随机响应,我当前的代码总是抛出相同的数字。

Sub rollDie(ByVal sides As Integer)
    Dim rand As Single = Rnd()
    For cnt As Integer = 1 To sides
        If rand < cnt / sides Then
            diceRoll = cnt
            Exit For
        End If
    Next
    Console.WriteLine("You rolled a {0} sided die which landed on {1}", sides, diceRoll)
End Sub

【问题讨论】:

标签: .net vb.net random dice


【解决方案1】:

我认为您最好将所有 Die 逻辑放入一个类中并使用 System.Random 类为您生成随机数,如下所示:

Public Class Die
    Private _sides As Integer
    Private Shared _generator As New System.Random '<<<one PRNG no matter how many dice

    Public ReadOnly Property Sides As Integer
        Get
            Return _sides
        End Get
    End Property

    Public Sub New(sides As Integer)
        _sides = sides
    End Sub

    ''' <summary>
    ''' Returns a random number between 1 and the number of sides of the die
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Roll() As Integer
        Return _generator.Next(1, _sides + 1)
    End Function
End Class

那么你可以这样使用它:

Dim elevensidedDie As New Die(11)
Debug.WriteLine("You rolled a(n) {0} sided die which landed on {1}", elevensidedDie.Sides, elevensidedDie.Roll)

【讨论】:

  • 你需要_rndGenerator.Next(1, _sides + 1)。否则,当场。
  • @MattWilko - 编辑后,无论有多少骰子,都有一个随机数。
【解决方案2】:

您应该使用 VB.Net 的 Randomize function 来播种随机数生成器,即

Sub rollDie(ByVal sides As Integer)
Randomize()
Dim rand As Single = Rnd()
For cnt As Integer = 1 To sides
    If rand < cnt / sides Then
        diceRoll = cnt
        Exit For
    End If
Next
Console.WriteLine("You rolled a {0} sided die which landed on {1}", sides, diceRoll)
End Sub

Randomize 函数将系统计时器用于种子。您可以在程序开始或rollDie 函数中调用它。

【讨论】:

    【解决方案3】:

    使用循环是一种非常低效的生成随机整数的方法。查看this 页面以获得更好的方法。

    这是与 cmets 最相关的部分的副本:

    ' Initialize the random-number generator.
    Randomize()
    ' Generate random value between 1 and 6. 
    Dim value As Integer = CInt(Int((6 * Rnd()) + 1))
    

    更简洁,也更快。

    【讨论】:

    • 还有偏见...... ;)
    • 您的意思是在生成结果的随机性方面存在偏见?这完全取决于 Rnd() 返回的结果的质量,并且超出 API 用户的控制范围,除非从头开始编写(或找到更好的实现)他们自己的 u(0,1) 生成器,否?
    • 啊,我在另一个答案中读到了您的改进。您正在使用 VB 的 API 访问操作系统的随机字节生成器来生成数字吗?它为安全关键应用程序产生了更好的结果(我认为骰子可能过度杀伤力,除非它用于赌场)。从来没有深入研究过为什么操作系统提供的字节生成器通常更好,但这可能是另一个问题的主题。
    • 不确定您找到了什么答案,但我想更多的是我在this answer 中写的内容。关键是乘以浮点数以使其适合您的范围会引入偏差,就像做模数一样。诚然,那里的例子是相当做作的。根据范围,现实世界的结果并不那么激烈。顺便说一句,这与(伪)随机性的来源无关。
    • 如果除数不是股息的一个因素,我可以看到模方法如何引入偏差。但是,这里没有使用它。我们使用模拟的 u(0,1) 并使用 u(0,1) 作为基础来生成其他类型随机分布的样本是教科书应用概率。我不明白这是有偏见的。
    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2018-09-24
    • 1970-01-01
    • 2016-08-10
    • 2016-12-26
    • 2018-09-08
    相关资源
    最近更新 更多