PHP洗牌一包卡 [英] php shuffle a pack of cards

查看:72
本文介绍了PHP洗牌一包卡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用php创建随机桥手的集合.我以为我可以将有序卡牌编码为下面的字符串$deal(我喜欢在同时考虑大写和小写的情况下,它有52个字母).我发现了php函数str_shuffle.因此,我认为我可以执行以下操作:

I would like to use php to create a collection of random bridge hands. I thought that I could encode an ordered pack of cards as the string $deal below (I like it that there are 52 letters when considering both upper and lower case). I discovered the php function str_shuffle. So I thought that I could do the following:

$pack = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$shuffledPack = str_shuffle($pack);

这给了我想要的输出.

This gives me the desired output.

我的问题是:str_shuffle是否为每个可能的排列给出遵循均匀分布的输出?

My question is: does str_shuffle give output that follows a uniform distribution for each and every possible permutation?

推荐答案

在内部,str_shuffle()使用rand()不会产生高质量的随机数,正如您在 mt_rand() :

Internally, str_shuffle() uses rand() which doesn't produce good quality random numbers as you can see in this answer; if you want a better distribution, you may wish to implement Fisher-Yates yourself and pick a random source of your choice, e.g. mt_rand():

function my_str_shuffle($str)
{
    if ($str == '') {
        return $str;
    }

    $n_left = strlen($str);

    while (--$n_left) {
        $rnd_idx = mt_rand(0, $n_left);
        if ($rnd_idx != $n_left) {
            $tmp = $str[$n_left];
            $str[$n_left] = $str[$rnd_idx];
            $str[$rnd_idx] = $tmp;
        }
    }

    return $str;
}

另请参阅我之前的答案有关找到合适的0/1随机数的信息.

See also my earlier answer on finding a suitable 0/1 randomiser.

使用 openssl_random_pseudo_bytes() 作为随机来源:

Using openssl_random_pseudo_bytes() as your random source:

assert($n_left <= 255);
$random = openssl_random_pseudo_bytes($n_left);

while (--$n_left) {
    $rnd_index = round($random[$n_left] / 255 * $n_left);
    // ...
}

这篇关于PHP洗牌一包卡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆