为什么随机选择不从头开始选择一些数字?

why does pick random doesnt pick some numbers in scratch?

我正在从头创建一个迷你 housie 游戏,我使用随机选择块在 1 到 27 之间进行选择。我有 27 个背景,上面写着 1 到 27 个数字。但是我注意到,在大约 21-22 个数字之后,随机选择器无法选择任何剩余的数字。下面是我的代码的样子 -

我如何修复此代码以确保它随机选择从 1 到 27 的所有内容?

您的问题是由于 "contains" 块的工作方式造成的。很自然地假设它将您给它的值与列表中的每个值进行比较,如果匹配则计算为 "true",如果不匹配则计算为 "false"。但不幸的是,这不是它的作用。相反,它将列表视为通过连接列表中的所有元素(用 space 分隔每个元素)形成的单个字符串,然后 then 检查是否你问的东西包含在列表中是在那个字符串中。

如果您 运行 这个片段:

,您可以看到它的实际效果

您会发现您的 sprite 实际上会说 "Hello",即使列表中绝对没有任何地方包含“2 3”!

在您的脚本中,这具有排除一些个位数的效果,具体取决于选择数字的顺序。例如,号码 1 被选中的可能性很小,因为几乎一半您 可以 挑选的号码中都有数字 1。同样 2。其他数字被排除的机会要低得多,但这是一个非零的机会,并且至少其中一些人会出于同样的原因而被排除。

换句话说,当您选择了 27 个号码中的大约 20 到 22 个时,剩余的号码将被视为已被选中,即使它们并未被选中。

如果您实施适当的 "contains" 块,您可以让您的脚本运行,如下所示:

然后你可以像这样在你的主脚本中使用它:

综上所述,您选择随机数的方法并不理想,因为您必须进行此循环并反复选择和忽略一些数字,随着循环的进行越来越多。如果您开始不得不从更大范围的数字中进行选择,这可能会变得非常棘手。

作为一个合适的 "shuffle" 实施会更好。为此有一个标准算法,称为 Fisher-Yates shuffle。本质上,您使用要选择的所有数字初始化列表,从第一个元素开始,选择一个随机的其他元素与该元素交换(可以选择您所在的元素),交换值,然后移动到下一个元素。在每次迭代中,您只会从列表中剩余的元素中选择一个新元素。

我将 Scratch 程序中 Fisher-Yates shuffle 的实现留给您和其他读者。这是一个很好的编程练习。 :)