4

java中有一个扑克系统,在Collections.shuffle()发牌之前使用所有可用的牌。

所以收集了 4 种类型的 52 张卡片 2-9、J、Q、K、A。

之后我们Collections.shuffle()

问题是,看起来(直到现在我们还没有大的统计数据,我们可能只看到很多统计推断),算法非常不清楚。

那么,Collections.shuffle()扑克算法可以吗?


评论的答案:“不清楚”我的意思是它在某些时候非常非常神秘。许多用户抱怨“它与现场/其他扑克室不同”。我在这个系统中玩了很多,我必须说,我同意,我在这个系统中看到 3 次 Royal Flashs 在不到 2000 手牌中,并且在现场/在其他扑克室中超过 100.000 手牌,直到今天我看到了 2 次。

4

7 回答 7

9

如果这是一个严肃的扑克应用程序,钱可以转手,简短的回答是否定的。对于这样的事情,您应该真正使用真正随机性的硬件源。

稍长一点的答案是:如果您无法获得硬件来执行真正的随机性,那么如果您提供. 这个解决方案的棘手部分是找到一个好的种子值。Collections.shuffle(List, Random) SecureRandom

更新:根据您的说明,我建议您研究如何播种 PRNG(假设您已经在使用加密安全实现;如果没有,请先这样做)。您应该使用一组有限的种子。其他需要考虑的事项:

  • 您可能应该为每个游戏实例化一个 PRNG
  • 你应该只在双手之间洗牌;从你的问题来看,并不是 100% 清楚你不会在翻牌、转牌、河牌等之间洗牌。
于 2010-04-26T17:23:43.707 回答
6

使用Fisher-Yates 改组算法Collection.shuffle的 O(n) 实现。

并且随机索引是使用 Java 的正常 PRNG 选择的,因此它将大致一致:每一次洗牌的可能性与其他每一次洗牌的可能性一样大。

这对于您想要做的事情来说是完全可以的,但是当您想要真正的随机化时,您应该引入一些真正的随机因素(例如System.currentTimeMillis()用于播种随机数生成器)或更可靠的东西,例如专用硬件。

于 2010-04-26T17:25:13.540 回答
4

好吧,我通常讨厌人们这样对我说,但是是的,不是的。它与 pickrandomcardbetween(1, 52) 一样好,并且在涉及随机性时使用 rand() 函数。

最重要的是,对于任何处理机会或随机值的事情,您都需要适当的硬件,普通计算机甚至无法远程生成任何类型的真正随机结果。

编辑:如果你的扑克系统是为了好玩,那是一回事,但当涉及金钱时,人们会因为你以这种方式创造随机结果而绞死你。

于 2010-04-26T17:20:54.143 回答
4

我建议阅读这篇文章:

我们如何学会在线扑克作弊

作者查看了一个软件包,发现了几个缺陷。一个严重的问题是种子。如果从 32 位种子开始(并且在 shuffle 期间不生成新的独立种子),则只能生成 2^32 个不同的随机序列。52 张牌的牌组有 2^226 次可能的洗牌,这意味着只会产生一小部分可能的牌组顺序。

玩家在翻牌圈知道 5 个牌位(奥马哈中的 7 个)。如果玩家知道洗牌算法,他可以根据他看到的牌猜测候选种子是什么。这使他在推断隐藏牌的概率方面具有很大优势。

于 2010-04-26T17:55:41.743 回答
2

如果这是涉及金钱的严肃扑克软件,那么答案是否定的。(为此,您需要一些真正随机性的来源。)但是,对于简单的情况,它与任何其他算法一样好。

如果您想了解更多关于 shuffle 算法本身的信息,请参阅Java 的 Collections.shuffle 是做什么的?.

于 2010-04-26T17:27:24.707 回答
0

问题是随机生成的数字在统计上是随机的。这意味着洗牌不像一副纸牌,因为它比现实生活中的洗牌更随机。要获得更真实的东西,您需要模拟现实生活中洗牌的方式,例如您切牌的次数等等。我看到一个网站,上面有一张图表,比较了真实骰子的结果和计算机生成的结果,显示结果有多么不同。计算机结果分布更均匀,但我似乎无法在谷歌上找到链接。

于 2010-04-26T18:45:13.007 回答
0

我可以告诉你,这不是大型扑克网站的做法。预洗牌使卡片序列在游戏服务器的某个地方的内存中可用,即如果您可以访问服务器主机(就像操作一样),就可以读取它。取而代之的是,在需要时从卡组中随机挑选卡片(在硬件 RNG 之上使用安全随机)。当你得到“错误的”公共卡时,这有时会让你大吃一惊,因为如果你再等一毫秒再打电话,它们就会不同:)

于 2013-11-10T20:34:03.033 回答