【问题标题】:randomly generated probability game with loops and elimination [closed]具有循环和消除的随机生成概率游戏[关闭]
【发布时间】:2013-02-06 08:02:00
【问题描述】:

这是我的任务:


在 Puzzlevania 的土地上,亚伦、鲍勃和查理为他们中的哪一个发生了争执 是有史以来最伟大的解谜者。为了一劳永逸地结束争论,他们同意 在生死决斗中。亚伦的射门很差,只有 1/3。 Bob 稍微好一点,以 1/2 的概率击中了他的目标。查理是前任 完美的神射手,从未错过。击中意味着杀死,被击中的人退出决斗。 为了弥补枪法上的不公平,三人决定 将轮流进行,从 Aaron 开始,然后是 Bob,然后是 Charlie。循环 会重复,直到有一个人站着。那个男人会被所有人铭记 成为有史以来最伟大的解谜者。

一个明显而合理的策略是让每个人仍然向最准确的射手射击 活着,理由是这个射手是最致命的,并且有最好的反击机会。 编写一个程序来模拟使用这种策略的决斗。你的程序应该使用随机 问题中给出的数字和概率来确定射手是否击中他的 目标。您可能需要创建多个子例程和函数来完成 问题。

提示 假设 Aaron 击中目标的几率是 1/3。您可以通过以下方式模拟此概率 生成一个介于 1 和 99 之间的随机变量 R。发生的概率是多少 R小于33?是 1/3。你知道这会导致什么吗?如果 R 33,那么我们可以 模拟 Aaron 击中目标。如果 R > 33,那么他错过了。也可以随机生成 0 到 1 之间的变量,并检查它是否小于 0.33。


这是我从头重写两次后终于能够编写的代码:

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;


int main ()
{
    int aaron=1, bob=1,charlie=1, a=0,b=0,c=0,counter=0;
    srand(time(0));
    a= rand() % 100;
    if (a<=33)//if aaron kills charlie
    {
        charlie=0;

        b= rand() % 100; //bob choots at aaron
        if (b<=50)  //if bob kills aaron
        {
            aaron=0;
            cout<<"error1"<<endl;
        }
        else if (b>50)
        {
            while (b>50) //if bob misses
            {
                a= rand() % 100; //aaron shoots at bob
                if (a<=33)// if he kills bob
                {
                    bob=0;
                    cout<<"error2"<<endl;
                }
                else //if he misses
                {
                    b= rand() % 100;//bob shoots at aaron

                    if (b<=50)//if he kills him
                    {
                        aaron=0;
                        cout<<"error3"<<endl;
                    }
                    else //if he misses then the loop continues
                    {
                        counter++;
                    }
                }
            }
        }
    }
    else if (a>33)//aaron misses
    {
        b= rand() % 100; //bob shoots at charlie
        if (b<=50) //he kills charlie
        {
            charlie = 0;
            a= rand() % 100; //aaron shoots at bob
            if (a<=33)//aaron kills bob
            {
                bob=0;
                cout<<"error4"<<endl;
            }
            else //if not
            {
                b= rand() % 100;//bob shoots at aaron
                if (b<=50) // if he kills aaron
                {
                    aaron=0;
                    cout<<"error5"<<endl;
                }
                else if (b>50)
                {
                    while (b>50)//if not then begin loop
                    {
                        a= rand() % 100; //aaron shoots at bob
                        if (a<=33) //if he kills him
                        {
                            bob=0;
                            cout<<"error6"<<endl;
                        }
                        else
                        {
                            b= rand() % 100;;   //if not bob shoots at aaron
                            if (b<=50)// if he kills aaron
                            {
                                aaron=0;
                                cout<<"error7"<<endl;
                            }
                            else
                            {
                                counter++; //if not loop around
                            }
                        }

                    }
                }
            }
        }

        else //he misses so charlies kills bob
        {
            bob=0;
            a= rand() % 100; //aaron shoots at charlie
            if (a<=33) //aaron kills charlie
            {
                charlie=0;
                cout<<"error8"<<endl;
            }
            else // or charlie kills aaron
            {
                aaron=0;
                cout<<"error9"<<endl;
            }
        }


        if (charlie==0 && bob==0)
        {
            cout<<"Aaron wins."<<endl;
        }
        else if (aaron==0 && bob==0)
        {
            cout<<"Charlie wins."<<endl;
        }
        else if (charlie==0 && aaron==0)
        {
            cout<<"Bob wins."<<endl;
        }
    }

    return 0;
}

我在 cout 行中添加了 error#,以便在我编译程序时查看我的错误在哪里。

如果我得到错误 1、2、3 和 6 的 cout 行,程序将继续运行,我没有得到一个带有命名获胜者的 cout。此外,对于这些数字,我似乎有时会得到双重结果(即一个错误的结果和另一个来自程序不同部分的结果)导致我假设我的循环存在问题。

我选择使用循环而不是递归函数,因为它超出了赋值范围。

如果我真的很难过,我将不胜感激任何对我的语法和形式的评论。

【问题讨论】:

  • 旁注:如果您应该具有均匀分布,您可能希望选择使用均匀分布 RNG 算法。如果你可以使用 C++11,&lt;random&gt; 已经为你提供了这样的发行版,即std::uniform_int_distribution。设置有点奇怪,但最终值得。请注意,rand()%100 不会为您提供统一分布。
  • 另外,rand () % 100 给出的值是 0..99,而不是问题似乎要求的 1..99,所以即使分布均匀,&lt;=33 也会给出 34%案例。 rand () % 3 == 0 在这种情况下会更准确 - 避免额外的 1% 并减少但不消除使用 % 的错误(提示 - 随机数的范围可能不能被 3 或 100 整除,或者99 所以较低值的余数出现的频率略高)。

标签: c++ loops random probability


【解决方案1】:

第一点 - a= rand() % 100; 不包含 1..99,而是包含 0..99。您可以改用a = (rand() % 99) + 1。这仍然不是一个完全均匀的分布,因为rand 给出的随机数范围可能不能被 99 整除。可能的修复包括...

  1. 按照 WhozCraig 的建议使用 C++11 随机数库。

  2. 在循环中生成随机数。例如,如果rand() 给出了值&gt;= 9900,则将其丢弃并重试。把这个循环放在一个函数中,这样就不用每次都操心了。

  3. 别担心 - 对于这样的事情,如果你应该关心这个问题,你可能已经被警告过了。

下一点是针对诸如...之类的代码

if (b<=50)  //if bob kills aaron
{
    aaron=0;
    cout<<"error1"<<endl;
}
else if (b>50)

这里的if (b&gt;50) 是完全多余的,至少对编译器来说是这样。考虑到您在这里有相当长的代码块并带有一些深层嵌套,您可能会为了清楚起见将其包含在内,但我会将其作为注释,并让 else 完成它的工作。

不过,这可能是你真正的问题......

while (b>50) //if bob misses
{
    a= rand() % 100; //aaron shoots at bob
    if (a<=33)// if he kills bob
    {
        bob=0;
        cout<<"error2"<<endl;
    }
    else //if he misses
    {
        b= rand() % 100;//bob shoots at aaron

        if (b<=50)//if he kills him
        {
            aaron=0;
            cout<<"error3"<<endl;
        }
        else //if he misses then the loop continues
        {
            counter++;
        }
    }
}

如果 Aaron 向 Bob 开枪,b 未修改,因此循环再次重复。 Aaron 可以一遍又一遍地射击 Bob,直到他最终没有射中,即使 Bob 已经死了,他也终于得到了转身。你需要改变你的循环条件——可能在其他情况下也是如此,尽管我没有检查过。我可能会使用done 标志。

接下来,ab 不需要单独的变量(而且我认为您甚至没有使用 c) - 只需将单个变量 r 用于 random或类似的。

最后,我要使用的结构是……

while num_alive > 1
  if aaron_alive
    if charlie_alive
      aaron tries to shoot charlie
    else
      aaron tries to shoot bob

  if bob_alive
    if charlie_alive
      bob tries to shoot charlie
    else
      bob tries to shoot aaron

  if charlie_alive
    if bob_alive
      charlie tries to shoot bob
    else
      charlie tries to shoot aaron

这里的重点是,如果您试图在控制流中记住太多关于谁活着谁死了的信息,代码就会变得复杂。在下一次迭代中再次检查似乎是不必要的工作,但这些检查是微不足道的,即使它们不是过早的优化。你应该更喜欢更简单的代码。

在这种情况下,您还可以查看这三个 if &lt;whoever&gt;_alive 块有多相似,以及它们如何被分解为一个函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    • 2018-11-03
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多