簡體   English   中英

為什么MT19937生成器在while循環中使用時每次都會生成相同的結果

[英]Why does a mt19937 generator, generate the same result everytime when used in a while loop

我一直在寫這款游戲,目的是輸入具有隨機攻擊機會的人類和骷髏數量。 如果一遍又一遍地運行程序時輸入的金額相同,則生成的金額相同。 為什么每次while循環重新啟動時,hitChance / random攻擊量都沒有改變? 當我在while循環中打印AttackChance(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 Humans\n\n";

    //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! \n\n";
            cout << "Skeletons left: " << numSkeletons << endl;
            cout << "Skeleton Casualties: " << startSkeletons - numSkeletons << endl;
            cout << "All " << startHumans << " humans are dead! \n\n";
            cout << "Game Over!";
            cin.get();
        }
        else {
            cout << "Humans Won! \n\n";
            cout << "Humans left: " << numHumans << endl;
            cout << "Human Casualties: " << startHumans - numHumans << endl;
            cout << "All " << startSkeletons << " skeletons are dead! \n\n";
            cout << "Game Over!";
            cin.get();
        }
    }

恕我直言,您認為戰斗計算中存在缺陷。 也就是說,當人類的健康狀況<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);

參考: std :: mersenne_twister_engine :: seed

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM