循环程序表现不可预测

时间:2016-05-30 14:49:49

标签: c++ loops

在Puzzlevania的土地上,Aaron,Bob和Charlie有一个争论 他们中的哪一个是有史以来最伟大的益智游戏。结束了 一劳永逸地争论,他们同意了对死的决斗。亚伦是一个 射手很差,只能以1/3的概率命中他的目标。鲍勃是一个 更好一点,并以1/2的概率击中他的目标。查理是一位专家 神射手,永不错过。命中意味着杀戮而该人击中掉落 走出决斗。 为了弥补其射击技巧的不公平性,我们决定 参赛者将从Aaron开始,然后是Bob, 然后是查理。这个循环会重复,直到有一个人站着。 那个人会被记住是有史以来最伟大的益智游戏。  一个明显的策略是每个人以最准确的方式进行射击 射手仍然活着,理由是这个射手是最致命的 最有可能击退。写一个名为的函数 startDuel使用射击功能来模拟整个决斗 使用这种策略。它应该循环直到只剩下一个参赛者, 用适当的目标和概率调用射击功能 根据谁在射击击中目标。功能应该 返回一个变量,表明谁赢得了决斗。

我的程序正常工作,如果我让它循环数百次或数千次但开始表现得很奇怪,就像输出错误的输出并且如果我循环超过一万次就不停地运行。

#include<iostream>
#include<cstdlib>
#include<time.h>


void shoot(bool targetAlive[], double accuracy[],bool round[], int i, int k);
int startDuel(bool notDead[], bool round[],double accuracy[]);
void finding_maximum(bool notDead[],int& Max);
void finding_minimum(bool notDead[],bool haveShot[], int& Min);

int main()
{
    using namespace std;
    int survivor,times(100),times0(0),times1(0),times2(0);
    while (times>0)
    {   
        double acc[3]={1/3.0,1/2.0,1.0}; //accuracy[0] is Aaron, accuracy[1] is Bob, accuracy[2] is Charlie
        bool Alive[3]={true,true,true}; //Alive[0] is Aaron, Alive[1] is Bob, Alive[2] is Charlie
        bool turn[3]={false,false,false}; //turn[0] is Aaron, turn[1] is Bob, turn[2] is Charlie
        survivor=startDuel(Alive,turn,acc);
        if (survivor==0)
        {
            times0++;
        }
        else if (survivor==1)
        {
            times1++;
        }
        else
        {
            times2++;
        }
        cout<<"Dueler number "<<survivor<<" survived the duel\n";
        times--;
    }
    cout<<times0<<" "<<times1<<" "<<times2<<endl;
    return 0;
}

void shoot(bool targetAlive[],double accuracy[],bool round[],int i, int k)
{//i is the one who is shot(highest accuracy), k is the shooter
    using namespace std;
    if (targetAlive[i]==true)
    {   
        srand(time(0));
        double shot;
        shot=(rand()%99+1)/100.0;
        cout<<"the shot is "<<shot<<endl;
        if (shot<accuracy[k])
        {
            cout<<"Dueler number "<<i<<" died"<<endl;
            targetAlive[i]=false;
            round[i]=true;
        }
        else
        {
            cout<<"Dueler number "<<i<<" lived"<<endl;
        }
    }
}

void finding_maximum(bool notDead[],int& Max)
{
    using namespace std;
    for (Max=2;Max>=0;Max--)
    {
        if (notDead[Max]==true)
        {
            break;
        }       
    }
}

void finding_minimum(bool notDead[],bool haveShot[],int& Min)
{
    using namespace std;
    for (Min=0;Min<=2;Min++)
    {
        if (notDead[Min]==true)
        {
            if (haveShot[Min]==false)
            {
                break;
            }
        }
    }
}
int startDuel(bool notDead[], bool round[], double accuracy[])
{
    using namespace std;
    int maximum,minimum;
    do
    {
        finding_maximum(notDead,maximum);
        finding_minimum(notDead,round,minimum);
        while (maximum==minimum)
        {
            for (int n=maximum-1;n>=0;n--)
            {
                if (notDead[n]==true)
                {
                    maximum=n;
                    break;
                }
            }
        }

        cout<<"the shooter is dueler number "<<minimum<<endl;
        cout<<"the target is dueler number "<<maximum<<endl;
        shoot(notDead,accuracy,round,maximum,minimum);
        round[minimum]=true;
        if ((round[0]==true)&&(round[1]==true)&&(round[2]==true))
        {
            round[0]=false;
            round[1]=false;
            round[2]=false;
        }
    } while (((notDead[0]==true)&&(notDead[1]==true)&&(notDead[2]==false))||
             ((notDead[0]==false)&&(notDead[1]==true)&&(notDead[2]==true))||
             ((notDead[0]==true)&&(notDead[1]==false)&&(notDead[2]==true))||
             ((notDead[0]==true)&&(notDead[1]==true)&&(notDead[2]==true)));
    return minimum;
}

1 个答案:

答案 0 :(得分:2)

  1. 即使循环次数较少,我也不认为您的程序正常运行。每当它即将使用srand(time(0))时,它会调用rand。这会将RNG种子每次重置为相同的值(几乎),因此rand每次都会生成相同的序列。较大的times值只会导致执行时间超过一秒(因为您导致rand与当前秒相关联),从而产生不稳定的输出,从而为开始使用bug(下面)。每隔一段时间,当你以低times值执行此操作时,它仍然会脱轨。 srand移至main以获得正确的结果。

  2. 您提出的错误与finding_minimum有关。在某些情况下,它始终会导致Min == 3。一个这样的情况是,如果查理在轮到他之前就死了,其余的投篮都是未命中的。使用Min == 3startDuel无限循环。