什么时候应该编写自己的随机数算法,而不是使用现成的数学函数?

我正在参加一个使用 Lua 脚本的测试,问题如下:

1.创建一个生成牌组(1-52)的算法。洗牌(不使用 array.randomize() 等)。然后将 5 张牌分给两个不同的玩家。每次发牌时,每张牌都必须分给不同的玩家。

通常,我会像这样获取一个随机数:

local newDeck = {} -- 假设这个数组包含了 52 张扑克牌
math.randomseed(os.time())
local card = math.random(#newDeck)

…但问题明确要求我不使用如此常见的随机函数:

(不使用 array.randomize())

这样做的优势是什么?我无法想象玩家会注意到伪随机和真随机之间的区别。

点赞
用户2380830
用户2380830

如果这只是那么简单就好了。大多数语言中的随机数生成器都是线性同余生成器,这意味着下一个术语J与前一个术语I相关,关系式为

J = (aI + b) mod c

其中,abc是常数。

这意味着从单个数字项可以解密序列!(这是一组含有些技巧的同时方程式,用于处理模数)

我会建议聪明的玩家肯定会注意到你的序列的伪随机性质,甚至可能会通过拆分你的生成器来操纵系统。你需要使用更复杂的方案。(早期尝试包括Park-Miller和Bays-Durham,是比较知名的方法)。

2013-10-26 22:46:06
用户2041077
用户2041077

我相信你可以使用内置的随机数生成器来获取随机数,但禁止使用可能存在的任何内置数组洗牌器。你怎么用随机数生成器使得每张牌在每个位置上都有相等的可能性?

2013-10-27 13:35:18
用户513763
用户513763

你可以编写一个函数,随机选取一张卡牌并将其放入洗牌后的牌堆中:

function shuf(tab)
    local new = {}
    for k=1,#tab do
        new[#new+1]=table.remove(tab,math.random(#tab))
    end
end

这种方法可以确保没有重复的卡牌。

除非你在做加密或其他真正重要的事情,我真的不认为使用不同的 RNG 会有太大区别。

解释问题:只是不要使用为此编写的库函数。但洗牌器和随机数生成器之间存在差异,因为后者可以返回重复的值,而前者无法返回。

2013-10-30 12:20:52