随机生成的具有循环和消除的概率博弈

randomly generated probability game with loops and elimination

本文关键字:概率 博弈 随机 循环      更新时间:2023-10-16

这是我的任务:


在Puzzlevania的土地上,Aaron、Bob和Charlie就他们中的哪一个发生了争执是有史以来最伟大的解谜者。为了一劳永逸地结束争论,他们同意了一场你死我活的决斗。亚伦的投篮很差,只命中了目标1/3。鲍勃稍微好一点,以1/2的概率击中了目标。Charlie是前任-出色的射手,从不失手。被击中意味着被杀,被击中的人退出决斗。为了弥补他们枪法上的不公平,三人决定会轮流出现,先是亚伦,然后是鲍勃,然后是查理。周期会重复,直到有一个人站着。那个人将永远被人们铭记时间是有史以来最伟大的谜题解决者。

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

提示假设亚伦命中目标的几率是1/3。您可以通过以下方式模拟这种概率生成介于1和99之间(包括1和99)的随机变量R。发生这种情况的可能性有多大R小于33?是1/3。你看到这是怎么回事了吗?如果R 33,那么我们可以模拟亚伦击中目标。如果R>33,则他未命中。您还可以生成一个随机变量,并检查其是否小于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行中添加了错误#for,以查看我的错误在哪里。

如果我得到错误1,2,3和6的cout行,程序就会运行。我没有得到一个带有指定赢家的cout。此外,对于这些数字,我有时似乎会得到一个双重结果(即带有该错误的结果和来自程序不同部分的另一个结果),这让我认为我的循环有问题。

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

如果能对我的语法和形式进行评论,我将不胜感激,因为我真的很困惑。

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

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

  2. 在循环中生成随机数。例如,如果rand()给出一个值>= 9900,请将其丢弃,然后重试。把这个循环放在一个函数中,这样你就不必每次都担心它了。

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

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

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

这里的if (b>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未被修改,因此循环再次重复。亚伦可以一次又一次地向鲍勃开枪,直到他最终没打中,鲍勃终于得到了机会,尽管他已经死了。你需要改变你的循环条件——可能在其他情况下也是如此,尽管我还没有检查。我可能会使用done标志。

接下来,ab并不需要单独的变量(我认为您甚至不使用c),只需为random或类似的变量使用单个变量r即可。

最后,我使用的结构是…

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 <whoever>_alive块的相似程度,以及它们如何被分解为一个函数。