奇怪的随机数Bug .Net

时间:2011-05-03 21:14:56

标签: .net vb.net silverlight random

我确定我做错了什么;但这一直让我疯狂了一段时间。

我做了一个小型的Silverlight游戏(旧的Galaxian克隆)。当游戏开始~90%的时候,一堆星星随机定位在游戏区域。有三种类型的恒星 - 更大的恒星更快,更小的恒星运动更慢。

看起来像这样:

ScreenShot1

大约10%的时间所有星星出现在'乐队'中 ScreenShot2

我认为值得一提的是,即使它们处于狭窄的范围内;他们并非都处于同一个位置。所以它就像它仍然生成一个随机数 - 只是一个很小的。

要重现错误,我只需在浏览器中点击“f5”即可。几乎所有时间,它都按预期工作。很少,我得到乐队。再次点击'f5'将解决问题。

没有张贴巨大的代码墙;我认为这是最相关的代码。它出现在Base类中,我的所有星星都继承自。当每个星星被创建时,它会被调用一次。

Protected Sub SetInitialPosition()
    myElipse.Height = GetStarSize()
    myElipse.Width = GetStarSize()

    _location.X = GetRandom.Next(-1 * Settings.StarEdge, CType(GameCanvas.Width, Integer) + Settings.StarEdge)
    _location.Y = GetRandom.Next(0, CType(GameCanvas.Height, Integer))

    myElipse.Fill = New SolidColorBrush(GetStarColor)

End Sub

我没有看到任何错误。 GetRandom()返回一个单例Random类,我依赖于GameCanvas.Height和GameCanvas.Width是有效的 - 但同样,.Width似乎完全按预期工作。

有没有人对这种行为有可能的解释?生成随机数时是否有任何需要注意的问题?每次我单步执行代码,一切都很好,游戏按预期工作。

如果有帮助我可以发布游戏链接 (http://robdude.weebly.com/cci.html

编辑#1:
以下是GetRandom()

的代码
Protected Shared Function GetRandom() As Random
    If _random Is Nothing Then _random = New Random()

    Return _random
End Function

编辑#2: 我非常感谢每个人对此的想法/建议。

2 个答案:

答案 0 :(得分:4)

我想让这个答案尽可能通用,希望它可能对其他人有所帮助。我已经在这里整合了其他答案(以及对我的问题的实际修复),这可能对那些经历随机生成数字的奇怪行为的人有所帮助。

  

使用不同的随机实例

     

Random类的实例具有关联的种子。一般来说,您希望重用相同的Random实例或确保种子不同。如果您使用相同的种子创建了2个不同的Random实例,则第一个.Next将返回相同的结果。

     

<强>线程安全

     

Random不是线程安全的。

     

条件断点

     

我有时会忘记这是一个选择。在某些情况下,“单步执行代码”的行为将隐藏运行时出现的错误。设置条件断点是检查这一点的好方法。在我的情况下'CType(GameCanvas.Height,Integer)&lt; 750'是我使用的条件。

     

<强>登录

     

同样,对于像这样的bug,日志记录也是非常宝贵的。我不知道为什么在问这个问题之前我没有想到它。

最后,由于我不理解的原因,很少有GameCanvas.Height的值未正确设置。我的理论是,当我创建/定位/调整GameCanvas时,我在其他地方做错了或做得不正确。

逐行逐步执行代码似乎无法解决问题。在我的情况下,比赛场地的大小是固定的;所以不是从GameCanvas控件检查大小 - 我现在从我的Settings对象中拉出它。

感谢团队调试每个人。非常感谢。

答案 1 :(得分:1)

如果GetRandom()每次都返回一个新的Random实例,那么这就解释了这个错误。你应该只有Random的实例。

如果它返回一个新实例,则新实例很有可能在重复调用时获得相同的种子值。如果种子相同,则两个不同的实例将返回相同的“随机”值。