为什么mt19937生成器每次在while循环中使用时都会生成相同的结果
Why does a mt19937 generator, generate the same result everytime when used in a while loop
我写这个游戏只是为了输入有随机攻击机会的人类和骨骼数量。如果在反复运行程序时输入相同的金额,则会生成相同的金额。为什么每次while循环重新启动时hitChance/随机攻击量都没有变化?当我在while循环中打印attakChance(randGen)时,它会发生变化。为什么randGen不改变战斗获胜者的输出?
#include <iostream>
#include <string>
#include <random>
#include <ctime>
using namespace std;
int getNumSkeletons();
int getNumHumans();
void finishedBattleStats(int numHumans, int startHumans, int numSkeletons, int startSkeletons);
void simulatedBattle(int &numSkeletons, int &numHumans, int &startHumans, int &startSkeletons);
int main() {
int startHumans;
int startSkeletons;
int numHumans;
int numSkeletons;
cout << "------------------------------------nSkeletons V Humansnn";
//Gets Number of Humans
numHumans = getNumHumans();
startHumans = numHumans;
//Gets Number of Skeletons
numSkeletons = getNumHumans();
startSkeletons = numSkeletons;
//Simulates Battle
simulatedBattle(numSkeletons, numHumans, startHumans, startSkeletons);
//End Battle Stats
finishedBattleStats(numHumans, startHumans, numSkeletons, startSkeletons);
cin.get();
return 0;
}
int getNumHumans() {
int numHumans;
cout << "Enter number of Humans: n";
cin >> numHumans;
return numHumans;
}
int getNumSkeletons() {
int numSkeletons;
cout << "Enter number of Skeletons: n";
cin >> numSkeletons;
return numSkeletons;
}
void simulatedBattle(int &numSkeletons, int &numHumans, int &startHumans, int &startSkeletons) {
static mt19937 randGen(time(NULL));
uniform_real_distribution<float> attackChance(0.0f, 1.0f);
//HumanProperties
float humanDamage = 30.0f;
float humanHitChance = 0.6f;
float humanCritChance = 0.2f;
float humanHealth = 50.0f;
float startHumanHealth = humanHealth;
float currentHuman = startHumanHealth;
//Skeleton Properties
float skeletonDamage = 20.0f;
float skeletonHitChance = 0.7f;
float skeletonCritChance = 0.2f;
float skeletonHealth = 40.0f;
float startSkeletonHealth = skeletonHealth;
float currentSkeleton = startSkeletonHealth;
char turn = 'H';
float hitChance;
while (numSkeletons > 0 && numHumans > 0) {
hitChance = attackChance(randGen);
if (turn == 'H') {
if (hitChance > humanHitChance) {
currentSkeleton -= humanDamage;
turn = 'S';
if (currentSkeleton < 0) {
numHumans--;
currentSkeleton = startSkeletonHealth;
turn = 'S';
}
}
}
else {
if (hitChance > skeletonHitChance) {
currentHuman -= skeletonDamage;
turn = 'H';
}
if (currentHuman < 0) {
numSkeletons--;
currentHuman = startHumanHealth;
turn = 'H';
}
}
}
}
void finishedBattleStats(int numHumans, int startHumans, int numSkeletons, int startSkeletons) {
if (numHumans == 0) {
cout << "Skeletons won! nn";
cout << "Skeletons left: " << numSkeletons << endl;
cout << "Skeleton Casualties: " << startSkeletons - numSkeletons << endl;
cout << "All " << startHumans << " humans are dead! nn";
cout << "Game Over!";
cin.get();
}
else {
cout << "Humans Won! nn";
cout << "Humans left: " << numHumans << endl;
cout << "Human Casualties: " << startHumans - numHumans << endl;
cout << "All " << startSkeletons << " skeletons are dead! nn";
cout << "Game Over!";
cin.get();
}
}
IMHO认为您在作战计算中存在缺陷。也就是说,当一个人的健康状况变得<0减去骨骼而不是人类,反之亦然。以下是更正。通过演示。我尝试了很多次演示,并给出了不同的结果(ENJOY):
void simulatedBattle(int &numSkeletons, int &numHumans, int &startHumans, int &startSkeletons) {
uniform_real_distribution<float> attackChance(0.0f, 1.0f);
static mt19937 randGen(time(NULL));
//HumanProperties
float humanDamage = 25.0f;
float humanHitChance = 0.2f;
float humanCritChance = 0.2f;
float humanHealth = 50.0f;
float startHumanHealth = humanHealth;
float currentHuman = startHumanHealth;
//Skeleton Properties
float skeletonDamage = 20.0f;
float skeletonHitChance = 0.8f;
float skeletonCritChance = 0.2f;
float skeletonHealth = 40.0f;
float startSkeletonHealth = skeletonHealth;
float currentSkeleton = startSkeletonHealth;
char turn = 'H';
float hitChance;
while (numSkeletons > 0 && numHumans > 0) {
hitChance = attackChance(randGen);
if (turn == 'H') {
if (hitChance > humanHitChance) {
currentSkeleton -= humanDamage;
if (currentSkeleton < 0) {
--numSkeletons;
currentSkeleton = startSkeletonHealth;
}
turn = 'S';
}
}
else {
if (hitChance > skeletonHitChance) currentHuman -= skeletonDamage;
if (currentHuman < 0) {
--numHumans;
currentHuman = startHumanHealth;
}
turn = 'H';
}
}
}
现场演示
在使用之前,您必须seed
一个mersenne扭曲器,否则您将始终获得相同的输出。通常的做法是用内部时钟来播种:
// obtain a seed from the timer
myclock::duration d = myclock::now() - beginning;
unsigned seed2 = d.count();
generator.seed (seed2);
ref:std::mersenne_twister_engine::seed
相关文章:
- 在更改for循环的第三部分后,未使用for循环结果
- 密码登录程序将永远循环并显示不正确的结果
- 为什么在递归中使用循环会产生意想不到的结果?
- 当我用"ñ"字符循环访问字符串时出现奇怪的结果
- 有没有办法将 for 循环结果返回到像三元运算符这样的函数中?
- 如何在 for 循环中显示一个结果
- 如何修复循环中的错误产生的错误结果?
- 我的循环超时并且不显示结果
- 在 for 循环中仅显示序列的最后一个结果
- C 编程:在循环时运行 2 并从 loop1 获取数据的随机结果
- C++ 3 for 循环中,结果不应重复
- C++ 循环以在表中输出结果
- 循环中的IF-ELSE条件:未来的迭代覆盖以前的迭代结果
- std::chrono 不同的结果 - 固定的时间步长循环
- 如何在 for 循环中取下第一个结果,使其不会重复
- 为什么循环给出的结果与累积的结果不同
- 嵌套循环导致奇怪的结果
- OpenMP循环结果为零
- 在与 OpenMP 并行的嵌套 for 循环中写入共享数组(通过指针)如何产生错误的结果
- 使用For循环显示1个结果