Seeding Properly
Get reproducible randomness.
Seeding Properly is a free C++ Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C++ Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is Seeding?
A seed is the starting state of an engine. The same seed reproduces the same sequence; a different seed gives a different one.
#include <iostream>
#include <random>
int main() {
std::mt19937 a(100), b(200);
std::cout << std::boolalpha << (a() == b()) << '\n';
return 0;
}Fixed Seed for Reproducibility
A constant seed makes results repeatable, which is ideal for tests and debugging.
#include <iostream>
#include <random>
int main() {
auto run = [](unsigned s) {
std::mt19937 g(s);
return g() % 1000;
};
std::cout << run(42) << ' ' << run(42) << '\n';
return 0;
}std::random_device
std::random_device provides nondeterministic seeds from the operating system. Use it once to seed your engine.
#include <iostream>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> d(1, 6);
std::cout << "a roll: " << d(gen) << '\n';
return 0;
}Seed Once, Reuse
Seed the engine a single time at startup. Re-seeding before every draw destroys randomness quality.
#include <iostream>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd()); // seed once
std::uniform_int_distribution<int> d(1, 100);
for (int i = 0; i < 3; ++i) std::cout << d(gen) << ' ';
std::cout << '\n';
return 0;
}The Time Seed Pitfall
Seeding with time(nullptr) changes only once per second, so programs started together get the same sequence. Prefer random_device.
#include <iostream>
#include <random>
#include <ctime>
int main() {
std::mt19937 gen(static_cast<unsigned>(std::time(nullptr)));
std::cout << "seeded from time (coarse)\n";
std::cout << (gen() % 100) << '\n';
return 0;
}Seeding with seed_seq
An engine has lots of internal state. std::seed_seq spreads several seed values across all of it for better initialization.
#include <iostream>
#include <random>
int main() {
std::seed_seq seq{1, 2, 3, 4};
std::mt19937 gen(seq);
std::cout << (gen() % 1000) << '\n';
return 0;
}Combining random_device Values
For high-quality seeding, gather several values from random_device into a seed_seq.
#include <iostream>
#include <random>
#include <array>
int main() {
std::random_device rd;
std::array<unsigned, 4> seeds{rd(), rd(), rd(), rd()};
std::seed_seq seq(seeds.begin(), seeds.end());
std::mt19937 gen(seq);
std::cout << "well-seeded engine ready\n";
std::cout << (gen() % 100) << '\n';
return 0;
}Re-seeding Explicitly
You can reset an existing engine with seed(value) to restart its sequence from a known point.
#include <iostream>
#include <random>
int main() {
std::mt19937 gen(1);
unsigned first = gen();
gen.seed(1); // restart
std::cout << std::boolalpha << (gen() == first) << '\n';
return 0;
}Saving and Restoring State
An engine can be streamed out and back in, letting you save and resume an exact random state.
#include <iostream>
#include <sstream>
#include <random>
int main() {
std::mt19937 gen(5);
std::ostringstream save; save << gen;
unsigned expected = gen();
std::istringstream load(save.str());
std::mt19937 restored; load >> restored;
std::cout << std::boolalpha << (restored() == expected) << '\n';
return 0;
}random_device Is Not Reproducible
Because random_device is nondeterministic, never use it when you need to reproduce a run. Use a fixed seed for that.
#include <iostream>
#include <random>
int main() {
const unsigned FIXED = 2026;
std::mt19937 gen(FIXED); // reproducible across runs
std::cout << (gen() % 10000) << '\n';
return 0;
}A Reusable Generator
A common pattern wraps a seeded engine behind a small helper so the rest of the code just asks for numbers.
#include <iostream>
#include <random>
int roll(std::mt19937& gen) {
std::uniform_int_distribution<int> d(1, 6);
return d(gen);
}
int main() {
std::mt19937 gen(2026);
std::cout << roll(gen) << ' ' << roll(gen) << '\n';
return 0;
}Quick Check
Test your understanding of seeding.
Recap
You learned proper seeding:
- a fixed seed gives reproducible runs;
std::random_devicegives unique ones - seed once at startup, not per draw; avoid the coarse
time()seed seed_seqspreads entropy across the engine, and engine state can be saved/restored via streams
Next, you'll apply all this to practical examples.
Frequently asked questions
Is the “Seeding Properly” lesson free?
Yes — the full text of “Seeding Properly” is free to read here on the web, and the C++ Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C++ Academy course, upgrade to CoddyKit PRO.
What will I learn in “Seeding Properly”?
Get reproducible randomness. You practise C++ Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C++ Academy?
No prior experience is required. C++ Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Seeding Properly” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C++ Academy lesson?
Yes. Every C++ Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Random Engines
- Distributions
- Seeding Properly
- Practical Examples