我正在Visual Basic 6中制作“猜曲”游戏,该游戏应该以随机顺序播放每首歌曲:

Randomize语句,所以它应该是一个很好的,甚至是随机的。我在正确的轨道上吗?

评论

除了:我的提案中的问题。实际上,我在几年前(2004年)就编写了这段代码,然后才知道更好。

#1 楼

不。您的随机播放不会是随机的。您正在逐步浏览每张卡,然后将其与另一张随机卡交换。这是在许多改组算法中发现的常见错误。

为了说明为什么随机播放不是随机的,我们假设您在随机播放三首歌曲(1、2、3)。三首歌曲(123、132、213、231、321、312)有六种组合。如果您的随机播放是随机的,则这些组合中的每一个都应以相同的概率出现。因此,如果您将随机播放算法运行600,000次,则每个组合应分别出现大约100,000次。当您按顺序运行shuffle算法600,000次时,您将看到类似以下结果:有关编码恐怖:Naïveté的危险。

您需要的是Fisher-Yates随机播放,您可以在其中将当前卡与其余卡(或本身)交换。

此处是就地随机播放的伪代码:

To shuffle an array a of n elements:
  for i from n − 1 downto 1 do
       j ← random integer with 0 ≤ j ≤ i
       exchange a[j] and a[i]


此处列出了其他类型的Fisher-Yates随机播放:维基百科:Fisher–Yates洗牌。

#2 楼

我可能会做这样的事情:

我不知道VB,所以这是伪代码。

您这样做的方式是,有足够的机会撤消洗牌。例如,假设您在索引1处,并且随机数为2。交换1和2。现在假设您在索引2处,并且随机数为1。现在,您只需取消上一次迭代中执行的随机播放。另外,我不喜欢使用全局变量InnerPlaylist。

#3 楼

对于没有严重后果的游戏,您可以运行多次,看看它是否令人满意。对于某些东西,如果它不能很好地进行混洗会产生严重的后果,我认为您不应该怀疑混洗是否足够好,则需要有一种理论来告诉您它足够好(可能是在假设您很满意的情况下)与)。有关此卷第一章“计算机编程艺术”的第2部分提供了大量有关生成随机数以及如何测试随机数的信息。