这个洗牌守则如何运作? [关闭]

Posted

技术标签:

【中文标题】这个洗牌守则如何运作? [关闭]【英文标题】:How does this Code for shuffling cards work? [closed] 【发布时间】:2021-11-07 22:12:51 【问题描述】:

我只是想知道这段代码是如何工作的,我对编码很陌生,我想知道它是如何工作的。


    for (int x = 0; x < 53; x++)
    
        int h = rand() % 52;
        int j = rand() % 52;
    
        //   Randomize/shuffle deck
        Deck[52].face = Deck[h].face;
        Deck[52].suit = Deck[h].suit;
        Deck[52].value = Deck[h].value;
    
        Deck[h].face = Deck[j].face;
        Deck[h].suit = Deck[j].suit;
        Deck[h].value = Deck[j].value;
    
        Deck[j].face = Deck[52].face;
        Deck[j].suit = Deck[52].suit;
        Deck[j].value = Deck[52].value;
    

【问题讨论】:

在后台没有发生任何事情。代码中的一切都很清楚。看来您需要了解一副牌中有多少张卡片,以及如何使用调试器逐步执行代码以了解其工作原理。 顺便说一句,这是一个非常糟糕的洗牌算法。 请标记您的编程语言。我认为是 C。 Imo 这就是“写出手写体”导致代码难以理解的地方。 std::swap(Deck[h], Deck[j]); 把噪音消减成名副其实的东西 【参考方案1】:

索引从 0 开始,因此卡片组的底部是卡片组 [51]。他们使用位置 52 作为辅助容器在 Deck[e] 和 Deck[i] 之间进行切换。

【讨论】:

【参考方案2】:

D. Kupra 给出了一个答案,这是如何避免重复卡片的技术核心。我添加了一个试图帮助您可视化“后台发生的事情”的答案,因为它可能会帮助您超越数组索引和变量分配。

它的工作原理是将两张牌交换 53 次,在一个展开的牌组中,比喻只用一只手。

我所说的“散布牌”是指所有的牌都分布在一张宽大的桌子上,如果你拿走一张牌,就会剩下一个空位。 (这与手里拿着一副牌的常用方法形成对比,后者的作用类似于链表数据结构;如果你拿一张牌,两张相邻的牌就会缩小差距。) “只用一只手”是指你不能在移动另一张牌的同时保留一张牌。您只能将一张卡从一个地方移动到另一个地方。 幸运的是,在桌子的最后(见 D. Kupra 的回答),比卡片多一个地方。

选择两张牌,只记住它们在桌子上的位置
int e = rand() % 52;
int i = rand() % 52;
将第一张选定的卡片移动到(当前空闲的)结束位置
Deck[52].face = Deck[e].face;
Deck[52].suit = Deck[e].suit;
Deck[52].value = Deck[e].value;
将第二张选中的卡片移动到第一张选中卡片所在的空闲位置
Deck[e].face = Deck[i].face;
Deck[e].suit = Deck[i].suit;
Deck[e].value = Deck[i].value;
将第一张选中的卡片从当前在表格末尾的位置移动到第二张选中的卡片直到最近所在的位置
Deck[i].face = Deck[52].face;
Deck[i].suit = Deck[52].suit;
Deck[i].value = Deck[52].value;

此时,您仍然可以“看到牌”,它暂时在桌子的最后,比喻在这里有点跛行......

【讨论】:

以上是关于这个洗牌守则如何运作? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

像 Virus Total 这样的网站是如何运作的? [关闭]

什么是好的一次性伪随机洗牌? [关闭]

使用卡片布局更改面板[关闭]

使用 Random 和 OrderBy 是不是是一个好的 shuffle 算法? [关闭]

使用 jQuery 移动 div [关闭]

ubuntu关闭不必要的端口