Mersenne Twister & 在 algorithm.h 中接收语义问题

Mersenne Twister & receiving Semantic Issue in the algorithm.h

我是编程新手,希望这个问题不会成为负担。作为我通过 YouTube 使用的视频教程系列的一部分,该系列使用一系列挑战让学生使用当时的语言部分来解决预定义的问题。在这种情况下,它制作了一个简单的人类与骷髅“1D 战斗模拟器”(LINK: https://youtu.be/TH7plF4UT_E?list=PLSPw4ASQYyynKPY0I-QFHK0iJTjnvNUys)

导师 Ben 最初使用 default_random_engine,但在他对视频的恼怒评论中指出,这是一个糟糕的实施方式,而 mt19937 是更好的选择。 (LINK: https://youtu.be/JGwSEbnJGR0?list=PLSPw4ASQYyynKPY0I-QFHK0iJTjnvNUys&t=138).

我搜索过 Stack Overflow 以及 cplusplus.com 和其他网站等

我在其中任何一个中都找不到有用的提示。大多数 Mersenne Twister 问题似乎与它的使用有关,而不是与任何头文件或库文件有关。 : Issues with c++ 11 mersenne_twister_engine class : : mt19937 and uniform_real_distribution : Why do I get the same sequence for every run with std::random_device with mingw gcc4.8.1?

据我所知,我决定采用 mt19937 的方法来获得更准确、熵更大的随机生成。对于我正在从事的小项目来说,这可能有点矫枉过正,并且愿意接受更好的解决方案。

我经常厌倦大多数 C++ 教程(视频或书籍),因为它们教授语法和词汇,但很少教授使用该语言解决问题。所以,即使我不理解它们,我也会跳来跳去玩弄它们,这样我就可以尝试更好地理解它们。我对功能的理解,就功能的解剖和最佳使用而言,是薄弱的。 类 也是如此。尽管如此,我已经将 met19937 实现到一个函数中,这样我就可以创建各种多面体模具模拟。 (d4、d6、d8、d10)。

我的源代码没有任何错误,但是algorithm.h文件有两个相同类型的错误,如下

Type 'std::__1::mersenne_twister_engine (long)' 不能在 '::' 之前使用,因为它没有成员

当我进入 algorithm.h 文件时(好像我知道我在做什么),这些是发现错误的代码行。

private:
typedef typename _Engine::result_type _Engine_result_type;
typedef typename conditional
    <

tatic _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
                                                  + _Working_result_type(1);

(分别在文件的第 2844 和 2866 行。)

这是我的源代码,我已经注释掉了很多项目,因为我试图在玩弄其余部分之前让一件事情正常工作:

#include <iostream>
#include <string>
#include <random>
//#include <chrono>
//#include <ctime>

using namespace std;

/*
  // Simple Attack and Defense Attributes.
 int Agility = 40;
 int Attack =52;

 int MyAgility = 45;
 int MyAttack = 64;
*/

//Globals
mt19937 randomGenerator(time_t);
//default_random_engine randomGenerator(time_t);

//Function Protypes
void d4();
void d6();
void d8();
void d10();
void SuccessCheck();


int main()
{

    //Variables
    int MyWarriors;
    //int WarriorsAvailable = NULL;
    //int Skeletons = NULL;
    //int CharacterCount;

    /*
    int Attack;
    int Defense;
    int AxeDMG = 1;
    int SwordDMG = 2;
    int ShieldDEF = 1;

    //String Variables
    //Too Many Soldiers Requested
    char str1[150] = "I'm sorry Sire, we just don't have that many troops available.";
    char str2[150] = "No sir! We just can't manage that.";
    char str3[150] = "Oh! Our woes would not be so terrible, should we only have that many in our guard.";
    char str4[150] = "Have you been listening to my counsel? We just can't raise an army that size in such a short time.";
    char str5[150] = "Very well Sir, I suppose we'll perish until you can't give me a real answer.";

    //A Valid Amount of Soldiers Requested
    char str6[150] = "Great! I'll send them through the gates immediately!";
    char str7[150] = "YES! Through the forest, they'll ut down our foes!";
    char str8[150] = "By the Lord Almighty, they shall be vanquished!";
    char str9[150] = "They won't stand a chance!";
    char str10[150] = "No man or beast will rise against you again!";

    //Maybe Not Enough Soldiers Requested
    char str11[150] = "You may need a tad more men, Sire.";
    char str12[150] = "Perhaps, you'd like to join your men, just in case they need help?";
    char str13[150] = "I think we have a few more men you could send, Sire.";
    char str14[150] = "Oh yea, you'll have them quaking in their boots. Much like kittens and babies would. Perhaps you could spare a few more?";
    char str15[150] = "You can't say that I didn't warn you. Maybe send a few more men.";
    */


    //Random number of Skeletons!
    uniform_int_distribution<int> Skeletons (1, 3000);

    //Random number of Skeletons!
    uniform_int_distribution<int> WarriorsAvailable (1, 3000);

    //Invalid MySoldier Selection
    uniform_int_distribution<int> TooManySoldiers (1, 5);

    //Random number of Skeletons!
    uniform_int_distribution<int> RightNumSoldiers (6, 10);

    //Random number of Skeletons!
    uniform_int_distribution<int> ATadMoreSoldiers (11, 15);

    cout << "Sire! There are " << Skeletons(randomGenerator) << " marching toward the castle!" << endl << "We should send out our troops!" << endl;
    cout << "Our registry indicates that we have " << WarriorsAvailable << " who are combat ready!";
    cout << "How many warriors do wich to send out to battle?" << endl;
    cin >> MyWarriors;


    /*
    do {
        <#statements#>
    } while (<#condition#>); (MyWarriors > WarriorsAvailable)
        cout <<  << endl << "How many warriors woudl you like to send in to combat?";


    cout << "Yes, Sire! I will rally " << MyWarriors << " to do battle with our enemy, at once!" << endl << endl;


    */

    return 0;

}


//Dice Functions: Many of these functions cam from a Stack Overflow answer I found weeks prior to joining
void d4(){//function prints a randomly generated number
    //mt19937 randomGenerator(time_t);
    //auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
    uniform_int_distribution<int> d4Die (1, 4);
    int d4Roll = d4Die(randomGenerator); //the generated number is then set equal to an integer for functionality
    cout << d4Roll; //finally, the integer is printed to the screen
}


void d6(){//function prints a randomly generated number
    //mt19937 randomGenerator(time_t);
    uniform_int_distribution<int> d6Die (1, 6);
    int d6Roll = d6Die(randomGenerator); //the generated number is then set equal to an integer for functionality
    cout << d6Roll; //finally, the integer is printed to the screen
}

void d8(){//function prints a randomly generated number
    //mt19937 randomGenerator(time_t);
    uniform_int_distribution<int> d8Die (1, 8);
//the generated number is then set equal to an integer for functionality
    int d8Roll = d8Die(randomGenerator);
    cout << d8Roll; //finally, the integer is printed to the screen
}

void d10(){//function prints a randomly generated number
    //mt19937 randomGenerator(time_t);
    uniform_int_distribution<int> d10Die (1, 10);
    //the generated number is then set  equal to an integer for functionality
    int d10Roll = d10Die(randomGenerator); 
    cout << d10Roll; //finally, the integer is printed to the screen
}

void SuccessCheck(){//function prints a randomly generated number
    //mt19937 randomGenerator(time_t);
     //Success Check based on a percentile roll of (2d10) yielding a 1 - 100%
    uniform_int_distribution<int> SCDie (1, 100);
    //the generated number is then set equal to an integer for functionality
    int SCRoll = SCDie(randomGenerator); 
    cout << SCRoll; //finally, the integer is printed to the screen

}

//Combat Skill Modifier
uniform_int_distribution<int> CmbSklMod (1, 3);

//uniform_real_distribution<float> SucessCheck(0.0f, 1.0f);

你的问题是

mt19937 randomGenerator(time_t);

没有创建随机数生成器。它声明了一个名为 randomGenerator 的函数,它接受一个 time_t 和 returns 一个 mt19937.

你需要做的就是使用类似

的东西
std::random_device rd
std::mt19937 randomGenerator{rd()};

这将创建 PRNG 并使用 rd 中的初始值作为种子。如果你想要更好的种子,那么你可以使用

std::random_device rd;
std::seed_seq seed{rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()};
std::mt19937 randomGenerator(seed);

以上技巧来自bames53 in this answer

谢谢内森!这实际上帮助了很多。输入第一个选项后,我收到了新的错误,下面将解释这些错误以及我是如何解决这些错误的。当然,我怀疑更多经验丰富的程序员会认为这是显而易见的。 :P

错误 使用 class 模板 uniform_int_distribution 需要模板参数

解决代码:

uniform_int_distribution<int> Skeletons (randomGenerator);

错误

uniform_int_distribution 的初始化没有匹配的构造函数 使用未声明的标识符 Skeletons

解决代码:

uniform_int_distribution<int> Skeletons (1, 3000);

其他帮助来自: cppreference.com

最终工作代码片段:

std::random_device rd;
std::seed_seq seed{rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()};
std::mt19937 randomGenerator(seed);

正在使用

//Random number of Skeletons!
uniform_int_distribution<int> Skeletons (1, 3000);

//Random number of Available Warriors!
uniform_int_distribution<int> WarriorsAvailable (1, 3000);

//Invalid MySoldier Selection
uniform_int_distribution<int> TooManySoldiers (1, 5);

//Random number of Skeletons!
uniform_int_distribution<int> RightNumSoldiers (6, 10);

//Random number of Skeletons!
uniform_int_distribution<int> ATadMoreSoldiers (11, 15);

============= Messner-Twister 的可靠性 ===================== 这就是为什么 rd() 在上面的代码中使用如此之多的原因。

是否有更好、更准确的方法?这是一个 'warning' 关于 Messner-Twister 以及在更好地播种之前如何预测它。

Stack Overflow

====================== 间接相关===================== ============

根据我的问题上面发布的代码,我想我会 link 我的骰子函数来自哪里。

http://www.cplusplus.com/forum/beginner/138382/

void d4(){//函数打印一个随机生成的数字 uniform_int_distribution d4Die (1, 4); int d4Roll = d4Die(randomGenerator); //然后将生成的数字设置为等于功能的整数 cout << d4Roll; //最后,整数被打印到屏幕上 }

=======================脚注===================== ================

谢谢你们的帮助。我希望这个答案可以帮助其他不熟悉该语言的人克服 PRGN 的这个或类似问题。无论是对战系统还是角色扮演游戏(RPG),都可能会有用。