当前位置: 首页 > 编程语言 > C#

C#随机数不是“随机的”分享

时间:2023-04-10 14:47:26 C#

问题:publicvoidautoAttack(enemytheEnemy){//获取随机数floatdamage=randomNumber((int)(strength*1.5),(int)(强度*2.5));//减少敌人护甲伤害*=(100/(100+theEnemy.armor));//告诉用户他们造成了多少伤害Console.WriteLine("Youattacktheenemyfor{0}damage",(int)damage);//造成实际伤害theEnemy.health-=(int)damage;//告诉用户敌人还剩下多少生命值Console.WriteLine("Theenemyhas{0}healthleft",theEnemy.health);然后我在这里调用函数(我调用它5次来检查数字是否是随机的):if(thePlayer.input=="fight"){Console.WriteLine("youwanttofight");thePlayer.autoAttack(enemy1);thePlayer.autoAttack(enemy1);thePlayer.autoAttack(enemy1);然而,当我检查输出时,我为3个函数调用中的每一个都得到了完全相同的数字。但是,每次我运行该程序时,我都会得到一个不同的数字(重复3次),如下所示:您攻击敌人造成30点伤害。敌人还剩70点生命值。你攻击敌人造成30点伤害。敌人还剩40点生命值。你攻击敌人造成30点伤害。敌人还剩10点生命值。然后我将重新/重新调试/运行程序并得到一个不同的数字而不是30,但它会重复所有3次。我的问题是:如何确保每次调用此函数时得到不同的随机数?我一遍又一遍地得到相同的“随机”数字。这是我使用的随机类调用:privateintrandomNumber(intmin,intmax){Randomrandom=newRandom();返回random.Next(min,max);我的猜测是randomNumber都会创建一个新的Random实例......它会根据当前时间创建一个新的伪随机数生成器......它不会像你想象的那样经常变化。不要那样做。重复使用相同的Random实例......但不要通过创建静态Random变量来“修复”它。从长远来看,这不会很好地工作,因为Random不是线程安全的。在测试中一切看起来都很好,然后在你碰巧遇到不幸的并发后你神秘地得到了所有零:(幸运的是,使用线程局部变量并不难,特别是如果你使用.NET4。你最终得到一个每个线程的随机新实例。我写了一篇关于这个主题的文章,您可能会觉得有用,包括这段代码:usingSystem;使用系统线程;publicstaticclassRandomProvider{privatestaticintseed=Environment.TickCount;privatestaticThreadLocalrandomWrapper=newThreadLocal(()=>newRandom(Interlocked.Increment(refseed)));publicstaticRandomGetThreadRandom(){returnrandomWrapper.Value;如果您将新的Random()调用更改为RandomProvider.GetThreadRandom(),它可能会完成您需要的一切(同样,假设是.NET4)。这并没有解决可测试性问题,而是一步一步......你没有向我们展示randomNumber的代码。如果它看起来像privateintrandomNumber(intm,intn){Randomrg=newRandom();inty=rg.Next();intz=//使用m和n的一些计算returnz;那么,那是你的问题。如果您不断创建新的Random实例,它们有时可能具有相同的种子(默认种子是系统时钟,其精度有限;创建它们足够快并且它们获得相同的种子)然后生成的序列生成器将始终相同的。要解决此问题,您必须实例化Random实例一次:privatereadonlyRandomrg=newRandom();privateintrandomNumber(intm,intn){inty=this.rg.Next();intz=//使用m和n的一些计算returnz;只是为了澄清另一点,即使你这样做,Random的输出仍然不是“真正的”随机的。这只是伪随机。什么是随机数?通常,伪随机数生成器被播种(带有一些时间相关的东西,或者一些随机的东西,比如两次按键或网络数据包之间的时间)。您没有说明您使用的是哪个生成器,也没有说明它是如何播种的。如果您在循环中生成随机数,它可能不是随机的。因为随机数基本上是在当前系统时间内创建的。所以把这段代码放在一个循环中:Thread.Sleep(10);因此系统将休眠10毫秒。您将获得一个新的随机数。这是一个有保证的解决方案,但它也会影响系统的性能。对象在方法外随机实例化。(randomrandom=newRandom();应该写在method之前)理解random不是随机的也很重要。以上就是C#学习教程:C#随机数并不是“随机”分享的全部内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: