在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;
}
答案 0 :(得分:2)
即使循环次数较少,我也不认为您的程序正常运行。每当它即将使用srand(time(0))
时,它会调用rand
。这会将RNG种子每次重置为相同的值(几乎),因此rand
每次都会生成相同的序列。较大的times
值只会导致执行时间超过一秒(因为您导致rand
与当前秒相关联),从而产生不稳定的输出,从而为开始使用bug(下面)。每隔一段时间,当你以低times
值执行此操作时,它仍然会脱轨。 将srand
移至main
以获得正确的结果。
您提出的错误与finding_minimum
有关。在某些情况下,它始终会导致Min == 3
。一个这样的情况是,如果查理在轮到他之前就死了,其余的投篮都是未命中的。使用Min == 3
,startDuel
无限循环。