39. Random
Learn how to generate random numbers, colors, and coordinates, or randomly select elements from multiple choices.
39.1 Random Number Overview
- Siv3D provides the following functionality related to random numbers:
- Random number engine classes that generate random numbers
- Distribution classes that distribute random numbers to specific distributions
- Random number functions implemented by combining these
- Unless otherwise specified, Siv3D uses a global random number engine secured internally for each thread
- The seed value of the global random number engine is determined by non-deterministic hardware noise, so it generates different random number sequences each time the program is run
- When random number reproducibility is needed, give a fixed seed to the random number engine, or create a random number engine object with a fixed seed and pass it to random number functions
39.2 Random Numbers with Specified Range (1)
Random<Type>(max)
returns a random value of Type
in the range from 0 to max
Random<Type>(min, max)
returns a random value of Type
in the range from min to max
- For integers, values in the range
[min, max]
are returned; for floating-point numbers, values in the range [min, max)
are returned

# include <Siv3D.hpp>
void Main()
{
while (System::Update())
{
if (SimpleGUI::Button(U"int32", Vec2{ 200, 20 }, 120))
{
ClearPrint();
for (int32 i = 0; i < 10; ++i)
{
// Random integer in range 0-100
Print << Random(100);
}
}
if (SimpleGUI::Button(U"double", Vec2{ 200, 60 }, 120))
{
ClearPrint();
for (int32 i = 0; i < 10; ++i)
{
// Random floating-point number in range -100.0 to 100.0
Print << Random(-100.0, 100.0);
}
}
if (SimpleGUI::Button(U"char32", Vec2{ 200, 100 }, 120))
{
ClearPrint();
for (int32 i = 0; i < 10; ++i)
{
// Random character in range A-Z
Print << Random(U'A', U'Z');
}
}
}
}
39.3 Random Numbers with Specified Range (2)
- Random number generation functions corresponding to specific integer type ranges are provided
Type |
Function |
Value Range |
int8 |
RandomInt8() |
-128 to 127 |
uint8 |
RandomUint8() |
0 to 255 |
int16 |
RandomInt16() |
-32768 to 32767 |
uint16 |
RandomUint16() |
0 to 65535 |
int32 |
RandomInt32() |
-2147483648 to 2147483647 |
uint32 |
RandomUint32() |
0 to 4294967295 |
int64 |
RandomInt64() |
-9223372036854775808 to 9223372036854775807 |
uint64 |
RandomUint64() |
0 to 18446744073709551615 |

# include <Siv3D.hpp>
void Main()
{
while (System::Update())
{
if (SimpleGUI::Button(U"int8", Vec2{ 200, 20 }, 120))
{
ClearPrint();
for (int32 i = 0; i < 10; ++i)
{
// Random integer in int8 range
Print << RandomInt8();
}
}
if (SimpleGUI::Button(U"uint8", Vec2{ 200, 60 }, 120))
{
ClearPrint();
for (int32 i = 0; i < 10; ++i)
{
// Random integer in uint8 range
Print << RandomUint8();
}
}
if (SimpleGUI::Button(U"uint32", Vec2{ 200, 100 }, 120))
{
ClearPrint();
for (int32 i = 0; i < 10; ++i)
{
// Random integer in uint32 range
Print << RandomUint32();
}
}
}
}
39.4 Global Random Engine Seed Initialization
- To initialize the global random engine with a new seed, use
Reseed(uint64 seed)
- If the seed is the same, the generated random number pattern will be the same

# include <Siv3D.hpp>
void Generate()
{
for (int32 i = 0; i < 10; ++i)
{
Print << Random(1, 6);
}
}
void Main()
{
while (System::Update())
{
if (SimpleGUI::Button(U"seed 1", Vec2{ 200, 20 }, 120))
{
ClearPrint();
Reseed(123456789ull);
Generate();
}
if (SimpleGUI::Button(U"seed 2", Vec2{ 200, 60 }, 120))
{
ClearPrint();
Reseed(3333333333ull);
Generate();
}
if (SimpleGUI::Button(U"seed 3", Vec2{ 200, 100 }, 120))
{
ClearPrint();
Reseed(55555555555555ull);
Generate();
}
}
}
39.5 Creating Independent Random Engine Objects
- You can create random engine objects independent from the global random engine and use them with random functions
- For most purposes, using the
SmallRNG
class provides sufficient quality random numbers
SmallRNG
is initialized with a uint64
type seed value
- By passing a random engine object as the last argument to various random functions, that random engine is used instead of the global random engine

# include <Siv3D.hpp>
void Generate(uint64 seed)
{
SmallRNG rng{ seed };
for (int32 i = 0; i < 10; ++i)
{
Print << Random(1, 6, rng);
}
}
void Main()
{
while (System::Update())
{
if (SimpleGUI::Button(U"seed 1", Vec2{ 200, 20 }, 120))
{
ClearPrint();
Generate(123456789ull);
}
if (SimpleGUI::Button(U"seed 2", Vec2{ 200, 60 }, 120))
{
ClearPrint();
Generate(3333333333ull);
}
if (SimpleGUI::Button(U"seed 3", Vec2{ 200, 100 }, 120))
{
ClearPrint();
Generate(55555555555555ull);
}
}
}
39.6 50% Probability
RandomBool()
returns true
with 50% probability and false
with 50% probability each time it's called

# include <Siv3D.hpp>
void Main()
{
while (System::Update())
{
if (SimpleGUI::Button(U"Generate", Vec2{ 200, 20 }))
{
ClearPrint();
for (int32 i = 0; i < 10; ++i)
{
// 50% probability true, 50% probability false
Print << RandomBool();
}
}
}
}
39.7 Returning true
with Specified Probability
RandomBool(p)
returns true
with probability p
and false
with probability (1 - p)
each time it's called
- If you want
true
with 10% probability, p
is 0.1
- If you want
true
with 25% probability, p
is 0.25

# include <Siv3D.hpp>
void Main()
{
while (System::Update())
{
if (SimpleGUI::Button(U"10 %", Vec2{ 200, 20 }, 120))
{
ClearPrint();
for (int32 i = 0; i < 10; ++i)
{
Print << RandomBool(0.1);
}
}
if (SimpleGUI::Button(U"50 %", Vec2{ 200, 60 }, 120))
{
ClearPrint();
for (int32 i = 0; i < 10; ++i)
{
Print << RandomBool(0.5);
}
}
if (SimpleGUI::Button(U"80 %", Vec2{ 200, 100 }, 120))
{
ClearPrint();
for (int32 i = 0; i < 10; ++i)
{
Print << RandomBool(0.8);
}
}
}
}
39.8 Random Colors
RandomColorF()
generates a random color and returns it as a ColorF
type
- Colors are generated by
HSV{ Random(360.0), 1.0, 1.0 }
, so pale colors, dark colors, white, or black are not generated

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(Palette::White);
Array<ColorF> colors(10);
for (auto& color : colors)
{
color = RandomColor();
}
while (System::Update())
{
if (SimpleGUI::Button(U"Generate", Vec2{ 40, 40 }))
{
for (auto& color : colors)
{
color = RandomColor();
}
}
for (size_t i = 0; i < colors.size(); ++i)
{
Circle{ (40 + i * 80.0), 200, 30 }
.drawShadow(Vec2{ 2, 2 }, 12, 1)
.draw(colors[i]);
}
}
}
39.9 Random Coordinates
- Functions to generate random point coordinates on specified shapes are provided
Code |
Description |
RandomVec2(const Line&) |
Returns random point coordinates on the specified line segment |
RandomVec2(const Circle&) |
Returns random point coordinates on the specified circle |
RandomVec2(const RectF&) |
Returns random point coordinates on the specified rectangle |
RandomVec2(const Triangle&) |
Returns random point coordinates on the specified triangle |
RandomVec2(const Quad&) |
Returns random point coordinates on the specified quadrilateral |

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Rect rect{ 100, 150, 300, 200 };
const Circle circle{ 600, 400, 150 };
Array<Vec2> rectPoints(100);
Array<Vec2> circlePoints(100);
for (auto& point : rectPoints)
{
point = RandomVec2(rect);
}
for (auto& point : circlePoints)
{
point = RandomVec2(circle);
}
while (System::Update())
{
if (SimpleGUI::Button(U"Generate", Vec2{ 40, 40 }))
{
for (auto& point : rectPoints)
{
point = RandomVec2(rect);
}
for (auto& point : circlePoints)
{
point = RandomVec2(circle);
}
}
rect.draw(ColorF{ 0.2 });
circle.draw(ColorF{ 0.2 });
for (const auto& point : rectPoints)
{
point.asCircle(3).draw(ColorF{ 0.2, 1.0, 0.4 });
}
for (const auto& point : circlePoints)
{
point.asCircle(3).draw(ColorF{ 0.2, 0.4, 1.0 });
}
}
}
39.10 Random Vectors
- Functions to generate random two-dimensional vectors with specified lengths are provided
Code |
Description |
RandomVec2() |
Returns a vector with length 1.0 and random direction |
RandomVec2(double) |
Returns a random vector with the specified length |

Drawing lines while moving in random directions by 30 pixels each time# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
LineString lines = { Vec2{ 400, 300 } };
while (System::Update())
{
if (SimpleGUI::Button(U"Move", Vec2{ 40, 40 }))
{
// Add new point moved 30 pixels
lines << (lines.back() + RandomVec2(30));
}
lines.draw(2, ColorF{ 0.2 });
lines.back().asCircle(5).draw(Palette::Seagreen);
}
}
39.11 Random Elements from Array
- The
Array
member function .choice()
returns a reference to a random element in the array
- Cannot be used on empty arrays

# include <Siv3D.hpp>
void Main()
{
const Array<String> options =
{
U"Red", U"Green", U"Blue", U"Black", U"White"
};
while (System::Update())
{
if (SimpleGUI::Button(U"Choice", Vec2{ 200, 40 }))
{
// Return random element
Print << options.choice();
}
}
}
39.12 Multiple Random Elements from Array
Array
's .choice(N)
selects N random elements from the array without duplication and returns them as an array
- The order of elements in the result array is the same as their order in the original array

# include <Siv3D.hpp>
void Main()
{
const Array<int32> coins =
{
1, 2, 5, 10, 20, 50, 100, 500
};
while (System::Update())
{
if (SimpleGUI::Button(U"Choice", Vec2{ 200, 40 }))
{
// Return 3 random elements
Print << coins.choice(3);
}
}
}
39.13 Array Shuffling
Array
's .shuffle()
randomly shuffles the order of array elements
.shuffled()
creates and returns a new shuffled array without changing itself

# include <Siv3D.hpp>
void Main()
{
Array<String> cities =
{
U"Guangzhou", U"Tokyo", U"Shanghai", U"Jakarta",
U"Delhi", U"Metro Manila", U"Mumbai", U"Seoul",
U"Mexico City", U"São Paulo", U"New York City", U"Cairo",
};
while (System::Update())
{
if (SimpleGUI::Button(U"Shuffle", Vec2{ 200, 100 }))
{
ClearPrint();
// Shuffle element order
cities.shuffle();
Print << cities;
}
}
}
39.14 Randomly Selecting One
Sample({...})
randomly selects and returns one element from the list {...}
of choices

# include <Siv3D.hpp>
void Main()
{
while (System::Update())
{
if (SimpleGUI::Button(U"Sample", Vec2{ 200, 40 }))
{
// Randomly select
Print << Sample({ 1, 2, 5, 10, 20, 50, 100, 500 });
}
}
}
39.15 Randomly Selecting Multiple
Sample(N, {...})
randomly selects and returns N elements from the list {...}
of multiple choices
- The order of elements in the result array is the same as their order in the list

# include <Siv3D.hpp>
void Main()
{
while (System::Update())
{
if (SimpleGUI::Button(U"Sample", Vec2{ 200, 40 }))
{
// Randomly select 3
Print << Sample(3, { 1, 2, 5, 10, 20, 50, 100, 500 });
}
}
}
39.16 Specifying Appearance Probability
- When selecting random results from multiple choices with probability bias, use the
DiscreteSample
function
- The first argument is the choices, prepared as an array
- The second argument is the probability distribution of choices, prepared as a
DiscreteDistribution
type
- The probability distribution is specified with
double
type values, and the total doesn't need to be a specific number
- For example,
{ 2.0, 12.0, 6.0 }
would be distributed as 10%, 60%, 30%

# include <Siv3D.hpp>
void Main()
{
// Choices
const Array<String> options =
{
U"$0",
U"$1",
U"$5",
U"$20",
U"$100",
U"$500",
U"$2000",
};
// Probability distribution corresponding to choices
// ($0 is 1000 times more likely than $2000)
DiscreteDistribution distribution{
{
1000,
200,
50,
10,
5,
2,
1,
} };
while (System::Update())
{
if (SimpleGUI::Button(U"Sample", Vec2{ 200, 40 }))
{
// Randomly select based on probability distribution
Print << DiscreteSample(options, distribution);
}
}
}
39.17 Normal Distribution
- To generate random numbers following a normal distribution, use the
NormalDistribution
class
- Create a normal distribution by specifying mean and standard deviation, and generate random numbers following the normal distribution with the
()
operator
- You can use the global random engine obtained with
GetDefaultRNG()

# include <Siv3D.hpp>
void Main()
{
// Normal distribution with mean 40, standard deviation 8
NormalDistribution dist{ 40.0, 8.0 };
Array<int32> counts(80);
// Global random engine
auto& rng = GetDefaultRNG();
for (int32 i = 0; i < 10000; ++i)
{
const double x = dist(rng);
// Convert result to integer in range 0 to 79
const int32 xi = Clamp(static_cast<int32>(x), 0, 79);
++counts[xi];
}
while (System::Update())
{
// Draw histogram
for (int32 i = 0; i < 80; ++i)
{
Rect{ Arg::bottomLeft((i * 10), 600), 10, counts[i] }
.draw(HSV{ (i * 3), 0.5, 0.9 });
}
}
}
39.18 (Reference) Password Generator
- This is a sample password generator that creates passwords with random alphanumeric characters
Clipboard::SetText(s)
copies the string s
to the clipboard

# include <Siv3D.hpp>
String GeneratePassword()
{
String s;
for (int32 i = 0; i < 16; ++i)
{
s << Random(U'!', U'~');
}
return s;
}
void Main()
{
String password = GeneratePassword();
while (System::Update())
{
ClearPrint();
Print << password;
if (SimpleGUI::Button(U"Generate", Vec2{ 200, 40 }))
{
password = GeneratePassword();
}
if (SimpleGUI::Button(U"Copy to clipboard", Vec2{ 200, 80 }))
{
// Copy string to clipboard
Clipboard::SetText(password);
}
}
}