Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 我什么时候应该编写自己的随机数算法而不是使用股票数学函数?_Algorithm_Random_Lua - Fatal编程技术网

Algorithm 我什么时候应该编写自己的随机数算法而不是使用股票数学函数?

Algorithm 我什么时候应该编写自己的随机数算法而不是使用股票数学函数?,algorithm,random,lua,Algorithm,Random,Lua,因此,我正在Lua中进行脚本测试,我被问到以下问题: 创建一个算法来生成一副牌,1-52。洗牌牌(不要使用类似array.randomize()的东西)。然后将5张牌分发给两个不同的玩家。因为每张牌一次必须发给不同的玩家 通常我会这样做来得到一个随机数 local newDeck = {} --assume this array has all 52 cards in a playing deck math.randomseed( os.time() ) local card = math.ra

因此,我正在Lua中进行脚本测试,我被问到以下问题:

  • 创建一个算法来生成一副牌,1-52。洗牌牌(不要使用类似array.randomize()的东西)。然后将5张牌分发给两个不同的玩家。因为每张牌一次必须发给不同的玩家
  • 通常我会这样做来得到一个随机数

    local newDeck = {} --assume this array has all 52 cards in a playing deck
    math.randomseed( os.time() )
    local card = math.random(#newDeck)
    
    …但问题似乎是特别要求我不要使用股票数学函数

    (不要使用类似于array.randomize()的东西)


    这样做有什么好处?我无法想象这样一个游戏的玩家会注意到随机和伪随机之间的区别。

    如果它这么简单的话。作为语言一部分的大多数随机数生成器都是线性同余生成器,这意味着下一个术语
    J
    与前一个术语
    I
    相关

    J = (aI + b) mod c
    
    其中,
    a
    b
    c
    是常数

    这意味着可以从一位数的术语中破译序列(这是一组联立方程组,在处理模数时有点技巧)


    我想说,一个精明的玩家一定会注意到你的序列的伪随机性,甚至可能通过取消你的生成器来玩这个系统。你需要使用更复杂的方案。(早期的尝试包括Park Miller和Bays Durham;相当有名的方法)。

    我相信欢迎您使用内置随机数生成器获取随机数,但禁止使用任何可能存在的内置阵列洗牌器。您如何使用rng使每张牌在每个位置的可能性相等?

    您只需写一些东西,抽取一张随机牌并将其放入洗牌组:

    function shuf(tab)
        local new = {}
        for k=1,#tab do
            new[#new+1]=table.remove(tab,math.random(#tab))
        end
    end
    
    这种方法确保你没有替身

    我真的不认为使用不同的RNG会有那么大的影响,除非你在做密码学或其他真正重要的事情


    解释问题:只是不要使用为此编写的库函数。但是洗牌器和随机数生成器之间有区别,因为后者可以返回双倍值,而前者不能。

    我不确定你在最后一部分中问的是什么,因为计算机无法真正创建某种意义上非伪随机的东西。事实上,人类是否能做到这一点是有争议的(它涉及到整个命运/命运的事情…深层次的东西)。这个问题听起来像你应该使用股票随机函数,而不是洗牌部分。这一点是为了让您了解如何洗牌数组(提示:Fisher-Yates)以获得更实际的答案:大多数标准库中包含的PRNG都很糟糕。因此,每当您需要高质量的随机性时,您都需要将其替换为一个像样的实现。对于在线游戏,你甚至需要使用加密PRNG,因为其他玩家可能会作弊。@ShashankGupta-你是对的。这句话措词不当。这都是伪随机的。我应该说一下自定义随机化算法和lua库随机化器之间的区别。@CodesInChaos-很高兴知道。我甚至没有意识到有加密PRNG这样的东西,我会尝试Fisher-Yates…但是如果我的随机种子是基于系统时钟的,玩家难道不需要一只眼睛盯着时钟并注意到当前时间和15张卡之间的连接才能注意到它是伪的吗?我仍然无法想象这会发生。@PHazer说这是可能的。有人为口袋妖怪游戏破解任天堂DS时钟,滥用RNG获得闪亮的口袋妖怪(他们出现的机会非常少,但已经有程序从生成器中计算种子并预测未来的数字)。这些程序根据用户输入的时间工作,即启动口袋妖怪游戏的时间。“这真的取决于某人对你的游戏有多热衷。”沙尚古普塔说得对,但NDS的时钟精度仅为秒,而不是毫秒。我并不是说这是不可能的,只是说任天堂把他们的实现搞砸了,让它变得比应该的更可利用。