用平局抛硬币更好?

Better coin toss with a draw?

我正在为我的聊天机器人制作一个抛硬币游戏,我认为将硬币落在一边的情况非常罕见,这会很有趣。根据这篇文章,一枚美国镍币的几率约为 6000 分之一:

Extrapolations based on the model suggest that the probability of an American nickel landing on edge is approximately 1 in 6000 tosses.

我创建了一个可行的解决方案,但对一侧或另一侧来说很重,在我的最后一个 运行 中,它对正面结果很重要(从零到 3 次迭代的前 10 个结果平局:11 个反面,19 个正面):

Tails. Tails. Heads. Heads. Tails. Tails. Heads. Heads. Heads. - Toss 11666 was a draw.
Heads. Tails. Tails. Heads. Heads. Tails. Tails. Tails. Heads. - Toss 6135 was a draw.
Heads. Tails. Heads. Heads. Heads. Tails. Heads. Heads. Heads. - Toss 24100 was a draw.

此代码非常简单,尽管它允许抽奖 表面上 发生的频率低于 大约 6,000 次迭代中的 1 次 由于对 58006200 之间的随机数使用模数:

int result = _random.Next(2);
if (++_tossCount % _random.Next(5800, 6200) == 0) {
    result = 2;
    _tossCount = 0;
}

switch (result) {
    case 0: return "Heads.";
    case 1: return "Tails.";
    default: return "It was a draw!";
}

_random_tossCount是class中的字段,在构造函数中分别初始化为new Random()0它们可以在main的开头初始化,但是在迭代器之外用于复制在控制台应用程序中的目的)。上面的代码是一个返回 string 的方法,可以在您选择的迭代器中调用它来复制该过程。我使用 do-while 进行测试,但 for 仍然可以正常工作。


我怎样才能提高在正面和反面之间平均分配结果的概率,以及大约每 6000 次调用一次平局?

为了获得正确的赔率,您可以创建一个介于 1 和 12000 之间的随机数,其中各种结果由范围表示:

enum CoinTossResult { Heads, Tails, Draw };
CoinTossResult TossCoin()
{
    return _random.Next(1, 12000) switch
    {
        <= 5999 => CoinToss.Heads,
        <= 11998 => CoinToss.Tails,
        _ => CoinToss.Draw
    };
}

平局的概率现在是 6000 分之一。正面和反面平分 6000 中剩余的 5999。


注意:使用的语法仅在C# 8 and higher.中可用