Objectives
We would like to :- Review our coding environment.
- Review the edit-compile-execute cycle.
- See the need for more complex data types.
- Begin thinking about data types and operations
Notes
- Task 2: I would like multiple n sided die that are independent.
- I asked ChatGPT for help
-
prompt: I want to implement two dice with different random number sequences in c++, how do I do this? ChatGPT said: Good question! In C++, if you just use rand() (or a single engine from
), both dice will typically come from the same pseudo-random sequence. To make two dice with independent random number sequences, you need two separate random engines, each with its own seed. Here's how you can do it cleanly using the modern <random> library: #include <iostream> #include <random> int main() { // Create two independent random number engines std::mt19937 rng1(std::random_device{}()); // first RNG seeded std::mt19937 rng2(std::random_device{}()); // second RNG seeded // Uniform distribution for dice (1 to 6) std::uniform_int_distribution<int> dist(1, 6); // Roll each die int die1 = dist(rng1); int die2 = dist(rng2); std::cout << "Die 1: " << die1 << "\n"; std::cout << "Die 2: " << die2 << "\n"; return 0; }Why this works std::mt19937 is a Mersenne Twister engine. Each engine is initialized with a different seed (std::random_device{} generates entropy from the OS). Because they are independent engines, the two dice follow different random sequences. ... - Discuss the problems using this answer.
- I don't know what std::mt19937 is, and generally I am prohibited from using things in class we haven't discussed
- Same with std::uniform_int_distribution
dist(1, 6)
- The linear congruential formula
- $x_0 = seed$ (or 1 if srand is not called).
- $x_{n+1} = (ax_n + c) % m$
- m = $2^{48}$
- a = 0x5DEECE66D
- c = 0xB
- Some of these values might be different in some cases of rand
- But the big problem is that seed is a global variable, and used for ALL calls to rand.
-
- So how does this help?
-
int rand_r(unsigned * seed) - Returns an int between [0 ... RAND_MAX]
- But stores the value of the seed in
seed. -
cout << rand_r(&seed1) << endl;
-
- But how do I initialize the seeds?
- Initialize rand with
time(nullptr) - Then generate each seed with
rand
- Initialize rand with
- Hopefully we end up with code that looks like this:
#include <iostream> #include <iomanip> using namespace std; void RollDieAndPrint(unsigned int seedA, unsigned int seedB); int main() { srand(static_cast<int>(time(nullptr))); unsigned int seed1{static_cast<unsigned int>(rand())}, seed2{static_cast<unsigned int>(rand())}; cout << "Die 1 then Die 2" << endl; RollDieAndPrint(seed1, seed2); cout << endl; cout << "Die 2 then Die 1" << endl; RollDieAndPrint(seed2, seed1); return 0; } void RollDieAndPrint(unsigned int seedA, unsigned int seedB) { int die1, die2; for(int i = 0; i < 10; ++i) { die1 = rand_r(&seedA) % 6 + 1; die2 = rand_r(&seedB) % 6 + 1; cout << setw(20) << die1 << setw(20) << die2 << endl; } } - There are several things that bother me here
-
die1 = rand_r(&seedA) % 6 + 1;
is- Repeated code.
- Does not have much meaning as it stands.
- Is not flexible for multi sided die.
- Write a function that handles this.
- I need to make sure that I always associate die1 and seed1 together.
- And if I pass them to to functions, I need to pass both.
- Put these together in a struct.
-
- I asked ChatGPT for help